diff --git a/app/web/src/components/AppShell.tsx b/app/web/src/components/AppShell.tsx index 7af2238..29e8f16 100644 --- a/app/web/src/components/AppShell.tsx +++ b/app/web/src/components/AppShell.tsx @@ -15,12 +15,46 @@ export function AppShell(props: { children: ReactNode; }) { const base = `/${props.locale}`; + const product = props.labels["meta.product"] ?? props.labels["meta.brand"] ?? "弹弹 Web"; + return ( -
-
{hasMore && ( diff --git a/app/web/src/components/pages/MountsBody.tsx b/app/web/src/components/pages/MountsBody.tsx index 7784144..d0a03e5 100644 --- a/app/web/src/components/pages/MountsBody.tsx +++ b/app/web/src/components/pages/MountsBody.tsx @@ -46,29 +46,34 @@ function MountsInner(props: { locale: Locale }) { }} > setForm({ ...form, name: e.target.value })} required /> setForm({ ...form, baseUrl: e.target.value })} required /> setForm({ ...form, username: e.target.value })} /> setForm({ ...form, password: e.target.value })} /> setForm({ ...form, rootPath: e.target.value })} diff --git a/app/web/src/layouts/AppLayout.astro b/app/web/src/layouts/AppLayout.astro index 9de107d..a5a3026 100644 --- a/app/web/src/layouts/AppLayout.astro +++ b/app/web/src/layouts/AppLayout.astro @@ -22,6 +22,8 @@ export interface Props { seo?: PageSeoInput; /** 媒体页只保留 AppShell 侧栏时隐藏模板 side-rail(含左让位) */ hideSideRail?: boolean; + /** 媒体页隐藏模板页脚 */ + hideFooter?: boolean; } const { @@ -33,10 +35,12 @@ const { switchLabel, seo, hideSideRail = false, + hideFooter = false, } = Astro.props; const brandName = brand ?? t(locale, "meta.brand"); const nav = navProp ?? []; +const isProductBrand = Boolean(brand) && brand !== t(locale, "meta.brand"); const siteSeo = getSiteSeo(locale); const pageSeoInput: PageSeoInput = { @@ -50,8 +54,12 @@ const jsonLdHtml = toJsonLdScript(buildDefaultJsonLd(siteSeo, pageSeoInput)); const pageTitle = headTags.find((tTag) => tTag.key === "og:title")?.value ?? title; const homeHref = locale === "zh-CN" ? "/zh-CN" : "/en"; -const brandHref = homeHref; -const brandInitial = locale === "zh-CN" ? "模" : "A"; +const brandHref = isProductBrand ? (locale === "zh-CN" ? "/zh-CN/library" : "/en/library") : homeHref; +const brandInitial = isProductBrand + ? brandName.charAt(0) + : locale === "zh-CN" + ? "模" + : "A"; --- @@ -210,13 +218,17 @@ const brandInitial = locale === "zh-CN" ? "模" : "A"; -
- - -
+ {!hideFooter && ( +
+ + +
+ )} diff --git a/app/web/src/views/browse.astro b/app/web/src/views/browse.astro index b67b73f..35cf700 100644 --- a/app/web/src/views/browse.astro +++ b/app/web/src/views/browse.astro @@ -13,6 +13,7 @@ const { locale } = Astro.props; const other: Locale = locale === "zh-CN" ? "en" : "zh-CN"; const labels: Record = { "meta.brand": t(locale, "meta.brand"), + "meta.product": t(locale, "meta.product"), "nav.library": t(locale, "nav.library"), "nav.browse": t(locale, "nav.browse"), "nav.mounts": t(locale, "nav.mounts"), @@ -25,6 +26,8 @@ const labels: Record = { locale={locale} nav={[]} hideSideRail + hideFooter + brand={t(locale, "meta.product")} switchHref={alternatePath(Astro.url.pathname, other)} switchLabel={t(other, `locale.${other}` as never)} seo={{ diff --git a/app/web/src/views/danmaku.astro b/app/web/src/views/danmaku.astro index 245b4b9..f072ad5 100644 --- a/app/web/src/views/danmaku.astro +++ b/app/web/src/views/danmaku.astro @@ -13,6 +13,7 @@ const { locale } = Astro.props; const other: Locale = locale === "zh-CN" ? "en" : "zh-CN"; const labels: Record = { "meta.brand": t(locale, "meta.brand"), + "meta.product": t(locale, "meta.product"), "nav.library": t(locale, "nav.library"), "nav.browse": t(locale, "nav.browse"), "nav.mounts": t(locale, "nav.mounts"), @@ -25,6 +26,8 @@ const labels: Record = { locale={locale} nav={[]} hideSideRail + hideFooter + brand={t(locale, "meta.product")} switchHref={alternatePath(Astro.url.pathname, other)} switchLabel={t(other, `locale.${other}` as never)} seo={{ diff --git a/app/web/src/views/library.astro b/app/web/src/views/library.astro index 741a7d2..4d84c71 100644 --- a/app/web/src/views/library.astro +++ b/app/web/src/views/library.astro @@ -13,6 +13,7 @@ const { locale } = Astro.props; const other: Locale = locale === "zh-CN" ? "en" : "zh-CN"; const labels: Record = { "meta.brand": t(locale, "meta.brand"), + "meta.product": t(locale, "meta.product"), "nav.library": t(locale, "nav.library"), "nav.browse": t(locale, "nav.browse"), "nav.mounts": t(locale, "nav.mounts"), @@ -25,6 +26,8 @@ const labels: Record = { locale={locale} nav={[]} hideSideRail + hideFooter + brand={t(locale, "meta.product")} switchHref={alternatePath(Astro.url.pathname, other)} switchLabel={t(other, `locale.${other}` as never)} seo={{ diff --git a/app/web/src/views/mounts.astro b/app/web/src/views/mounts.astro index f26de78..cf64776 100644 --- a/app/web/src/views/mounts.astro +++ b/app/web/src/views/mounts.astro @@ -13,6 +13,7 @@ const { locale } = Astro.props; const other: Locale = locale === "zh-CN" ? "en" : "zh-CN"; const labels: Record = { "meta.brand": t(locale, "meta.brand"), + "meta.product": t(locale, "meta.product"), "nav.library": t(locale, "nav.library"), "nav.browse": t(locale, "nav.browse"), "nav.mounts": t(locale, "nav.mounts"), @@ -25,6 +26,8 @@ const labels: Record = { locale={locale} nav={[]} hideSideRail + hideFooter + brand={t(locale, "meta.product")} switchHref={alternatePath(Astro.url.pathname, other)} switchLabel={t(other, `locale.${other}` as never)} seo={{ diff --git a/app/web/src/views/watch.astro b/app/web/src/views/watch.astro index 723a353..b1d82a3 100644 --- a/app/web/src/views/watch.astro +++ b/app/web/src/views/watch.astro @@ -14,6 +14,7 @@ const { locale, mediaItemId } = Astro.props; const other: Locale = locale === "zh-CN" ? "en" : "zh-CN"; const labels: Record = { "meta.brand": t(locale, "meta.brand"), + "meta.product": t(locale, "meta.product"), "nav.library": t(locale, "nav.library"), "nav.browse": t(locale, "nav.browse"), "nav.mounts": t(locale, "nav.mounts"), @@ -26,6 +27,8 @@ const labels: Record = { locale={locale} nav={[]} hideSideRail + hideFooter + brand={t(locale, "meta.product")} switchHref={alternatePath(Astro.url.pathname, other)} switchLabel={t(other, `locale.${other}` as never)} seo={{ diff --git a/packages/i18n/src/messages/en.ts b/packages/i18n/src/messages/en.ts index f6a0947..b915ad9 100644 --- a/packages/i18n/src/messages/en.ts +++ b/packages/i18n/src/messages/en.ts @@ -3,6 +3,8 @@ import type { MessageKey } from "./zh-CN.js"; /** 与 zh-CN 同构;类型强制 key 对齐。 */ export const en: Record = { "meta.brand": "App Template", + "meta.product": "DanDan Web", + "meta.productTagline": "Local files · online danmaku", "meta.tagline": "Astro · tRPC · Drizzle scaffold", "nav.home": "Home", @@ -48,6 +50,8 @@ export const en: Record = { "library.match": "Match", "library.empty": "No media yet. Scan a mount in the file browser first.", "library.loadMore": "Load more", + "library.ctaBrowse": "Open file browser", + "library.ctaMounts": "Add mount", "library.matchTitle": "Manual Bangumi match", "library.searchWork": "Search by title", "library.bind": "Bind", @@ -61,6 +65,7 @@ export const en: Record = { "browse.root": "Root", "browse.up": "Up", "browse.empty": "Empty directory or no mount selected", + "browse.addMount": "Add mount", "browse.loading": "Loading…", "browse.loadError": "Failed to read directory", "browse.playError": "Failed to add to library", @@ -104,7 +109,7 @@ export const en: Record = { "danmaku.density": "Density", "danmaku.enabled": "Enable danmaku", "danmaku.opacityValue": "Opacity {value}%", - "danmaku.densityValue": "Density {value}x", + "danmaku.densityValue": "Density {value}%", "danmaku.save": "Save", "danmaku.saved": "Saved (local session)", "danmaku.localImportHint": diff --git a/packages/i18n/src/messages/zh-CN.ts b/packages/i18n/src/messages/zh-CN.ts index 7a347c9..6325ebb 100644 --- a/packages/i18n/src/messages/zh-CN.ts +++ b/packages/i18n/src/messages/zh-CN.ts @@ -5,6 +5,8 @@ */ export const zhCN = { "meta.brand": "应用模板", + "meta.product": "弹弹 Web", + "meta.productTagline": "本地片源 · 在线弹幕", "meta.tagline": "Astro · tRPC · Drizzle 脚手架", "nav.home": "首页", @@ -49,6 +51,8 @@ export const zhCN = { "library.match": "匹配", "library.empty": "暂无媒体,请先在文件浏览中扫描挂载。", "library.loadMore": "加载更多", + "library.ctaBrowse": "打开文件浏览", + "library.ctaMounts": "添加挂载", "library.matchTitle": "手动匹配 Bangumi", "library.searchWork": "搜索作品名", "library.bind": "绑定", @@ -62,6 +66,7 @@ export const zhCN = { "browse.root": "根目录", "browse.up": "上一级", "browse.empty": "空目录或未选择挂载", + "browse.addMount": "添加挂载", "browse.loading": "加载中…", "browse.loadError": "目录读取失败", "browse.playError": "入库失败,请重试", @@ -105,7 +110,7 @@ export const zhCN = { "danmaku.density": "密度", "danmaku.enabled": "启用弹幕", "danmaku.opacityValue": "不透明度 {value}%", - "danmaku.densityValue": "密度 {value}x", + "danmaku.densityValue": "密度 {value}%", "danmaku.save": "保存", "danmaku.saved": "已保存(本地会话)", "danmaku.localImportHint": "本地 XML 导入在播放页操作;此处保存默认开关与显示参数。",