Skip to content

Commit 1f7d0ce

Browse files
committed
[refactor] isolate Internationalization data with MobX-i18n 0.7 & React context
[optimize] reduce Dependency conflicts with Independent Configuration module [optimize] upgrade to MobX-RESTful-table 2.2, Next-SSR-middleware 1.0 & other latest Upstream packages
1 parent 363e023 commit 1f7d0ce

26 files changed

+2095
-1637
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pnpm container
124124
[18]: https://code.visualstudio.com/
125125
[19]: https://github.com/new?template_name=Lark-Next-Bootstrap-ts&template_owner=idea2app
126126
[20]: https://github.com/idea2app/Lark-Next-Bootstrap-ts/blob/80967ed49045af9dbcf4d3695a2c39d53a6f71f1/.github/workflows/pull-request.yml#L9-L11
127-
[21]: https://github.com/kaiyuanshe/kaiyuanshe.github.io/blob/bb4675a56bf1d6b207231313da5ed0af7cf0ebd6/.github/workflows/pull-request.yml#L32-L56
127+
[21]: https://github.com/idea2app/Lark-Next-Bootstrap-ts/blob/363e023e5dd472c8ea53ec96eac25ec5122e667b/.github/workflows/Lark-notification.yml#L39
128128
[22]: https://github.com/idea2app/Lark-Next-Bootstrap-ts/settings/secrets/actions
129129
[23]: https://github.com/idea2app/Lark-Next-Bootstrap-ts/issues/new/choose
130130
[24]: https://github.com/idea2app/Lark-Next-Bootstrap-ts/projects

components/Git/Card.tsx

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { text2color } from 'idea-react';
22
import { GitRepository } from 'mobx-github';
33
import { observer } from 'mobx-react';
4-
import { FC } from 'react';
4+
import { FC, useContext } from 'react';
55
import { Badge, Button, Card, CardProps, Col, Row } from 'react-bootstrap';
66

7-
import { t } from '../../models/Translation';
7+
import { I18nContext } from '../../models/Translation';
88
import { GitLogo } from './Logo';
99

1010
export interface GitCardProps
@@ -24,45 +24,49 @@ export const GitCard: FC<GitCardProps> = observer(
2424
description,
2525
homepage,
2626
...props
27-
}) => (
28-
<Card className={className} {...props}>
29-
<Card.Body className="d-flex flex-column gap-3">
30-
<Card.Title as="h3" className="h5">
31-
<a target="_blank" href={html_url} rel="noreferrer">
32-
{full_name}
33-
</a>
34-
</Card.Title>
27+
}) => {
28+
const { t } = useContext(I18nContext);
3529

36-
<nav className="flex-fill">
37-
{topics.map(topic => (
38-
<Badge
39-
key={topic}
40-
className="me-1 text-decoration-none"
41-
bg={text2color(topic, ['light'])}
42-
as="a"
43-
target="_blank"
44-
href={`https://github.com/topics/${topic}`}
45-
>
46-
{topic}
47-
</Badge>
48-
))}
49-
</nav>
50-
<Row as="ul" className="list-unstyled g-4" xs={4}>
51-
{languages.map(language => (
52-
<Col key={language} as="li">
53-
<GitLogo name={language} />
54-
</Col>
55-
))}
56-
</Row>
57-
<Card.Text>{description}</Card.Text>
58-
</Card.Body>
59-
<Card.Footer className="d-flex justify-content-between align-items-center">
60-
{homepage && (
61-
<Button variant="success" target="_blank" href={homepage}>
62-
{t('home_page')}
63-
</Button>
64-
)}
65-
</Card.Footer>
66-
</Card>
67-
),
30+
return (
31+
<Card className={className} {...props}>
32+
<Card.Body className="d-flex flex-column gap-3">
33+
<Card.Title as="h3" className="h5">
34+
<a target="_blank" href={html_url} rel="noreferrer">
35+
{full_name}
36+
</a>
37+
</Card.Title>
38+
39+
<nav className="flex-fill">
40+
{topics.map(topic => (
41+
<Badge
42+
key={topic}
43+
className="me-1 text-decoration-none"
44+
bg={text2color(topic, ['light'])}
45+
as="a"
46+
target="_blank"
47+
href={`https://github.com/topics/${topic}`}
48+
>
49+
{topic}
50+
</Badge>
51+
))}
52+
</nav>
53+
<Row as="ul" className="list-unstyled g-4" xs={4}>
54+
{languages.map(language => (
55+
<Col key={language} as="li">
56+
<GitLogo name={language} />
57+
</Col>
58+
))}
59+
</Row>
60+
<Card.Text>{description}</Card.Text>
61+
</Card.Body>
62+
<Card.Footer className="d-flex justify-content-between align-items-center">
63+
{homepage && (
64+
<Button variant="success" target="_blank" href={homepage}>
65+
{t('home_page')}
66+
</Button>
67+
)}
68+
</Card.Footer>
69+
</Card>
70+
);
71+
},
6872
);

components/LarkImage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { TableCellValue } from 'mobx-lark';
22
import { FC } from 'react';
33
import { Image, ImageProps } from 'react-bootstrap';
44

5-
import { DefaultImage, fileURLOf } from '../models/Base';
5+
import { fileURLOf } from '../models/Base';
6+
import { DefaultImage } from '../models/configuration';
67

78
export interface LarkImageProps extends Omit<ImageProps, 'src'> {
89
src?: TableCellValue;

components/Layout/NotFoundCard.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import { observer } from 'mobx-react';
12
import { ErrorProps } from 'next/error';
2-
import Script from 'next/script';
3-
import { FC } from 'react';
3+
import { FC, useContext } from 'react';
44

5-
import { i18n } from '../../models/Translation';
5+
import { I18nContext } from '../../models/Translation';
66

7-
export const NotFoundCard: FC<ErrorProps> = ({ title }) =>
8-
i18n.currentLanguage.startsWith('zh') ? (
9-
<Script
7+
export const NotFoundCard: FC<ErrorProps> = observer(({ title }) => {
8+
const { currentLanguage } = useContext(I18nContext);
9+
10+
return currentLanguage.startsWith('zh') ? (
11+
<script
1012
src="//cdn.dnpw.org/404/v1.min.js"
1113
// @ts-expect-error https://www.dnpw.org/cn/pa-notfound.html
1214
jumptarget="/"
@@ -19,3 +21,4 @@ export const NotFoundCard: FC<ErrorProps> = ({ title }) =>
1921
src="https://notfound-static.fwebservices.be/en/404?key=66abb751ed312"
2022
/>
2123
);
24+
});

components/Layout/PageHead.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import Head from 'next/head';
22
import type { FC, PropsWithChildren } from 'react';
33

4+
import { Name, Summary } from '../../models/configuration';
5+
46
export type PageHeadProps = PropsWithChildren<{
57
title?: string;
68
description?: string;
79
}>;
810

9-
const Name = process.env.NEXT_PUBLIC_SITE_NAME,
10-
Summary = process.env.NEXT_PUBLIC_SITE_SUMMARY;
11-
1211
export const PageHead: FC<PageHeadProps> = ({
1312
title,
1413
description = Summary,

components/Navigator/LanguageMenu.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { Option, Select } from 'idea-react';
22
import { observer } from 'mobx-react';
3-
import { FC } from 'react';
3+
import { FC, useContext } from 'react';
44

5-
import { i18n, LanguageName } from '../../models/Translation';
5+
import { I18nContext, LanguageName } from '../../models/Translation';
66

77
const LanguageMenu: FC = observer(() => {
8-
const { currentLanguage } = i18n;
8+
const i18n = useContext(I18nContext);
99

1010
return (
1111
<Select
12-
value={currentLanguage}
13-
onChange={key => i18n.changeLanguage(key as typeof currentLanguage)}
12+
value={i18n.currentLanguage}
13+
onChange={key => i18n.loadLanguages(key as typeof i18n.currentLanguage)}
1414
>
1515
{Object.entries(LanguageName).map(([key, name]) => (
1616
<Option key={key} value={key}>
Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,50 @@
11
import { observer } from 'mobx-react';
22
import dynamic from 'next/dynamic';
3-
import { FC } from 'react';
3+
import { FC, useContext } from 'react';
44
import { Container, Nav, Navbar } from 'react-bootstrap';
55

6-
import { t } from '../../models/Translation';
6+
import { Name } from '../../models/configuration';
7+
import { I18nContext } from '../../models/Translation';
78

8-
const LanguageMenu = dynamic(import('./LanguageMenu'), { ssr: false });
9+
const LanguageMenu = dynamic(() => import('./LanguageMenu'), { ssr: false });
910

10-
const Name = process.env.NEXT_PUBLIC_SITE_NAME || '';
11+
export const MainNavigator: FC = observer(() => {
12+
const { t } = useContext(I18nContext);
1113

12-
export const MainNavigator: FC = observer(() => (
13-
<Navbar bg="primary" variant="dark" fixed="top" expand="sm" collapseOnSelect>
14-
<Container>
15-
<Navbar.Brand href="/">{Name}</Navbar.Brand>
14+
return (
15+
<Navbar
16+
bg="primary"
17+
variant="dark"
18+
fixed="top"
19+
expand="sm"
20+
collapseOnSelect
21+
>
22+
<Container>
23+
<Navbar.Brand href="/">{Name}</Navbar.Brand>
1624

17-
<Navbar.Toggle aria-controls="navbar-inner" />
25+
<Navbar.Toggle aria-controls="navbar-inner" />
1826

19-
<Navbar.Collapse id="navbar-inner">
20-
<Nav className="me-auto">
21-
<Nav.Link href="/article">{t('article')}</Nav.Link>
27+
<Navbar.Collapse id="navbar-inner">
28+
<Nav className="me-auto">
29+
<Nav.Link href="/article">{t('article')}</Nav.Link>
2230

23-
<Nav.Link href="/component">{t('component')}</Nav.Link>
31+
<Nav.Link href="/component">{t('component')}</Nav.Link>
2432

25-
<Nav.Link href="/pagination">{t('pagination')}</Nav.Link>
33+
<Nav.Link href="/pagination">{t('pagination')}</Nav.Link>
2634

27-
<Nav.Link href="/scroll-list">{t('scroll_list')}</Nav.Link>
35+
<Nav.Link href="/scroll-list">{t('scroll_list')}</Nav.Link>
2836

29-
<Nav.Link
30-
target="_blank"
31-
href="https://github.com/idea2app/Lark-Next-Bootstrap-ts"
32-
>
33-
{t('source_code')}
34-
</Nav.Link>
35-
</Nav>
37+
<Nav.Link
38+
target="_blank"
39+
href="https://github.com/idea2app/Next-Bootstrap-TS"
40+
>
41+
{t('source_code')}
42+
</Nav.Link>
43+
</Nav>
3644

37-
<LanguageMenu />
38-
</Navbar.Collapse>
39-
</Container>
40-
</Navbar>
41-
));
45+
<LanguageMenu />
46+
</Navbar.Collapse>
47+
</Container>
48+
</Navbar>
49+
);
50+
});

components/Navigator/SearchBar.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { observer } from 'mobx-react';
2-
import { FC } from 'react';
2+
import { FC, useContext } from 'react';
33
import {
44
Button,
55
Form,
@@ -9,7 +9,7 @@ import {
99
InputGroupProps,
1010
} from 'react-bootstrap';
1111

12-
import { t } from '../../models/Translation';
12+
import { I18nContext } from '../../models/Translation';
1313
import styles from './SearchBar.module.less';
1414

1515
export interface SearchBarProps
@@ -27,24 +27,30 @@ export const SearchBar: FC<SearchBarProps> = observer(
2727
action = '/search',
2828
size,
2929
name = 'keywords',
30-
placeholder = t('keywords'),
30+
placeholder,
3131
expanded = true,
3232
defaultValue,
3333
value,
3434
onChange,
3535
...props
36-
}) => (
37-
<Form {...{ action, ...props }}>
38-
<InputGroup size={size}>
39-
<Form.Control
40-
className={expanded ? '' : styles.input}
41-
type="search"
42-
{...{ name, placeholder, defaultValue, value, onChange }}
43-
/>
44-
<Button type="submit" variant="light">
45-
🔍
46-
</Button>
47-
</InputGroup>
48-
</Form>
49-
),
36+
}) => {
37+
const { t } = useContext(I18nContext);
38+
39+
placeholder ??= t('keywords');
40+
41+
return (
42+
<Form {...{ action, ...props }}>
43+
<InputGroup size={size}>
44+
<Form.Control
45+
className={expanded ? '' : styles.input}
46+
type="search"
47+
{...{ name, placeholder, defaultValue, value, onChange }}
48+
/>
49+
<Button type="submit" variant="light">
50+
🔍
51+
</Button>
52+
</InputGroup>
53+
</Form>
54+
);
55+
},
5056
);

models/Base.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,17 @@ import { TableCellAttachment, TableCellMedia, TableCellValue } from 'mobx-lark';
66
import { DataObject } from 'mobx-restful';
77
import { buildURLData } from 'web-utility';
88

9-
export const isServer = () => typeof window === 'undefined';
10-
11-
export const VercelHost = process.env.VERCEL_URL,
12-
GithubToken = process.env.GITHUB_TOKEN,
13-
LARK_BASE_ID = process.env.NEXT_PUBLIC_LARK_BASE_ID!;
14-
15-
export const API_Host = isServer()
16-
? VercelHost
17-
? `https://${VercelHost}`
18-
: 'http://localhost:3000'
19-
: globalThis.location.origin;
20-
21-
export const LARK_API_HOST = `${API_Host}/api/Lark/`;
22-
9+
import { GITHUB_TOKEN, LARK_API_HOST } from './configuration';
2310
export const larkClient = new HTTPClient({
2411
baseURI: LARK_API_HOST,
2512
responseType: 'json',
2613
});
2714

2815
githubClient.use(({ request }, next) => {
29-
if (GithubToken)
16+
if (GITHUB_TOKEN)
3017
request.headers = {
3118
...request.headers,
32-
Authorization: `Bearer ${GithubToken}`,
19+
Authorization: `Bearer ${GITHUB_TOKEN}`,
3320
};
3421

3522
return next();
@@ -53,8 +40,6 @@ export async function upload(file: Blob) {
5340
return body!.location;
5441
}
5542

56-
export const DefaultImage = process.env.NEXT_PUBLIC_LOGO!;
57-
5843
export function fileURLOf(field: TableCellValue, cache = false) {
5944
if (!(field instanceof Array) || !field[0]) return field + '';
6045

0 commit comments

Comments
 (0)