feat(viewer): album page with locale fallback and timezone display
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -25,19 +25,21 @@ function resolveInitialLocale(): ViewerLocale {
|
||||
return FALLBACK_LOCALE;
|
||||
}
|
||||
|
||||
export const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: resolveInitialLocale(),
|
||||
fallbackLocale: FALLBACK_LOCALE,
|
||||
messages: { 'zh-CN': zhCN, en },
|
||||
});
|
||||
|
||||
// 切换语言并持久化;写失败不阻断切换。
|
||||
export function setLocale(locale: ViewerLocale): void {
|
||||
i18n.global.locale.value = locale;
|
||||
try {
|
||||
localStorage.setItem(LOCALE_STORAGE_KEY, locale);
|
||||
} catch {
|
||||
// 忽略持久化失败
|
||||
}
|
||||
/**
|
||||
* 构建 viewer i18n 实例(运行时单例与测试各自构造)。
|
||||
* 组件测试必须每次挂载用新实例:vue-i18n 的 install 会包装 app.unmount 调
|
||||
* i18n.dispose()——共享单例被任一测试卸载后全局 composer 反应性即永久失效
|
||||
* (locale 写入不再传播)。运行时 main.ts 只挂载一次,不受影响。
|
||||
*/
|
||||
export function createViewerI18n(initialLocale: ViewerLocale = resolveInitialLocale()) {
|
||||
return createI18n({
|
||||
legacy: false,
|
||||
locale: initialLocale,
|
||||
fallbackLocale: FALLBACK_LOCALE,
|
||||
messages: { 'zh-CN': zhCN, en },
|
||||
});
|
||||
}
|
||||
|
||||
export type ViewerI18n = ReturnType<typeof createViewerI18n>;
|
||||
|
||||
export const i18n = createViewerI18n();
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
export default {
|
||||
app: { title: 'Live Gallery' },
|
||||
home: { hint: 'Open an album link to start viewing' },
|
||||
album: { emptyNotice: 'Photos coming soon' },
|
||||
album: {
|
||||
loading: 'Loading…',
|
||||
emptyNotice: 'Photos coming soon',
|
||||
time: 'Time',
|
||||
venue: 'Venue',
|
||||
categories: 'Categories',
|
||||
retry: 'Retry',
|
||||
},
|
||||
lang: { switch: 'Switch language' },
|
||||
route: { tokenLabel: 'Album token', photoLabel: 'Photo' },
|
||||
errors: {
|
||||
albumNotFound: 'Album not found',
|
||||
albumNotAvailable: 'Album unavailable',
|
||||
// ALBUM_NOT_PUBLIC 专用:offline / disabled / ghost token 同码(防枚举)。
|
||||
albumNotAvailable: 'Album not found or offline',
|
||||
photoNotFound: 'Photo not found',
|
||||
notFound: 'Page not found',
|
||||
authExpired: 'Session expired',
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
export default {
|
||||
app: { title: '现场相册' },
|
||||
home: { hint: '打开相册链接即可观看' },
|
||||
album: { emptyNotice: '照片即将上线' },
|
||||
album: {
|
||||
loading: '加载中…',
|
||||
emptyNotice: '照片即将上线',
|
||||
time: '时间',
|
||||
venue: '地点',
|
||||
categories: '分类',
|
||||
retry: '重试',
|
||||
},
|
||||
lang: { switch: '切换语言' },
|
||||
route: { tokenLabel: '相册令牌', photoLabel: '照片' },
|
||||
errors: {
|
||||
albumNotFound: '相册不存在',
|
||||
albumNotAvailable: '相册不可用',
|
||||
// ALBUM_NOT_PUBLIC 专用:offline / publicEnabled=false / 幽灵 token 同码(防枚举),
|
||||
// 文案需同时覆盖「不存在」与「已下线」两种用户可理解成因。
|
||||
albumNotAvailable: '相册不存在或已下线',
|
||||
photoNotFound: '照片不存在',
|
||||
notFound: '页面不存在',
|
||||
authExpired: '登录已过期',
|
||||
|
||||
Reference in New Issue
Block a user