Massive update and added changelogs for about 12 releases cause I am a little slow.

This commit is contained in:
Toastie 2024-12-14 01:00:50 +13:00
parent 63d93e7107
commit 7ffe4355b8
Signed by: toastie_t0ast
GPG key ID: 27F3B6855AFD40A4
34 changed files with 1209 additions and 2217 deletions

View file

@ -1,288 +0,0 @@
declare module 'astro:content' {
interface RenderResult {
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
headings: import('astro').MarkdownHeading[];
remarkPluginFrontmatter: Record<string, any>;
}
interface Render {
'.md': Promise<RenderResult>;
}
export interface RenderedContent {
html: string;
metadata?: {
imagePaths: Array<string>;
[key: string]: unknown;
};
}
}
declare module 'astro:content' {
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
export type CollectionKey = keyof AnyEntryMap;
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
export type ContentCollectionKey = keyof ContentEntryMap;
export type DataCollectionKey = keyof DataEntryMap;
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
ContentEntryMap[C]
>['slug'];
/** @deprecated Use `getEntry` instead. */
export function getEntryBySlug<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
// Note that this has to accept a regular string too, for SSR
entrySlug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
/** @deprecated Use `getEntry` instead. */
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
collection: C,
entryId: E,
): Promise<CollectionEntry<C>>;
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
collection: C,
filter?: (entry: CollectionEntry<C>) => entry is E,
): Promise<E[]>;
export function getCollection<C extends keyof AnyEntryMap>(
collection: C,
filter?: (entry: CollectionEntry<C>) => unknown,
): Promise<CollectionEntry<C>[]>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(entry: {
collection: C;
slug: E;
}): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(entry: {
collection: C;
id: E;
}): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
slug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(
collection: C,
id: E,
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
/** Resolve an array of entry references from the same collection */
export function getEntries<C extends keyof ContentEntryMap>(
entries: {
collection: C;
slug: ValidContentEntrySlug<C>;
}[],
): Promise<CollectionEntry<C>[]>;
export function getEntries<C extends keyof DataEntryMap>(
entries: {
collection: C;
id: keyof DataEntryMap[C];
}[],
): Promise<CollectionEntry<C>[]>;
export function render<C extends keyof AnyEntryMap>(
entry: AnyEntryMap[C][string],
): Promise<RenderResult>;
export function reference<C extends keyof AnyEntryMap>(
collection: C,
): import('astro/zod').ZodEffects<
import('astro/zod').ZodString,
C extends keyof ContentEntryMap
? {
collection: C;
slug: ValidContentEntrySlug<C>;
}
: {
collection: C;
id: keyof DataEntryMap[C];
}
>;
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
// Invalid collection names will be caught at build time.
export function reference<C extends string>(
collection: C,
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
>;
type ContentEntryMap = {
"releases": {
"4_3_17.md": {
id: "4_3_17.md";
slug: "4_3_17";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"4_3_18.md": {
id: "4_3_18.md";
slug: "4_3_18";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_0_8.md": {
id: "5_0_8.md";
slug: "5_0_8";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_0.md": {
id: "5_1_0.md";
slug: "5_1_0";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_1.md": {
id: "5_1_1.md";
slug: "5_1_1";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_10.md": {
id: "5_1_10.md";
slug: "5_1_10";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_11.md": {
id: "5_1_11.md";
slug: "5_1_11";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_12.md": {
id: "5_1_12.md";
slug: "5_1_12";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_13.md": {
id: "5_1_13.md";
slug: "5_1_13";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_14.md": {
id: "5_1_14.md";
slug: "5_1_14";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_15.md": {
id: "5_1_15.md";
slug: "5_1_15";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_2.md": {
id: "5_1_2.md";
slug: "5_1_2";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_3.md": {
id: "5_1_3.md";
slug: "5_1_3";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_4.md": {
id: "5_1_4.md";
slug: "5_1_4";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_5.md": {
id: "5_1_5.md";
slug: "5_1_5";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_6.md": {
id: "5_1_6.md";
slug: "5_1_6";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_7.md": {
id: "5_1_7.md";
slug: "5_1_7";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_8.md": {
id: "5_1_8.md";
slug: "5_1_8";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
"5_1_9.md": {
id: "5_1_9.md";
slug: "5_1_9";
body: string;
collection: "releases";
data: InferEntrySchema<"releases">
} & { render(): Render[".md"] };
};
};
type DataEntryMap = {
};
type AnyEntryMap = ContentEntryMap & DataEntryMap;
export type ContentConfig = typeof import("./../../src/content/config.js");
}

View file

@ -1,5 +0,0 @@
{
"_variables": {
"lastUpdateCheck": 1729668851846
}
}

2
.astro/types.d.ts vendored
View file

@ -1,2 +0,0 @@
/// <reference types="astro/client" />
/// <reference path="astro/content.d.ts" />

26
.gitignore vendored
View file

@ -1,2 +1,24 @@
node_modules
dist
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# jetbrains setting folder
.idea/

Binary file not shown.

View file

@ -1,3 +1,4 @@
// @ts-check
import { defineConfig } from 'astro/config';
// https://astro.build/config

View file

@ -10,11 +10,9 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "0.9.4",
"astro": "4.16.7",
"sass": "^1.77.8",
"sharp": "^0.33.3",
"typescript": "^5.3.3"
"astro": "^5.0.5",
"sass": "^1.80.6",
"sharp": "^0.33.3"
},
"packageManager": "yarn@4.5.0"
}
"packageManager": "yarn@4.5.3"
}

View file

@ -1,5 +1,5 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
import SEO, { type Props as SEOProps } from './SEO.astro';
import { SiteTitle, SiteDescription } from '../consts';
@ -7,6 +7,7 @@ export type Props = Partial<SEOProps>;
const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...seo } = Astro.props;
---
<meta charset="utf-8" />
<SEO {title} {description} {name} {...seo} />
<link rel="preconnect" href="https://fonts.googleapis.com" />
@ -16,4 +17,4 @@ const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...s
rel="stylesheet"
/>
<ViewTransitions />
<ClientRouter />

View file

@ -22,4 +22,4 @@ const { date, ...attrs } = Astro.props;
time {
display: block;
}
</style>
</style>

View file

@ -84,4 +84,4 @@ function normalizeImageUrl(image: string | ImageMetadata) {
<meta name="twitter:title" content={twitter.title} />
<meta name="twitter:description" content={twitter.description} />
{twitter.image && <meta name="twitter:image" content={normalizeImageUrl(twitter.image.src)} />}
{twitter.image && <meta name="twitter:image:alt" content={twitter.image.alt} />}
{twitter.image && <meta name="twitter:image:alt" content={twitter.image.alt} />}

View file

@ -1,8 +1,11 @@
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
const releases = defineCollection({
// Load Markdown files in the src/content/releases directory.
loader: glob({ base: './src/content/releases', pattern: '**/*.md' }),
// Type-check frontmatter using a schema
schema:
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string(),
@ -12,4 +15,4 @@ const releases = defineCollection({
}),
});
export const collections = { releases };
export const collections = { releases };

View file

@ -0,0 +1,19 @@
---
title: 'Ellie Bot 5.1.16.'
date: '2024-10-28'
versionNumber: '5.1.16'
description: 'Ellie Bot version 5.1.16 release notes.'
---
## Added
- Added .ncanvas and related commands.
- You can set pixel colors (and text) on a 500x350 canvas, pepega version of r/place
- You use currency to set pixels.
- Commands:
- see the entire canvas: `.nc`
- zoom: `.ncz <pos>` or `.ncz x y`
- set pixel: `.ncsp <pos> <color> <text?>`
- get pixel: `.ncp <pos>`
- Owners can use .ncsetimg to set a starting image, use `.h .setimg` for instructions
- Owners can reset the whole canvas via `.ncreset`

View file

@ -0,0 +1,11 @@
---
title: 'Ellie Bot 5.1.17.'
date: '2024-10-29'
versionNumber: '5.1.17'
description: 'Ellie Bot version 5.1.17 release notes.'
---
### Fixed
- fix: Bot will now not accept .aar Role if that Role is higher than or equal to bot's role. Previously bot would just
fail silently, now there is a proper error message.

View file

@ -0,0 +1,27 @@
---
title: 'Ellie Bot 5.1.18.'
date: '2024-11-04'
versionNumber: '5.1.18'
description: 'Ellie Bot version 5.1.18 release notes.'
---
### Added
- Added `.translateflags` / `.trfl` command.
- Enable on a per-channel basis.
- Reacting on any message in that channel with a flag emoji will post the translation of that message in the
language of that country
- 5 second cooldown per user
- The message can only be translated once per language (counter resets every 24h)
- `.timely` now has a button. Togglable via `.conf gambling` it's called pass because previously it was a captcha, but captchas are too annoying
## Changed
- [public bot] Patreon reward bonus for flowers reduced. Timely bonuses stay the same
- discriminators removed from the databases. All users who had ???? as discriminator have been renamed to ??username.
- all new unknown users will have ??Unknown as their name
- Flower currency generation will now have a strikeout to try combat the pickbots. This is the weakest but easiest protection to implement. There may be more options in the future
## Fixed
- nunchi join game message is now ok color instead of error color

View file

@ -0,0 +1,28 @@
---
title: 'Ellie Bot 5.1.19.'
date: '2024-11-05'
versionNumber: '5.1.19'
description: 'Ellie Bot version 5.1.19 release notes.'
---
### Added
- Added `.betstats`
- See your own stats with .betstats
- Target someone else: .betstats @mai_lanfiel
- You can also specify a game .betstats lula
- Or both! .betstats mai_lanfiel br
- `.timely` can now have a server boost bonus
- Configure server ids and reward amount in data/gambling.yml
- anyone who boosts one of the sepcified servers gets the amount as base timely bonus
### Changed
- `.plant/pick` password font size will be slightly bigger
- `.race` will now have 82-94% payout rate based on the number of players playing (1-12, x0.01 per player).
- Any player over 12 won't increase payout
### Fixed
- `.xplb` and `.xpglb` now have proper ranks after page 1
- Fixed boost bonus on shards different than the specified servers' shard

View file

@ -0,0 +1,25 @@
---
title: 'Ellie Bot 5.1.20.'
date: '2024-11-13'
versionNumber: '5.1.20'
description: 'Ellie Bot version 5.1.20 release notes.'
---
### Added
- Added `.rakeback` command, get a % of house edge back as claimable currency
- Added `.snipe` command to quickly get a copy of a posted message as an embed
- You can reply to a message to snipe that message
- Or just type .snipe and the bot will snipe the last message in the channel with content or image
- Added `.betstatsreset` / `.bsreset` command to reset your stats for a fee
- Added `.gamblestatsreset` / `.gsreset` owner-only command to reset bot stats for all games
- Added `.waifuclaims` command which lists all of your claimed waifus
- Added and changed `%bot.time%` and `%bot.date%` placeholders. They use timestamp tags now
### Changed
- `.divorce` no longer has a cooldown
- `.betroll` has a 2% better payout
- `.slot` payout balanced out (less volatile), reduced jackpot win but increased other wins,
- now has a new symbol, wheat
- worse around 1% in total (now shares the top spot with .bf)

View file

@ -0,0 +1,61 @@
---
title: 'Ellie Bot 5.2.0.'
date: '2024-11-28'
versionNumber: '5.2.0'
description: 'Ellie Bot version 5.2.0 release notes.'
---
### Added
- Added `.todo undone` command to unmark a todo as done
- Added Button Roles!
- `.btr a` to add a button role to the specified message
- `.btr list` to list all button roles on the server
- `.btr rm` to remove a button role from the specified message
- `.btr rma` to remove all button roles on the specified message
- `.btr excl` to toggle exclusive button roles (only 1 role per message or any number)
- Use `.h btr` for more info
- Added `.wrongsong` which will delete the last queued song.
- Useful in case you made a mistake, or the bot queued a wrong song
- It will reset after a shuffle or fairplay toggle, or similar events.
- Added Server color Commands!
- Every Server can now set their own colors for ok/error/pending embed (the default green/red/yellow color on the
left side of the message the bot sends)
- Use `.h .sclr` to see the list of commands
- `.sclr show` will show the current server colors
- `.sclr ok <color hex>` to set ok color
- `.sclr warn <color hex>` to set warn color
- `.sclr error <color hex>` to set error color
### Changed
- Self Assigned Roles reworked! Use `.h .sar` for the list of commands
- `.sar autodel`
- Toggles the automatic deletion of the user's message and Nadeko's confirmations for .iam and .iamn commands.
- `.sar ad`
- Adds a role to the list of self-assignable roles. You can also specify a group.
- If 'Exclusive self-assignable roles' feature is enabled (.sar exclusive), users will be able to pick one role
per group.
- `.sar groupname`
- Sets a self assignable role group name. Provide no name to remove.
- `.sar remove`
- Removes a specified role from the list of self-assignable roles.
- `.sar list`
- Lists self-assignable roles. Shows 20 roles per page.
- `.sar exclusive`
- Toggles whether self-assigned roles are exclusive. While enabled, users can only have one self-assignable role
per group.
- `.sar rolelvlreq`
- Set a level requirement on a self-assignable role.
- `.sar grouprolereq`
- Set a role that users have to have in order to assign a self-assignable role from the specified group.
- `.sar groupdelete`
- Deletes a self-assignable role group
- `.iam` and `.iamn` are unchanged
- Removed patron limits from Reaction Roles. Anyone can have as many reros as they like.
- `.timely` captcha made stronger and cached per user.
- `.bsreset` price reduced by 90%
### Fixed
- Fixed `.sinfo` for servers on other shard

View file

@ -0,0 +1,10 @@
---
title: 'Ellie Bot 5.2.1.'
date: '2024-11-28'
versionNumber: '5.2.1'
description: 'Ellie Bot version 5.2.1 release notes.'
---
### Fixed
- Fixed old self assigned missing

View file

@ -0,0 +1,16 @@
---
title: 'Ellie Bot 5.2.2.'
date: '2024-11-29'
versionNumber: '5.2.2'
description: 'Ellie Bot version 5.2.2 release notes.'
---
### Changed
- Button roles are now non-exclusive by default
### Fixed
- Fixed sar migration, again (this time correctly)
- Fixed `.sclr` not updating unless bot is restarted, the changes should be immediate now for warn and error
- Fixed group buttons exclusivity message always saying groups are exclusive

View file

@ -0,0 +1,15 @@
---
title: 'Ellie Bot 5.2.3.'
date: '2024-11-29'
versionNumber: '5.2.3'
description: 'Ellie Bot version 5.2.3 release notes.'
---
### Fixed
- `.iam` Fixed
- `.sclr` will now properly change color on many commands it didn't work previously
### Changed
- `.rps` now also has bet amount in the result, like other gambling commands

View file

@ -0,0 +1,11 @@
---
title: 'Ellie Bot 5.2.4.'
date: '2024-11-29'
versionNumber: '5.2.4'
description: 'Ellie Bot version 5.2.4 release notes.'
---
## Fixed
- More fixes for .sclr
- `.iamn` fixed

View file

@ -0,0 +1,49 @@
---
title: 'Ellie Bot 5.3.0.'
date: '2024-12-10'
versionNumber: '5.3.0'
description: 'Ellie Bot version 5.3.0 release notes.'
---
## Added
- Added `.minesweeper` / `.mw` command - spoiler-based minesweeper minigame. Just for fun
- Added `.temprole` command - add a role to a user for a certain amount of time, after which the role will be removed
- Added `.xplevelset` - you can now set a level for a user in your server
- Added `.winlb` command - leaderboard of top gambling wins
- Added `.notify` command
- Specify an event to be notified about, and the bot will post the specified message in the current channel when the
event occurs
- A few events supported right now:
- `UserLevelUp` when user levels up in the server
- `AddRoleReward` when a role is added to a user through .xpreward system
- `RemoveRoleReward` when a role is removed from a user through .xpreward system
- `Protection` when antialt, antiraid or antispam protection is triggered
- Added `.banner` command to see someone's banner
- Selfhosters:
- Added `.dmmod` and `.dmcmd` - you can now disable or enable whether commands or modules can be executed in bot's
DMs
## Changed
- Giveaway improvements
- Now mentions winners in a separate message
- Shows the timestamp of when the giveaway ends
- Xp Changes
- Removed awarded xp (the number in the brackets on the xp card)
- Awarded xp, (or the new level set) now directly apply to user's real xp
- Server xp notifications are now set by the server admin/manager in a specified channel
- `.sclr show` will now show hex code of the current color
- Queueing a song will now restart the playback if the queue is on the last track and stopped (there were no more tracks
to play)
- `.translate` will now use 2 embeds instead of 1
## Fixed
- .setstream and .setactivity will now pause .ropl (rotating statuses)
- Fixed `.sar ex` help description
## Removed
- `.xpnotify` command, superseded by `.notify`, although as of right now you can't post user's level up in the same
channel user last typed, because you have to specify a channel where the notify messages will be posted

View file

@ -0,0 +1,20 @@
---
title: 'Ellie Bot 5.3.1.'
date: '2024-12-12'
versionNumber: '5.3.1'
description: 'Ellie Bot version 5.3.1 release notes.'
---
## Changed
- `.translate` will now use 2 embeds, to allow for longer messages
- Added role icon to `.inrole`, if it exists
- `.honeypot` will now add a 'Honeypot' as a ban reason.
## Fixed
- `.winlb` looks better, has a title, shows 9 entries now
- `.sar ex` help updated
- `.banner` partially fixed, it still can't show global banners, but it will show guild ones correctly, in a good enough size
- `.sclr` will now show correct color hexes without alpha
- `.dmcmd` will now correctly block commands in dms, not globally

2
src/env.d.ts vendored
View file

@ -1,2 +0,0 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

View file

@ -9,15 +9,14 @@ const { ...head } = Astro.props;
---
<!doctype html>
<meta charset="utf-8" />
<html lang="en">
<head>
<BaseHead {...head} />
<body>
<div class="glow"></div>
<Header />
<slot />
<Footer />
</body>
</head>
</html>
<body>
<div class="glow"></div>
<Header />
<slot />
<Footer />
</body>
</html>

View file

@ -6,7 +6,7 @@ import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
type Props = {
release: CollectionEntry<'releases'>;
release: CollectionEntry<'releases'>;
};
const { release } = Astro.props;
@ -14,25 +14,25 @@ const { release } = Astro.props;
<!doctype html>
<html lang="en">
<head>
<BaseHead
title={release.data.title}
description={release.data.description}
/>
</head><body>
<div class="glow"></div>
<Header />
<div class="post single" transition:persist transition:name="post">
<div class="version_wrapper">
<div class="version_info">
<div class="version_number">{release.data.versionNumber}</div>
<FormattedDate class="date" date={release.data.date} />
</div>
</div>
<div class="content">
<slot />
</div>
</div>
<Footer />
</body>
</html>
<head>
<BaseHead
title={release.data.title}
description={release.data.description}
/>
</head><body>
<div class="glow"></div>
<Header />
<div class="post single" transition:persist transition:name="post">
<div class="version_wrapper">
<div class="version_info">
<div class="version_number">{release.data.versionNumber}</div>
<FormattedDate class="date" date={release.data.date} />
</div>
</div>
<div class="content">
<slot />
</div>
</div>
<Footer />
</body>
</html>

View file

@ -1,5 +1,5 @@
---
import { getCollection } from 'astro:content';
import { getCollection, render } from 'astro:content';
import FormattedDate from '../components/FormattedDate.astro';
import Layout from '../layouts/IndexLayout.astro';
@ -8,30 +8,29 @@ posts.sort((a, b) => +b.data.date - +a.data.date);
---
<Layout>
<main>
<title>Ellie Notes</title>
<h1 class="page_title">Changelogs</h1>
<hr />
<ul class="posts" transition:name="post">
{
posts.map((post) => (
<li class="post">
<div class="version_wrapper">
<div class="version_info">
<a href={`/releases/${post.slug}`}>
<div class="version_number">{post.data.versionNumber}</div>
<FormattedDate class="date" date={post.data.date} />
</a>
</div>
</div>
<div class="content">
{post.render().then(({ Content }) => (
<Content />
))}
</div>
</li>
))
}
</ul>
</main>
</Layout>
<main>
<h1 class="page_title">Changelog</h1>
<hr />
<ul class="posts" transition:name="post">
{
posts.map((post) => (
<li class="post">
<div class="version_wrapper">
<div class="version_info">
<a href={`/releases/${post.id}`}>
<div class="version_number">{post.data.versionNumber}</div>
<FormattedDate class="date" date={post.data.date} />
</a>
</div>
</div>
<div class="content">
{render(post).then(({ Content }) => (
<Content />
))}
</div>
</li>
))
}
</ul>
</main>
</Layout>

View file

@ -1,21 +1,21 @@
---
import { getCollection } from 'astro:content';
import { getCollection, render } from 'astro:content';
import Layout from '../../layouts/PostLayout.astro';
export async function getStaticPaths() {
const releases = await getCollection('releases');
return releases.map((release) => ({
params: { slug: release.slug },
params: { slug: release.id },
props: { release },
}));
}
const { release } = Astro.props;
const { Content } = await release.render();
const { Content } = await render(release);
---
<Layout {release}>
<Content />
</Layout>
</Layout>

View file

@ -1,11 +1,13 @@
@use 'sass:map';
@function color($color, $tone) {
// @warn map-get($palette,$color);
// @warn map.get($palette,$color);
@if map-has-key($palette, $color) {
$color: map-get($palette, $color);
@if map.has-key($palette, $color) {
$color: map.get($palette, $color);
@if map-has-key($color, $tone) {
$tone: map-get($color, $tone);
@if map.has-key($color, $tone) {
$tone: map.get($color, $tone);
@return $tone;
}

View file

@ -1,3 +1,3 @@
@import 'colors.scss';
@import 'type.scss';
@import 'layout.scss';
@use 'colors.scss';
@use 'type.scss';
@use 'layout.scss';

View file

@ -1,3 +1,7 @@
@use 'sass:color';
@use './colors.scss' as colors;
@use './type.scss' as type;
$container: 1040px;
$tablet: 768px;
$mobile: 420px;
@ -11,12 +15,10 @@ body {
padding: 0 1em;
width: 1040px;
max-width: 100%;
background-color: $white;
background-color: colors.$white;
@media (prefers-color-scheme: dark) {
background-color: color(gray, 950);
background-color: colors.color(gray, 950);
}
@media (max-width: $tablet) {
font-size: 16px;
}
@ -39,48 +41,47 @@ body {
left: calc(50% - 360px);
width: 720px;
height: 240px;
background: radial-gradient(50% 50% at 50% 50%,
rgba(color(orange, 500), 0.2) 0%,
rgba(color(orange, 500), 0) 100%);
background: radial-gradient(
50% 50% at 50% 50%,
rgba(colors.color(orange, 500), 0.2) 0%,
rgba(colors.color(orange, 500), 0) 100%
);
@media (prefers-color-scheme: dark) {
background: radial-gradient(50% 50% at 50% 50%,
rgba(255, 255, 255, 0.06) 0%,
rgba(255, 255, 255, 0) 100%);
background: radial-gradient(
50% 50% at 50% 50%,
rgba(255, 255, 255, 0.06) 0%,
rgba(255, 255, 255, 0) 100%
);
}
}
}
::selection {
background: color(orange, 200);
background: colors.color(orange, 200);
@media (prefers-color-scheme: dark) {
background: color(orange, 600);
background: colors.color(orange, 600);
}
}
a,
a:visited {
color: color(orange, 600);
color: colors.color(orange, 600);
transition: 0.1s ease;
@media (prefers-color-scheme: dark) {
color: color(orange, 300);
color: colors.color(orange, 300);
}
transition: 0.1s ease;
&:hover {
color: color(orange, 500);
color: colors.color(orange, 500);
}
}
hr {
margin: 1em 0;
border: 0;
border-bottom: 1px solid color(gray, 100);
border-bottom: 1px solid colors.color(gray, 100);
@media (prefers-color-scheme: dark) {
border-color: color(gray, 900);
border-color: colors.color(gray, 900);
}
}
@ -93,7 +94,6 @@ nav {
a {
transition: 0.1s ease;
&:hover {
opacity: 0.6;
}
@ -102,37 +102,31 @@ nav {
#site_title {
margin: 0;
}
#site_title a {
display: flex;
align-items: center;
gap: 10px;
color: color(gray, 950);
@media (prefers-color-scheme: dark) {
color: $white;
}
color: colors.color(gray, 950);
font-size: 16px;
font-weight: 700;
letter-spacing: 2px;
line-height: 1;
text-decoration: none;
text-transform: uppercase;
@media (prefers-color-scheme: dark) {
color: colors.$white;
}
}
.links a {
margin-left: 1em;
color: color(gray, 800);
color: colors.color(gray, 800);
@media (prefers-color-scheme: dark) {
color: color(gray, 200);
color: colors.color(gray, 200);
}
}
}
.content {
ol,
ul {
padding-left: 2em;
@ -154,7 +148,7 @@ nav {
top: 0.63em;
width: 8px;
height: 8px;
background: linear-gradient(25deg, color(purple, 500), color(orange, 500));
background: linear-gradient(25deg, colors.color(purple, 500), colors.color(orange, 500));
border-radius: 99px;
}
}
@ -163,7 +157,6 @@ nav {
.page_title {
margin: 1.5em 0;
@media (max-width: $tablet) {
margin: 0.5em 0;
}
@ -177,7 +170,6 @@ nav {
.post {
display: flex;
width: 100%;
@media (max-width: $tablet) {
flex-flow: column;
}
@ -190,15 +182,12 @@ nav {
.version_wrapper {
flex-basis: 260px;
@media (max-width: $container) {
flex-basis: 140px;
}
flex-grow: 0;
flex-shrink: 0;
margin: 4.5em 0 0 0;
@media (max-width: $container) {
flex-basis: 140px;
}
@media (max-width: $tablet) {
flex-basis: 0;
margin-top: 2em;
@ -207,7 +196,6 @@ nav {
.version_info {
position: sticky;
top: 1em;
@media (max-width: $tablet) {
position: relative;
top: 0;
@ -216,7 +204,7 @@ nav {
a {
float: left;
color: $white;
color: colors.$white;
text-decoration: none;
transition: 0.1s ease;
@ -228,64 +216,56 @@ nav {
.version_number {
display: inline-block;
font-family: $codeFont;
font-family: type.$codeFont;
line-height: 1;
margin-bottom: 8px;
padding: 4px 12px;
color: $white;
background: linear-gradient(25deg,
color(purple, 800),
color(purple, 700),
mix(color(purple, 500), color(orange, 500)),
color(orange, 500));
color: colors.$white;
background: linear-gradient(
25deg,
colors.color(purple, 800),
colors.color(purple, 700),
color.mix(colors.color(purple, 500), colors.color(orange, 500)),
colors.color(orange, 500)
);
border-radius: 8px;
}
.date {
clear: both;
color: colors.color(gray, 800);
font-family: type.$codeFont;
font-size: type.$fontSizeSmall;
@media (max-width: $tablet) {
display: inline;
margin-left: 1em;
}
color: color(gray, 800);
@media (prefers-color-scheme: dark) {
color: color(gray, 200);
color: colors.color(gray, 200);
}
font-family: $codeFont;
font-size: $fontSizeSmall;
}
.content {
margin: 0;
padding: 4em 0;
border-bottom: 1px solid colors.color(gray, 100);
@media (max-width: $tablet) {
margin: 1em 0;
padding: 0 0 2em 0;
}
border-bottom: 1px solid color(gray, 100);
@media (prefers-color-scheme: dark) {
border-color: color(gray, 900);
border-color: colors.color(gray, 900);
}
*:first-child {
margin-top: 0;
}
img {
max-width: 100%;
height: auto;
border-radius: 12px;
border: 1px solid color(gray, 200);
border: 1px solid colors.color(gray, 200);
@media (prefers-color-scheme: dark) {
border-color: color(gray, 800);
border-color: colors.color(gray, 800);
}
}
}
@ -293,26 +273,22 @@ nav {
footer {
display: flex;
padding: 2em 0;
color: colors.color(gray, 500);
justify-content: space-between;
border-top: 1px solid colors.color(gray, 100);
@media (max-width: $tablet) {
padding: 1em 0;
}
color: color(gray, 500);
justify-content: space-between;
border-top: 1px solid color(gray, 100);
@media (prefers-color-scheme: dark) {
border-color: color(gray, 900);
border-color: colors.color(gray, 900);
}
a {
margin-left: 1em;
color: color(gray, 500);
color: colors.color(gray, 500);
text-decoration: none;
&:hover {
color: color(gray, 500);
color: colors.color(gray, 500);
opacity: 0.6;
}
}

View file

@ -1,3 +1,5 @@
@use './colors.scss' as colors;
$baseFont: 'Lato', sans-serif;
$codeFont: 'Source Code Pro', monospace;
$fontSizeSmall: 15px;
@ -7,15 +9,14 @@ body {
font-size: 18px;
line-height: 1.65;
font-weight: 400;
@media (prefers-color-scheme: dark) {
color: color(gray, 200);
}
color: color(gray, 800);
color: colors.color(gray, 800);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
@media (prefers-color-scheme: dark) {
color: colors.color(gray, 200);
}
}
h1,
@ -25,31 +26,26 @@ h4,
h5 {
line-height: 1.2;
margin: 1em 0 0.5em 0;
color: colors.color(gray, 950);
font-weight: 700;
@media (prefers-color-scheme: dark) {
color: $white;
color: colors.$white;
}
color: color(gray, 950);
font-weight: 700;
}
h1 {
font-size: 3.052em;
}
h2 {
font-size: 2.441em;
}
h3 {
font-size: 1.953em;
}
h4 {
font-size: 1.563em;
}
h5 {
font-size: 1.25em;
}
@ -66,10 +62,9 @@ b,
strong {
font-weight: 700;
color: #fff;
color: colors.color(gray, 950);
@media (prefers-color-scheme: dark) {
color: $white;
color: colors.$white;
}
color: color(gray, 950);
}

View file

@ -1,6 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"exclude": [
"dist"
]
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}

2466
yarn.lock

File diff suppressed because it is too large Load diff