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 # build output
dist 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'; import { defineConfig } from 'astro/config';
// https://astro.build/config // https://astro.build/config

View file

@ -10,11 +10,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/check": "0.9.4", "astro": "^5.0.5",
"astro": "4.16.7", "sass": "^1.80.6",
"sass": "^1.77.8", "sharp": "^0.33.3"
"sharp": "^0.33.3",
"typescript": "^5.3.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 SEO, { type Props as SEOProps } from './SEO.astro';
import { SiteTitle, SiteDescription } from '../consts'; import { SiteTitle, SiteDescription } from '../consts';
@ -7,6 +7,7 @@ export type Props = Partial<SEOProps>;
const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...seo } = Astro.props; const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...seo } = Astro.props;
--- ---
<meta charset="utf-8" />
<SEO {title} {description} {name} {...seo} /> <SEO {title} {description} {name} {...seo} />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
@ -16,4 +17,4 @@ const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...s
rel="stylesheet" rel="stylesheet"
/> />
<ViewTransitions /> <ClientRouter />

View file

@ -1,8 +1,11 @@
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content'; import { defineCollection, z } from 'astro:content';
const releases = defineCollection({ 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 // Type-check frontmatter using a schema
schema: schema: ({ image }) =>
z.object({ z.object({
title: z.string(), title: z.string(),
description: z.string(), description: z.string(),

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> <!doctype html>
<meta charset="utf-8" />
<html lang="en"> <html lang="en">
<head> <head>
<BaseHead {...head} /> <BaseHead {...head} />
</head>
<body> <body>
<div class="glow"></div> <div class="glow"></div>
<Header /> <Header />
<slot /> <slot />
<Footer /> <Footer />
</body> </body>
</head>
</html> </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 FormattedDate from '../components/FormattedDate.astro';
import Layout from '../layouts/IndexLayout.astro'; import Layout from '../layouts/IndexLayout.astro';
@ -9,8 +9,7 @@ posts.sort((a, b) => +b.data.date - +a.data.date);
<Layout> <Layout>
<main> <main>
<title>Ellie Notes</title> <h1 class="page_title">Changelog</h1>
<h1 class="page_title">Changelogs</h1>
<hr /> <hr />
<ul class="posts" transition:name="post"> <ul class="posts" transition:name="post">
{ {
@ -18,14 +17,14 @@ posts.sort((a, b) => +b.data.date - +a.data.date);
<li class="post"> <li class="post">
<div class="version_wrapper"> <div class="version_wrapper">
<div class="version_info"> <div class="version_info">
<a href={`/releases/${post.slug}`}> <a href={`/releases/${post.id}`}>
<div class="version_number">{post.data.versionNumber}</div> <div class="version_number">{post.data.versionNumber}</div>
<FormattedDate class="date" date={post.data.date} /> <FormattedDate class="date" date={post.data.date} />
</a> </a>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
{post.render().then(({ Content }) => ( {render(post).then(({ Content }) => (
<Content /> <Content />
))} ))}
</div> </div>

View file

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

View file

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

View file

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

View file

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

View file

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

2466
yarn.lock

File diff suppressed because it is too large Load diff