Update to nextjs15

This commit is contained in:
selfboot 2025-05-19 19:24:05 +08:00
parent 2b02dee01c
commit b141d23bfa
53 changed files with 2493 additions and 972 deletions

View File

@ -4,9 +4,10 @@ const path = require('path');
const nextConfig = {
reactStrictMode: true,
transpilePackages: ['lodash'],
webpack: (config) => {
config.resolve.alias['@'] = path.resolve(__dirname, 'src');
return config;
turbopack: {
resolveAlias: {
'@': path.resolve(__dirname, 'src')
}
},
images: {
remotePatterns: [

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "node scripts/generate-sitemap-rss.mjs && next dev",
"dev": "node scripts/generate-sitemap-rss.mjs && next dev --turbopack",
"build": "node scripts/generate-sitemap-rss.mjs && next build",
"start": "next start",
"lint": "next lint",
@ -15,12 +15,12 @@
"@fortawesome/free-brands-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"@giscus/react": "^3.0.0",
"@headlessui/react": "^2.1.2",
"@next/third-parties": "^14.2.5",
"@react-spring/web": "^9.7.4",
"@react-three/drei": "^9.115.0",
"@react-three/fiber": "^8.17.10",
"@giscus/react": "^3.1.0",
"@headlessui/react": "^2.2.3",
"@next/third-parties": "15.3.2",
"@react-spring/web": "^10.0.0",
"@react-three/drei": "^10.0.8",
"@react-three/fiber": "^9.0.0",
"@tailwindcss/typography": "^0.5.14",
"@vercel/speed-insights": "^1.2.0",
"cookies-next": "^4.3.0",
@ -38,12 +38,12 @@
"html2canvas": "^1.4.1",
"lodash.debounce": "^4.0.8",
"lucide-react": "^0.416.0",
"next": "14.2.21",
"next": "15.3.2",
"node-fetch": "^3.3.2",
"papaparse": "^5.4.1",
"pizzip": "^3.1.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"reactflow": "^11.11.4",
"rehype-highlight": "^7.0.0",
"rehype-slug": "^6.0.0",
@ -53,16 +53,18 @@
"remark-rehype": "^11.1.0",
"rss": "^1.2.2",
"three": "^0.169.0",
"unist-util-visit": "^5.0.0",
"web-vitals": "^4.2.2",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
"xlsx-js-style": "^1.2.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.1",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.6.1",
"@types/jest": "^29.5.12",
"eslint": "^8.57.0",
"eslint-config-next": "14.2.5",
"eslint-config-next": "15.3.2",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
@ -73,5 +75,27 @@
"singleQuote": false,
"quoteProps": "preserve",
"printWidth": 120
},
"overrides": {
"@react-spring/web": {
"react": "$react",
"react-dom": "$react-dom"
},
"@headlessui/react": {
"react": "$react",
"react-dom": "$react-dom"
},
"@giscus/react": {
"react": "$react",
"react-dom": "$react-dom"
},
"@react-three/drei": {
"react": "$react",
"react-dom": "$react-dom"
},
"@react-three/fiber": {
"react": "$react",
"react-dom": "$react-dom"
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.astar.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function AstarPage({ params: { lang } }) {
export default async function AstarPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/astar`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.bfs_path.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function BFSPathPage({ params: { lang } }) {
export default async function BFSPathPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/bfs_path`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.binarysearchtree.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function BinarySearchTreePage({ params: { lang } }) {
export default async function BinarySearchTreePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/binarysearchtree`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.bloomfilter.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function BloomFilterPage({ params: { lang } }) {
export default async function BloomFilterPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/bloomfilter`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function DijkstraPage({ params: { lang } }) {
export default async function DijkstraPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/dijkstra`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function DPCoinPage({ params: { lang } }) {
export default async function DPCoinPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/dpcoin`} />

View File

@ -1,5 +1,6 @@
import React from 'react';
import { render, screen, fireEvent, waitFor} from '@/app/test_utils';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import HanoiTower from '../content';
@ -20,12 +21,22 @@ describe('HanoiTower Component', () => {
});
test('changes number of disks when selected', async () => {
const user = userEvent.setup();
render(<HanoiTower />);
fireEvent.click(screen.getByRole('button', { name: '6' }));
fireEvent.click(screen.getByRole('option', { name: '4' }));
const listboxButton = screen.getByRole('button', { name: '6' });
await user.click(listboxButton);
const option3 = await screen.findByRole('option', { name: '3' });
expect(option3).toBeVisible();
const option4 = await screen.findByRole('option', { name: '4' });
await user.click(option4);
await waitFor(() => {
const updatedDisks = screen.getAllByTestId('hanoi-disk');
expect(updatedDisks.length).toBe(4);
expect(screen.getByRole('button', { name: '4' })).toBeInTheDocument();
});
});
@ -125,7 +136,6 @@ describe('HanoiTower Component', () => {
firstTower = screen.getByTestId('tower-0');
secondTower = screen.getByTestId('tower-1');
// expect(firstTower.querySelectorAll('[data-testid="hanoi-disk"]')).toHaveLength(5);
const disksOnSecondTower = secondTower.querySelectorAll('[data-testid="hanoi-disk"]');
expect(disksOnSecondTower).toHaveLength(1);
});

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.hanoitower.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function HanoiTowerPage({ params: { lang } }) {
export default async function HanoiTowerPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/hanoitower`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.hashring.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function HashRingPage({ params: { lang } }) {
export default async function HashRingPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/hashring`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.hashtable.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function HashTablePage({ params: { lang } }) {
export default async function HashTablePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/hashtable`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.heap.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function HeapPage({ params: { lang } }) {
export default async function HeapPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/heap`} />

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.jumphash.title,
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function JumpHashPage({ params: { lang } }) {
export default async function JumpHashPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/jumphash`} />

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.linkedlist.title,
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function LinkedListPage({ params: { lang } }) {
export default async function LinkedListPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/linkedlist`} />

View File

@ -3,7 +3,13 @@ import ProjectGrid from "@/app/components/ProjectGrid";
import { getDictionary } from "@/app/dictionaries";
import { PageMeta } from "@/app/components/Meta";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default async function Algorithms({ params: { lang } }) {
export default async function Algorithms(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return (

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.ratelimit.title,
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function RateLimiterPage({ params: { lang } }) {
export default async function RateLimiterPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/ratelimit/`} />

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.skiplist.title,
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function StackPage({ params: { lang } }) {
export default async function StackPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/skiplist`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.stack.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function StackPage({ params: { lang } }) {
export default async function StackPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/stack`} />

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.tokenbucket.title,
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function TokenBucketPage({ params: { lang } }) {
export default async function TokenBucketPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/tokenbucket`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.trie.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function TriePage({ params: { lang } }) {
export default async function TriePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/algorithms/trie`} />

View File

@ -6,7 +6,14 @@ import TableOfContents from "@/app/components/TableOfContents";
import CommonComments from "@/app/components/GiscusComments";
import { SideAdComponent } from "@/app/components/AdComponent";
export default async function BlogPostPage({ params: { lang, slug } }) {
export default async function BlogPostPage(props) {
const params = await props.params;
const {
lang,
slug
} = params;
const post = await getPostContent(slug, lang);
if (!post) {
@ -77,7 +84,8 @@ export default async function BlogPostPage({ params: { lang, slug } }) {
);
}
export async function generateMetadata({ params }) {
export async function generateMetadata(props) {
const params = await props.params;
const { lang, slug } = params;
const post = await getPostContent(slug, lang);

View File

@ -5,7 +5,13 @@ import { BlogIndex } from "@/app/components/BlogIndex";
import { getDictionary } from '@/app/dictionaries';
import { PageMeta } from "@/app/components/Meta";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
@ -44,7 +50,13 @@ async function getPostMetadata(lang) {
return postsMetadata.filter(Boolean).sort((a, b) => new Date(b.date) - new Date(a.date));
}
export default async function BlogIndexPage({ params: { lang } }) {
export default async function BlogIndexPage(props) {
const params = await props.params;
const {
lang
} = params;
const posts = await getPostMetadata(lang);
return <BlogIndex posts={posts} lang={lang} />;
}

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -25,7 +31,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function Game2048Page({ params: { lang } }) {
export default async function Game2048Page(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/2048`} />

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -25,7 +31,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function ChessPage({ params: { lang } }) {
export default async function ChessPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/chess`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function CubePage({ params: { lang } }) {
export default async function CubePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/cube`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function GomokuPage({ params: { lang } }) {
export default async function GomokuPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/gomoku`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function MazePage({ params: { lang } }) {
export default async function MazePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/maze`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function MinesweeperPage({ params: { lang } }) {
export default async function MinesweeperPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/minesweeper`} />

View File

@ -3,7 +3,13 @@ import ProjectGrid from "@/app/components/ProjectGrid";
import { getDictionary } from "@/app/dictionaries";
import { PageMeta } from "@/app/components/Meta";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default async function Games({ params: { lang } }) {
export default async function Games(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return (

View File

@ -5,7 +5,13 @@ import PageHeader from '@/app/components/PageHeader';
import CommonComments from '@/app/components/GiscusComments';
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function SlidingPuzzlePage({ params: { lang } }) {
export default async function SlidingPuzzlePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/sliding`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function SnakePage({ params: { lang } }) {
export default async function SnakePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/snake`} />

View File

@ -43,7 +43,13 @@ function deduplicateAndSortLevels(levels) {
});
}
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -64,7 +70,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function SokobanGalleryPage({ params: { lang } }) {
export default async function SokobanGalleryPage(props) {
const params = await props.params;
const {
lang
} = params;
const levels = deduplicateAndSortLevels([...levelsData.levels, ...extraLevelsData]);
return (
<>

View File

@ -6,7 +6,13 @@ import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
import levelsData from "./levels.json";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -27,7 +33,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function SokobanPage({ params: { lang } }) {
export default async function SokobanPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/sokoban`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function SudokuPage({ params: { lang } }) {
export default async function SudokuPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/sudoku`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function TetrisPage({ params: { lang } }) {
export default async function TetrisPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/tangram`} />

View File

@ -4,7 +4,13 @@ import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -25,7 +31,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function TetrisPage({ params: { lang } }) {
export default async function TetrisPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/games/tetris`} />

View File

@ -15,7 +15,18 @@ export function generateStaticParams() {
return SUPPORTED_LANGUAGES.map(lang => ({ lang }));
}
export default async function Layout({ children, params: { lang, slug = [] } }) {
export default async function Layout(props) {
const params = await props.params;
const {
lang,
slug = []
} = params;
const {
children
} = props;
const dict = await getDictionary(lang);
const pathname = `/${lang}/${slug.join('/')}`;
@ -30,15 +41,17 @@ export default async function Layout({ children, params: { lang, slug = [] } })
title={`RSS Feed for AI Gallery`}
href={`https://gallery.selfboot.cn/${rssFileName}`}
/>
<Script id="check-device-and-load-ads" strategy="beforeInteractive">
<Script id="check-device-and-load-ads" strategy="afterInteractive">
{`
if (window.innerWidth >= 768) {
const script = document.createElement('script');
script.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7746897490519544";
script.async = true;
script.crossOrigin = "anonymous";
document.head.appendChild(script);
}
(function() {
if (typeof window !== 'undefined' && window.innerWidth >= 768) {
const script = document.createElement('script');
script.src = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7746897490519544";
script.async = true;
script.crossOrigin = "anonymous";
document.head.appendChild(script);
}
})();
`}
</Script>
<Script

View File

@ -1,7 +1,13 @@
import { getDictionary } from "@/app/dictionaries";
import { PageMeta } from "@/app/components/Meta";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.index.title,
@ -13,9 +19,16 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default async function Home({ params: { lang } }) {
export default async function Home(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return (
<></> // redriect now
// redriect now
<></>
);
}

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.gendocx.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function GenDocxPage({ params: { lang } }) {
export default async function GenDocxPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/awards`} />

View File

@ -63,7 +63,14 @@ async function fetchChartData(dataFile, config) {
}
}
export async function generateMetadata({ params: { chartId, lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
chartId,
lang
} = params;
const dict = await getDictionary(lang);
const chartConfig = dynamicChartConfigs.find((c) => c.id === chartId);
@ -79,7 +86,8 @@ export async function generateMetadata({ params: { chartId, lang } }) {
}
}
export default async function DynamicChartPage({ params }) {
export default async function DynamicChartPage(props) {
const params = await props.params;
const { chartId, lang } = params;
const config = dynamicChartConfigs.find((c) => c.id === chartId);

View File

@ -2,7 +2,13 @@ import { getDictionary } from "@/app/dictionaries";
import { PageMeta } from "@/app/components/Meta";
import DynamicChartsContent from './content';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
@ -15,7 +21,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default async function DynamicChartsPage({ params: { lang } }) {
export default async function DynamicChartsPage(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return <DynamicChartsContent initialDict={dict} lang={lang} />;

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
title: dict.seo.chartrace.title,
@ -17,7 +23,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default function ChartRacePage({ params: { lang } }) {
export default async function ChartRacePage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/chartrace`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function GenDocxPage({ params: { lang } }) {
export default async function GenDocxPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/gendocx`} />

View File

@ -6,7 +6,14 @@ import PageHeader from "@/app/components/PageHeader";
import TemplateDocx from "./content";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang, id } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang,
id
} = params;
const template = documentTemplates.find((template) => template.id === id);
if (!template) return notFound();
@ -38,7 +45,14 @@ export async function generateStaticParams() {
);
}
export default function TemplatePage({ params: { lang, id } }) {
export default async function TemplatePage(props) {
const params = await props.params;
const {
lang,
id
} = params;
const template = documentTemplates.find((template) => template.id === id);
if (!template) return notFound();

View File

@ -3,7 +3,13 @@ import TemplateList from "./content";
import { PageMeta } from "@/app/components/Meta";
import PageHeader from "@/app/components/PageHeader";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -24,7 +30,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function TemplatesPage({ params: { lang } }) {
export default async function TemplatesPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/gendocx/temp`} title="gendocx_templates" />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function GenDocxPage({ params: { lang } }) {
export default async function GenDocxPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/loanrate`} />

View File

@ -3,7 +3,13 @@ import ProjectGrid from "@/app/components/ProjectGrid";
import { getDictionary } from "@/app/dictionaries";
import { PageMeta } from "@/app/components/Meta";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return PageMeta({
@ -16,7 +22,13 @@ export async function generateMetadata({ params: { lang } }) {
});
}
export default async function Tools({ params: { lang } }) {
export default async function Tools(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return (

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from "@/app/components/BlogMarkdown";
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function GenDocxPage({ params: { lang } }) {
export default async function GenDocxPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/retire`} />

View File

@ -5,7 +5,13 @@ import PageHeader from "@/app/components/PageHeader";
import CommonComments from "@/app/components/GiscusComments";
import BlogMarkdown from '@/app/components/BlogMarkdown';
export async function generateMetadata({ params: { lang } }) {
export async function generateMetadata(props) {
const params = await props.params;
const {
lang
} = params;
const dict = await getDictionary(lang);
return {
...PageMeta({
@ -26,7 +32,13 @@ export async function generateMetadata({ params: { lang } }) {
};
}
export default function SubtitlesPage({ params: { lang } }) {
export default async function SubtitlesPage(props) {
const params = await props.params;
const {
lang
} = params;
return (
<>
<PageHeader lang={lang} pathname={`/${lang}/tools/subtitles`} />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,8 +1,8 @@
@import 'github-markdown-css/github-markdown-light.css';
@import 'highlight.js/styles/github.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'github-markdown-css/github-markdown-light.css';
@import 'highlight.js/styles/github.css';
@layer base {
:where(.markdown-body) {