Skip to content

Commit 9c5452f

Browse files
committed
perf: ⚡ 优化细节
1 parent de18a27 commit 9c5452f

File tree

9 files changed

+139
-56
lines changed

9 files changed

+139
-56
lines changed

web/public/locale/en.json

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@
5252
"log": "Log",
5353
"setting": "Setting"
5454
},
55+
"toolbar": {
56+
"popover": {
57+
"ariaLabel": "View options",
58+
"layout": "Layout",
59+
"sort": "Sort",
60+
"grid": "Grid",
61+
"list": "List",
62+
"asc": "Asc",
63+
"desc": "Desc",
64+
"filter": {
65+
"title": "Filter",
66+
"channel": {
67+
"all": "All channels",
68+
"enabled": "Enabled only",
69+
"disabled": "Disabled only"
70+
},
71+
"group": {
72+
"all": "All groups",
73+
"withMembers": "With members",
74+
"empty": "Empty groups"
75+
},
76+
"model": {
77+
"all": "All models",
78+
"priced": "Priced only",
79+
"free": "Free only"
80+
}
81+
}
82+
}
83+
},
5584
"common": {
5685
"copy": {
5786
"success": "Copied",
@@ -503,4 +532,4 @@
503532
"remark": "Remark"
504533
}
505534
}
506-
}
535+
}

web/public/locale/zh_hans.json

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@
5252
"log": "日志",
5353
"setting": "设置"
5454
},
55+
"toolbar": {
56+
"popover": {
57+
"ariaLabel": "视图选项",
58+
"layout": "布局",
59+
"sort": "排序",
60+
"grid": "网格",
61+
"list": "列表",
62+
"asc": "升序",
63+
"desc": "降序",
64+
"filter": {
65+
"title": "筛选",
66+
"channel": {
67+
"all": "全部渠道",
68+
"enabled": "仅启用",
69+
"disabled": "仅禁用"
70+
},
71+
"group": {
72+
"all": "全部分组",
73+
"withMembers": "有成员",
74+
"empty": "空分组"
75+
},
76+
"model": {
77+
"all": "全部模型",
78+
"priced": "仅收费",
79+
"free": "仅免费"
80+
}
81+
}
82+
}
83+
},
5584
"common": {
5685
"copy": {
5786
"success": "复制成功",
@@ -503,4 +532,4 @@
503532
"remark": "备注"
504533
}
505534
}
506-
}
535+
}

web/public/locale/zh_hant.json

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@
5252
"log": "日誌",
5353
"setting": "設定"
5454
},
55+
"toolbar": {
56+
"popover": {
57+
"ariaLabel": "檢視選項",
58+
"layout": "佈局",
59+
"sort": "排序",
60+
"grid": "網格",
61+
"list": "清單",
62+
"asc": "升序",
63+
"desc": "降序",
64+
"filter": {
65+
"title": "篩選",
66+
"channel": {
67+
"all": "全部供應源",
68+
"enabled": "僅啟用",
69+
"disabled": "僅停用"
70+
},
71+
"group": {
72+
"all": "全部分組",
73+
"withMembers": "有成員",
74+
"empty": "空分組"
75+
},
76+
"model": {
77+
"all": "全部模型",
78+
"priced": "僅收費",
79+
"free": "僅免費"
80+
}
81+
}
82+
}
83+
},
5584
"common": {
5685
"copy": {
5786
"success": "複製成功",
@@ -503,4 +532,4 @@
503532
"remark": "備註"
504533
}
505534
}
506-
}
535+
}

web/src/components/app.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ export function AppContainer() {
210210
initial={{ opacity: 0 }}
211211
animate={{ opacity: 1 }}
212212
transition={{ duration: 0.3 }}
213-
className="mx-auto h-dvh max-w-6xl overflow-hidden px-3 md:grid md:grid-cols-[auto_1fr] md:gap-6 md:px-6"
213+
className="mx-auto flex h-dvh max-w-6xl flex-col overflow-hidden px-3 md:grid md:grid-cols-[auto_1fr] md:gap-6 md:px-6"
214214
>
215215
<NavBar />
216-
<main className="flex min-h-0 w-full min-w-0 flex-col">
216+
<main className="flex min-h-0 w-full min-w-0 flex-1 flex-col">
217217
<header className="my-6 flex flex-none items-center gap-x-2 px-2">
218218
<Logo size={48} />
219219
<div className="flex-1 overflow-hidden">

web/src/components/modules/channel/Card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function Card({ channel, stats }: { channel: Channel; stats: StatsMetrics
3434
return (
3535
<MorphingDialog>
3636
<MorphingDialogTrigger className="w-full">
37-
<article className="relative flex h-54 flex-col justify-between gap-5 rounded-3xl border border-border bg-card text-card-foreground p-4 transition-all duration-300 hover:scale-[1.02]">
37+
<article className="relative flex h-54 flex-col justify-between gap-5 rounded-3xl border border-border bg-card text-card-foreground p-4 transition-all duration-300">
3838
<header className="relative flex items-center justify-between gap-2">
3939
<Tooltip side="top" sideOffset={10} align="center">
4040
<TooltipTrigger asChild>

web/src/components/modules/home/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { PageWrapper } from '@/components/common/PageWrapper';
88

99
export function Home() {
1010
return (
11-
<PageWrapper className="h-full min-h-0 overflow-y-auto overscroll-contain space-y-6">
11+
<PageWrapper className="h-full min-h-0 overflow-y-auto overscroll-contain space-y-6 pb-24 md:pb-4 rounded-t-3xl">
1212
<Total />
1313
<Activity />
1414
<StatsChart />

web/src/components/modules/log/Item.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ export function LogCard({ log }: { log: RelayLog }) {
201201
<MorphingDialogTrigger
202202
className={cn(
203203
"rounded-3xl border bg-card w-full text-left",
204-
"hover:shadow-md transition-shadow duration-200",
205204
hasError ? "border-destructive/40" : "border-border",
206205
)}
207206
>

web/src/components/modules/setting/index.tsx

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,19 @@ import { SettingCircuitBreaker } from './CircuitBreaker';
1414

1515
export function Setting() {
1616
return (
17-
<PageWrapper className="h-full min-h-0 overflow-y-auto overscroll-contain columns-1 md:columns-2 gap-4 [&>div]:mb-4 [&>div]:break-inside-avoid">
18-
<div>
17+
<div className="h-full min-h-0 overflow-y-auto overscroll-contain rounded-t-3xl">
18+
<PageWrapper className="columns-1 gap-4 pb-24 md:columns-2 md:pb-4 *:mb-4 *:break-inside-avoid">
1919
<SettingInfo key="setting-info" />
20-
</div>
21-
<div>
2220
<SettingAppearance key="setting-appearance" />
23-
</div>
24-
<div>
2521
<SettingAccount key="setting-account" />
26-
</div>
27-
<div>
2822
<SettingSystem key="setting-system" />
29-
</div>
30-
<div>
3123
<SettingLog key="setting-log" />
32-
</div>
33-
<div>
3424
<SettingAPIKey key="setting-apikey" />
35-
</div>
36-
<div>
3725
<SettingLLMPrice key="setting-llmprice" />
38-
</div>
39-
<div>
4026
<SettingLLMSync key="setting-llmsync" />
41-
</div>
42-
<div>
4327
<SettingCircuitBreaker key="setting-circuit-breaker" />
44-
</div>
45-
<div>
4628
<SettingBackup key="setting-backup" />
47-
</div>
48-
</PageWrapper>
29+
</PageWrapper>
30+
</div>
4931
);
5032
}

web/src/components/modules/toolbar/index.tsx

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useNavStore, type NavItem } from '@/components/modules/navbar';
1616
import { CreateDialogContent as ChannelCreateContent } from '@/components/modules/channel/Create';
1717
import { CreateDialogContent as GroupCreateContent } from '@/components/modules/group/Create';
1818
import { CreateDialogContent as ModelCreateContent } from '@/components/modules/model/Create';
19+
import { useTranslations } from 'next-intl';
1920
import { useSearchStore } from './search-store';
2021
import {
2122
useToolbarViewOptionsStore,
@@ -26,21 +27,9 @@ import {
2627
type ModelFilter,
2728
} from './view-options-store';
2829

29-
const CHANNEL_FILTER_OPTIONS: Array<{ value: ChannelFilter; label: string }> = [
30-
{ value: 'all', label: 'All channels' },
31-
{ value: 'enabled', label: 'Enabled only' },
32-
{ value: 'disabled', label: 'Disabled only' },
33-
];
34-
const GROUP_FILTER_OPTIONS: Array<{ value: GroupFilter; label: string }> = [
35-
{ value: 'all', label: 'All groups' },
36-
{ value: 'with-members', label: 'With members' },
37-
{ value: 'empty', label: 'Empty groups' },
38-
];
39-
const MODEL_FILTER_OPTIONS: Array<{ value: ModelFilter; label: string }> = [
40-
{ value: 'all', label: 'All models' },
41-
{ value: 'priced', label: 'Priced only' },
42-
{ value: 'free', label: 'Free only' },
43-
];
30+
const CHANNEL_FILTER_OPTIONS: ChannelFilter[] = ['all', 'enabled', 'disabled'];
31+
const GROUP_FILTER_OPTIONS: GroupFilter[] = ['all', 'with-members', 'empty'];
32+
const MODEL_FILTER_OPTIONS: ModelFilter[] = ['all', 'priced', 'free'];
4433

4534
function isToolbarPage(item: NavItem): item is ToolbarPage {
4635
return (TOOLBAR_PAGES as readonly NavItem[]).includes(item);
@@ -58,6 +47,7 @@ function CreateDialogContent({ activeItem }: { activeItem: ToolbarPage }) {
5847
}
5948

6049
export function Toolbar() {
50+
const t = useTranslations('toolbar');
6151
const { activeItem } = useNavStore();
6252
const toolbarItem = isToolbarPage(activeItem) ? activeItem : null;
6353
const searchTerm = useSearchStore((s) => (toolbarItem ? s.searchTerms[toolbarItem] || '' : ''));
@@ -77,11 +67,36 @@ export function Toolbar() {
7767

7868
if (!toolbarItem) return null;
7969

70+
const channelFilterLabelKeys: Record<ChannelFilter, string> = {
71+
all: 'popover.filter.channel.all',
72+
enabled: 'popover.filter.channel.enabled',
73+
disabled: 'popover.filter.channel.disabled',
74+
};
75+
const groupFilterLabelKeys: Record<GroupFilter, string> = {
76+
all: 'popover.filter.group.all',
77+
'with-members': 'popover.filter.group.withMembers',
78+
empty: 'popover.filter.group.empty',
79+
};
80+
const modelFilterLabelKeys: Record<ModelFilter, string> = {
81+
all: 'popover.filter.model.all',
82+
priced: 'popover.filter.model.priced',
83+
free: 'popover.filter.model.free',
84+
};
85+
8086
const filterOptions = toolbarItem === 'channel'
81-
? CHANNEL_FILTER_OPTIONS
87+
? CHANNEL_FILTER_OPTIONS.map((value) => ({
88+
value,
89+
label: t(channelFilterLabelKeys[value]),
90+
}))
8291
: toolbarItem === 'group'
83-
? GROUP_FILTER_OPTIONS
84-
: MODEL_FILTER_OPTIONS;
92+
? GROUP_FILTER_OPTIONS.map((value) => ({
93+
value,
94+
label: t(groupFilterLabelKeys[value]),
95+
}))
96+
: MODEL_FILTER_OPTIONS.map((value) => ({
97+
value,
98+
label: t(modelFilterLabelKeys[value]),
99+
}));
85100

86101
const activeFilter = toolbarItem === 'channel'
87102
? channelFilter
@@ -154,7 +169,7 @@ export function Toolbar() {
154169
<PopoverTrigger asChild>
155170
<button
156171
type="button"
157-
aria-label="View options"
172+
aria-label={t('popover.ariaLabel')}
158173
className={buttonVariants({
159174
variant: 'ghost',
160175
size: 'icon',
@@ -172,7 +187,7 @@ export function Toolbar() {
172187
>
173188
<div className="grid gap-3">
174189
<div className="grid gap-2">
175-
<p className="text-xs font-medium text-muted-foreground">Layout</p>
190+
<p className="text-xs font-medium text-muted-foreground">{t('popover.layout')}</p>
176191
<div className="grid grid-cols-2 gap-2">
177192
<button
178193
type="button"
@@ -185,7 +200,7 @@ export function Toolbar() {
185200
)}
186201
>
187202
<LayoutGrid className="size-3.5" />
188-
Grid
203+
{t('popover.grid')}
189204
</button>
190205
<button
191206
type="button"
@@ -198,13 +213,13 @@ export function Toolbar() {
198213
)}
199214
>
200215
<List className="size-3.5" />
201-
List
216+
{t('popover.list')}
202217
</button>
203218
</div>
204219
</div>
205220

206221
<div className="grid gap-2">
207-
<p className="text-xs font-medium text-muted-foreground">Sort</p>
222+
<p className="text-xs font-medium text-muted-foreground">{t('popover.sort')}</p>
208223
<div className="grid grid-cols-2 gap-2">
209224
<button
210225
type="button"
@@ -217,7 +232,7 @@ export function Toolbar() {
217232
)}
218233
>
219234
<ArrowDownUp className="size-3.5" />
220-
Asc
235+
{t('popover.asc')}
221236
</button>
222237
<button
223238
type="button"
@@ -230,13 +245,13 @@ export function Toolbar() {
230245
)}
231246
>
232247
<ArrowDownUp className="size-3.5 rotate-180" />
233-
Desc
248+
{t('popover.desc')}
234249
</button>
235250
</div>
236251
</div>
237252

238253
<div className="grid gap-2">
239-
<p className="text-xs font-medium text-muted-foreground">Filter</p>
254+
<p className="text-xs font-medium text-muted-foreground">{t('popover.filter.title')}</p>
240255
<div className="grid gap-2">
241256
{filterOptions.map((option) => (
242257
<button

0 commit comments

Comments
 (0)