Skip to content

Commit

Permalink
refactor: i18n for account pages
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Jan 23, 2024
1 parent 0eedda8 commit a575f99
Show file tree
Hide file tree
Showing 98 changed files with 678 additions and 543 deletions.
14 changes: 13 additions & 1 deletion src/GZCTF/ClientApp/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
{
"liveServer.settings.root": "/build"
"liveServer.settings.root": "/build",
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
"i18n-ally.keystyle": "nested",
"i18n-ally.extract.keyPrefix": "{fileNameWithoutExt}",
"i18n-ally.localesPaths": [
"src/locales"
],
"i18n-ally.extract.autoDetect": true,
"i18n-ally.extract.keyMaxLength": 20,
"i18n-ally.extract.keygenStyle": "snake_case",
"i18n-ally.sortKeys": true,
"i18n-ally.sourceLanguage": "zh"
}
1 change: 1 addition & 0 deletions src/GZCTF/ClientApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
},
"devDependencies": {
"@babel/eslint-parser": "^7.23.3",
"@kainstar/vite-plugin-i18next-loader": "^1.0.2",
"@nabla/vite-plugin-eslint": "^2.0.2",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/katex": "^0.16.7",
Expand Down
220 changes: 131 additions & 89 deletions src/GZCTF/ClientApp/pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { useLocalStorage } from '@mantine/hooks'
import { ModalsProvider } from '@mantine/modals'
import { Notifications } from '@mantine/notifications'
import { FC, Suspense } from 'react'
import { useTranslation } from 'react-i18next'
import { useRoutes } from 'react-router-dom'
import { SWRConfig } from 'swr'
import routes from '~react-pages'
import { useTranslation } from '@Utils/I18n'
import { ThemeOverride } from '@Utils/ThemeOverride'
import { useBanner, useLocalStorageCache } from '@Utils/useConfig'
import { fetcher } from '@Api'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from '@mantine/core'
import { Icon } from '@mdi/react'
import { FC, useState } from 'react'
import { useTranslation } from '@Utils/I18n'
import { useTranslation } from 'react-i18next'

export interface ActionIconWithConfirmProps {
iconPath: string
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
} from '@mdi/js'
import { Icon } from '@mdi/react'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import LogoHeader from '@Components/LogoHeader'
import { useTranslation } from '@Utils/I18n'
import { useIsMobile } from '@Utils/ThemeOverride'
import { useLocalStorageCache } from '@Utils/useConfig'
import { useLoginOut, useUser } from '@Utils/useUser'
Expand Down
60 changes: 33 additions & 27 deletions src/GZCTF/ClientApp/src/components/AppNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import {
} from '@mdi/js'
import { Icon } from '@mdi/react'
import React, { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import MainIcon from '@Components/icon/MainIcon'
import { useTranslation } from '@Utils/I18n'
import { useLocalStorageCache } from '@Utils/useConfig'
import { useLoginOut, useUser } from '@Utils/useUser'
import { Role } from '@Api'
Expand Down Expand Up @@ -88,15 +88,6 @@ interface NavbarItem {
admin?: boolean
}

const items: NavbarItem[] = [
{ icon: mdiHomeVariantOutline, label: t('主页'), link: '/' },
{ icon: mdiNoteTextOutline, label: t('文章'), link: '/posts' },
{ icon: mdiFlagOutline, label: t('赛事'), link: '/games' },
{ icon: mdiAccountGroupOutline, label: t('队伍'), link: '/teams' },
{ icon: mdiInformationOutline, label: t('关于'), link: '/about' },
{ icon: mdiWrenchOutline, label: t('管理'), link: '/admin/games', admin: true },
]

export interface NavbarLinkProps {
icon: string
label?: string
Expand All @@ -122,29 +113,37 @@ const NavbarLink: FC<NavbarLinkProps> = (props: NavbarLinkProps) => {
)
}

const getLabel = (path: string) =>
items.find((item) =>
item.link === '/'
? path === '/'
: item.link.startsWith('/admin')
? path.startsWith('/admin')
: path.startsWith(item.link)
)?.label

const AppNavbar: FC = () => {
const location = useLocation()
const navigate = useNavigate()
const { classes } = useStyles()

const [active, setActive] = useState(getLabel(location.pathname) ?? '')
const { colorScheme, toggleColorScheme } = useMantineColorScheme()

const logout = useLoginOut()
const { clearLocalCache } = useLocalStorageCache()
const { user, error } = useUser()

const { t } = useTranslation()

const items: NavbarItem[] = [
{ icon: mdiHomeVariantOutline, label: t('common.tab.home'), link: '/' },
{ icon: mdiNoteTextOutline, label: t('common.tab.post'), link: '/posts' },
{ icon: mdiFlagOutline, label: t('common.tab.game'), link: '/games' },
{ icon: mdiAccountGroupOutline, label: t('common.tab.team'), link: '/teams' },
{ icon: mdiInformationOutline, label: t('common.tab.about'), link: '/about' },
{ icon: mdiWrenchOutline, label: t('common.tab.manage'), link: '/admin/games', admin: true },
]

const getLabel = (path: string) =>
items.find((item) =>
item.link === '/'
? path === '/'
: item.link.startsWith('/admin')
? path.startsWith('/admin')
: path.startsWith(item.link)
)?.label

const [active, setActive] = useState(getLabel(location.pathname) ?? '')

useEffect(() => {
if (location.pathname === '/') {
setActive(items[0].label)
Expand Down Expand Up @@ -184,7 +183,10 @@ const AppNavbar: FC = () => {
<Stack align="center" spacing={5}>
{/* Color Mode */}
<Tooltip
label={'切换至' + (colorScheme === 'dark' ? '浅色' : '深色') + '主题'}
label={t('common.tab.theme.switch_to', {
theme:
colorScheme === 'dark' ? t('common.tab.theme.light') : t('common.tab.theme.dark'),
})}
classNames={{ tooltip: classes.tooltipBody }}
position="right"
>
Expand Down Expand Up @@ -219,18 +221,22 @@ const AppNavbar: FC = () => {
to="/account/profile"
icon={<Icon path={mdiAccountCircleOutline} size={1} />}
>
用户信息
{t('common.tab.account.profile')}
</Menu.Item>
<Menu.Item onClick={clearLocalCache} icon={<Icon path={mdiCached} size={1} />}>
清除缓存
{t('common.tab.account.clean_cache')}
</Menu.Item>
<Menu.Item color="red" onClick={logout} icon={<Icon path={mdiLogout} size={1} />}>
登出
{t('common.tab.account.logout')}
</Menu.Item>
</Menu.Dropdown>
</Menu>
) : (
<Tooltip label="登录" classNames={{ tooltip: classes.tooltipBody }} position="right">
<Tooltip
label={t('common.tab.account.login')}
classNames={{ tooltip: classes.tooltipBody }}
position="right"
>
<ActionIcon
component={Link}
to={`/account/login?from=${location.pathname}`}
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/ChallengeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { mdiFlag } from '@mdi/js'
import { Icon } from '@mdi/react'
import dayjs from 'dayjs'
import { FC } from 'react'
import { useTranslation } from '@Utils/I18n'
import { useTranslation } from 'react-i18next'
import { BloodsTypes, ChallengeTagLabelMap } from '@Utils/Shared'
import { useTooltipStyles } from '@Utils/ThemeOverride'
import { ChallengeInfo, SubmissionType } from '@Api'
Expand Down
90 changes: 45 additions & 45 deletions src/GZCTF/ClientApp/src/components/ChallengeDetailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { notifications, showNotification, updateNotification } from '@mantine/no
import { mdiCheck, mdiClose, mdiDownload, mdiLightbulbOnOutline, mdiLoading } from '@mdi/js'
import { Icon } from '@mdi/react'
import React, { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import MarkdownRender, { InlineMarkdownRender } from '@Components/MarkdownRender'
import { showErrorNotification } from '@Utils/ApiErrorHandler'
import { useTranslation } from '@Utils/I18n'
import { ChallengeTagItemProps } from '@Utils/Shared'
import { useTooltipStyles } from '@Utils/ThemeOverride'
import { OnceSWRConfig } from '@Utils/useConfig'
Expand All @@ -39,53 +39,53 @@ interface ChallengeDetailModalProps extends ModalProps {
}

export const FlagPlaceholders: string[] = [
t('横看成岭侧成峰,flag 高低各不同'),
t('flag 当关,万夫莫开'),
t('寻寻觅觅,冷冷清清,flag 惨惨戚戚'),
t('问君能有几多愁?恰似一江 flag 向东流'),
t('人生得意须尽欢,莫使 flag 空对月'),
t('汉皇重色思 flag,御宇多年求不得'),
t('flag 几时有?把酒问青天'),
t('羽扇纶巾,谈笑间,flag 灰飞烟灭'),
t('浊酒一杯家万里,flag 未勒归无计'),
t('孤帆远影碧空尽,唯见 flag 天际流'),
t('安得 flag 千万间,大庇天下 ctfer 俱欢颜!'),
t('两个黄鹂鸣翠柳,一行 flag 上青天'),
t('flag 一场大梦,人生几度秋凉?'),
t('剪不断,理还乱,是 flag'),
t('蓦然回首,flag 却在,灯火阑珊处'),
t('稻花香里说丰年,听取 flag 一片'),
t('采菊东篱下,悠然见 flag'),
t('不畏 flag 遮望眼,自缘身在最高层'),
t('便纵有千种 flag,更与何人说?'),
t('人生自古谁无死?留取 flag 照汗青'),
t('借问 flag 何处有?牧童遥指杏花村'),
'横看成岭侧成峰,flag 高低各不同',
'flag 当关,万夫莫开',
'寻寻觅觅,冷冷清清,flag 惨惨戚戚',
'问君能有几多愁?恰似一江 flag 向东流',
'人生得意须尽欢,莫使 flag 空对月',
'汉皇重色思 flag,御宇多年求不得',
'flag 几时有?把酒问青天',
'羽扇纶巾,谈笑间,flag 灰飞烟灭',
'浊酒一杯家万里,flag 未勒归无计',
'孤帆远影碧空尽,唯见 flag 天际流',
'安得 flag 千万间,大庇天下 ctfer 俱欢颜!',
'两个黄鹂鸣翠柳,一行 flag 上青天',
'flag 一场大梦,人生几度秋凉?',
'剪不断,理还乱,是 flag',
'蓦然回首,flag 却在,灯火阑珊处',
'稻花香里说丰年,听取 flag 一片',
'采菊东篱下,悠然见 flag',
'不畏 flag 遮望眼,自缘身在最高层',
'便纵有千种 flag,更与何人说?',
'人生自古谁无死?留取 flag 照汗青',
'借问 flag 何处有?牧童遥指杏花村',
]

export const WrongFlagHints: string[] = [
t('饮水思源,重新审题吧。'),
t('诗云:路漫漫其修远兮,再接再厉吧。'),
t('沉着冷静,可能会有意想不到的收获。'),
t('失败乃成功之母,回去再琢磨琢磨。'),
t('非也非也,不是这个 flag。'),
t('望眼欲穿,flag 却不在这里。'),
t('不要浮躁,仔细再思考思考。'),
t('翻遍天涯,也不是这个答案。'),
t('走马观花,可找不到 flag。'),
t('反复推敲,答案应该就在你手边。'),
t('深谋远虑,flag 不是那么简单。'),
t('山高水远,flag 藏得真是深啊!'),
t('时运不济,碾过你的难道是寂寞?'),
t('兴奋过头,还需要学会更加冷静的思考。'),
t('碰壁了,难道是你已经到了巅峰?'),
t('岁月静好,flag 却已然远去。'),
t('浅水已涸,flag 不可复得。'),
t('白雪纷纷何所似,似此 flag 被错过。'),
t('旧事追思,往事如烟。flag 已然消逝。'),
t('桃花潭水深千尺,不及 flag 不见了踪迹。'),
t('万籁俱寂,唯有 flag 的错误提示在耳边响起。'),
t('陌上花开,可缓缓归矣。flag 未得而返。'),
t('风萧萧兮易水寒,无奈 flag 仍未到彼岸。'),
'饮水思源,重新审题吧。',
'诗云:路漫漫其修远兮,再接再厉吧。',
'沉着冷静,可能会有意想不到的收获。',
'失败乃成功之母,回去再琢磨琢磨。',
'非也非也,不是这个 flag。',
'望眼欲穿,flag 却不在这里。',
'不要浮躁,仔细再思考思考。',
'翻遍天涯,也不是这个答案。',
'走马观花,可找不到 flag。',
'反复推敲,答案应该就在你手边。',
'深谋远虑,flag 不是那么简单。',
'山高水远,flag 藏得真是深啊!',
'时运不济,碾过你的难道是寂寞?',
'兴奋过头,还需要学会更加冷静的思考。',
'碰壁了,难道是你已经到了巅峰?',
'岁月静好,flag 却已然远去。',
'浅水已涸,flag 不可复得。',
'白雪纷纷何所似,似此 flag 被错过。',
'旧事追思,往事如烟。flag 已然消逝。',
'桃花潭水深千尺,不及 flag 不见了踪迹。',
'万籁俱寂,唯有 flag 的错误提示在耳边响起。',
'陌上花开,可缓缓归矣。flag 未得而返。',
'风萧萧兮易水寒,无奈 flag 仍未到彼岸。',
]

const ChallengeDetailModal: FC<ChallengeDetailModalProps> = (props) => {
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/ChallengePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import { mdiFileUploadOutline, mdiFlagOutline, mdiPuzzle } from '@mdi/js'
import { Icon } from '@mdi/react'
import dayjs from 'dayjs'
import React, { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useParams } from 'react-router-dom'
import ChallengeCard from '@Components/ChallengeCard'
import ChallengeDetailModal from '@Components/ChallengeDetailModal'
import Empty from '@Components/Empty'
import WriteupSubmitModal from '@Components/WriteupSubmitModal'
import { useTranslation } from '@Utils/I18n'
import { ChallengeTagLabelMap, SubmissionTypeIconMap } from '@Utils/Shared'
import { useGame } from '@Utils/useGame'
import api, { ChallengeInfo, ChallengeTag, SubmissionType } from '@Api'
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/Empty.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { MantineNumberSize, Stack, Text } from '@mantine/core'
import { mdiInbox } from '@mdi/js'
import { Icon } from '@mdi/react'
import { FC, ReactNode } from 'react'
import { useTranslation } from '@Utils/I18n'
import { useTranslation } from 'react-i18next'

interface EmptyProps {
bordered?: boolean
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/GameCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
import { mdiChevronTripleRight, mdiFlagOutline } from '@mdi/js'
import { Icon } from '@mdi/react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import { useTranslation } from '@Utils/I18n'
import { getGameStatus } from '@Utils/useGame'
import { BasicGameInfoModel } from '@Api'

Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/GameJoinModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { showNotification } from '@mantine/notifications'
import { mdiClose } from '@mdi/js'
import { Icon } from '@mdi/react'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useParams } from 'react-router-dom'
import { useTranslation } from '@Utils/I18n'
import { useGame } from '@Utils/useGame'
import { useTeams } from '@Utils/useUser'
import { GameJoinModel } from '@Api'
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/GameNoticePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { Icon } from '@mdi/react'
import * as signalR from '@microsoft/signalr'
import dayjs from 'dayjs'
import { FC, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useParams } from 'react-router-dom'
import Empty from '@Components/Empty'
import { InlineMarkdownRender } from '@Components/MarkdownRender'
import { useTranslation } from '@Utils/I18n'
import { NoticTypeIconMap } from '@Utils/Shared'
import api, { GameNotice, NoticeType } from '@Api'

Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/HintList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { mdiClose, mdiPlus } from '@mdi/js'
import { Icon } from '@mdi/react'
import { FC } from 'react'
import { useTranslation } from '@Utils/I18n'
import { useTranslation } from 'react-i18next'

interface HintListProps extends TextInputProps {
hints: string[]
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/InstanceEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Icon } from '@mdi/react'
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from '@Utils/I18n'
import { useTranslation } from 'react-i18next'
import { getProxyUrl } from '@Utils/Shared'
import { useTooltipStyles } from '@Utils/ThemeOverride'
import { ClientFlagContext } from '@Api'
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/components/MobilePostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { mdiPencilOutline, mdiPinOffOutline, mdiPinOutline } from '@mdi/js'
import { Icon } from '@mdi/react'
import dayjs from 'dayjs'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
import MarkdownRender from '@Components/MarkdownRender'
import { PostCardProps } from '@Components/PostCard'
import { RequireRole } from '@Components/WithRole'
import { useTranslation } from '@Utils/I18n'
import { useUserRole } from '@Utils/useUser'
import { Role } from '@Api'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
} from '@mantine/core'
import dayjs from 'dayjs'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import TeamRadarMap from '@Components/TeamRadarMap'
import { useTranslation } from '@Utils/I18n'
import { BonusLabel } from '@Utils/Shared'
import { useTableStyles } from '@Utils/ThemeOverride'
import { ChallengeInfo, ScoreboardItem, SubmissionType } from '@Api'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Avatar, Box, Group, Input, Pagination, Paper, Select, Stack, Table } from '@mantine/core'
import React, { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useParams } from 'react-router-dom'
import MobileScoreboardItemModal from '@Components/MobileScoreboardItemModal'
import { ScoreboardProps, useScoreboardStyles } from '@Components/ScoreboardTable'
import { useTranslation } from '@Utils/I18n'
import { BloodBonus } from '@Utils/Shared'
import { useGameScoreboard } from '@Utils/useGame'
import { ScoreboardItem, SubmissionType } from '@Api'
Expand Down
Loading

0 comments on commit a575f99

Please sign in to comment.