feat: implement browser extension for media publishing and add backend support for media management
This commit is contained in:
@@ -112,7 +112,7 @@ const enUS = {
|
||||
},
|
||||
media: {
|
||||
title: "Media Management",
|
||||
description: "No matching backend APIs exist in this repository yet.",
|
||||
description: "Manage media bindings, local extension state, and one-click publishing from a single control plane.",
|
||||
},
|
||||
brands: {
|
||||
title: "Brand Library",
|
||||
@@ -196,6 +196,9 @@ const enUS = {
|
||||
publish: {
|
||||
unpublished: "Unpublished",
|
||||
publishing: "Publishing",
|
||||
success: "Published",
|
||||
failed: "Failed",
|
||||
partial_success: "Partial Success",
|
||||
published: "Published",
|
||||
publish_success: "Published",
|
||||
publish_failed: "Failed",
|
||||
@@ -230,6 +233,7 @@ const enUS = {
|
||||
preview: "Preview",
|
||||
edit: "Edit article",
|
||||
editDisabled: "Only draft, failed, or completed articles can be edited",
|
||||
publishDisabled: "Only completed articles can be published",
|
||||
versions: "Versions",
|
||||
deleteConfirm: "Delete this article?",
|
||||
deleteSuccess: "Article deleted.",
|
||||
@@ -384,6 +388,7 @@ const enUS = {
|
||||
drawerTitle: "Article details",
|
||||
preview: "Content preview",
|
||||
versionHistory: "Version history",
|
||||
publishedDetails: "Published details",
|
||||
untitled: "Untitled article",
|
||||
noContent: "This article does not have generated content yet.",
|
||||
editor: {
|
||||
@@ -405,7 +410,7 @@ const enUS = {
|
||||
saved: "Article saved.",
|
||||
generating: "This article is still generating. Try editing it later.",
|
||||
locked: "Only completed articles can be edited.",
|
||||
publishPending: "Publishing is not wired yet. The current action only saves content.",
|
||||
publishPending: "Save the article first, then choose the target platforms.",
|
||||
},
|
||||
platforms: {
|
||||
zhihu: "Zhihu",
|
||||
@@ -419,6 +424,90 @@ const enUS = {
|
||||
},
|
||||
versionUntitled: "Untitled version",
|
||||
},
|
||||
media: {
|
||||
hero: {
|
||||
eyebrow: "Publisher",
|
||||
},
|
||||
plugin: {
|
||||
title: "Browser Publisher",
|
||||
ready: "Extension connected",
|
||||
notInstalled: "Extension not connected",
|
||||
installTitle: "Install and open the GEO Publisher extension first",
|
||||
installDesc: "Binding and publishing depend on the browser's local platform sessions. The extension stores its own installation identity so future background checks can continue after the SaaS page is closed.",
|
||||
backgroundHint: "The extension should not reuse the web app's access token directly. This implementation already registers a dedicated installation identity for future background scanning and inclusion checks.",
|
||||
versionLabel: "Extension version",
|
||||
installationLabel: "Installation ID",
|
||||
connectedSummary: "Locally signed-in platforms",
|
||||
registerRequired: "The extension installation is not registered yet. Please re-detect first.",
|
||||
},
|
||||
actions: {
|
||||
redetect: "Re-detect",
|
||||
bind: "Bind",
|
||||
rebind: "Rebind",
|
||||
unbind: "Unbind",
|
||||
},
|
||||
card: {
|
||||
bound: "Bound",
|
||||
unbound: "Unbound",
|
||||
unboundHint: "{platform} has not been bound to this tenant yet.",
|
||||
needsAttention: "Needs attention",
|
||||
expiredHint: "This account is no longer healthy. Rebind it to restore publishing.",
|
||||
localMissing: "Local session missing",
|
||||
localMismatch: "Local account mismatch",
|
||||
readyHint: "The correct local account is available and ready for publish or future background checks.",
|
||||
accountLabel: "SaaS account",
|
||||
uidLabel: "Platform UID",
|
||||
localLabel: "Local state",
|
||||
localConnected: "Session detected",
|
||||
localDisconnected: "No session detected",
|
||||
updatedAt: "Last sync",
|
||||
multiAccount: "{count} accounts bound",
|
||||
openPlatform: "Open platform",
|
||||
},
|
||||
account: {
|
||||
localMissing: "The tenant account is bound, but this browser does not currently have the matching local session.",
|
||||
localMismatch: "This browser is signed in to a different account. Rebind or switch the local account first.",
|
||||
ready: "Ready",
|
||||
selectable: "Selectable",
|
||||
unavailable: "Unavailable",
|
||||
},
|
||||
empty: {
|
||||
accounts: "No publishable media accounts are bound yet.",
|
||||
},
|
||||
messages: {
|
||||
bindSuccess: "{platform} bound successfully.",
|
||||
bindPending: "The extension did not detect a local session for this platform yet. Sign in via the extension and retry.",
|
||||
unbindSuccess: "Account unbound.",
|
||||
unbindConfirm: "Unbind this platform account? Publishing will no longer be available until it is bound again.",
|
||||
},
|
||||
publish: {
|
||||
title: "Publish",
|
||||
subtitle: "Multi-platform Dispatch",
|
||||
description: "Choose tenant-bound accounts that are currently signed in locally. The extension executes the real publish flow and writes back the resulting links.",
|
||||
platformsTitle: "Target platforms",
|
||||
platformsHint: "Only tenant-bound accounts are listed here. Accounts with missing or mismatched local sessions are disabled automatically.",
|
||||
coverTitle: "Cover image",
|
||||
coverHint: "This version uses a cover asset URL. Upload and crop can be wired later.",
|
||||
coverPlaceholder: "Enter an optional cover asset URL",
|
||||
messages: {
|
||||
success: "{count} publish tasks submitted.",
|
||||
partial: "Publish finished with {success} succeeded and {failed} failed.",
|
||||
selectPlatform: "Choose at least one available platform first.",
|
||||
},
|
||||
},
|
||||
records: {
|
||||
tabTitle: "Published details",
|
||||
platform: "Platform",
|
||||
status: "Status",
|
||||
publishedAt: "Published at",
|
||||
link: "Published link",
|
||||
open: "Open",
|
||||
copy: "Copy",
|
||||
empty: "No publish records yet",
|
||||
linkEmpty: "No link is available for this record yet.",
|
||||
copySuccess: "Link copied.",
|
||||
},
|
||||
},
|
||||
brands: {
|
||||
eyebrow: "Brand Library",
|
||||
title: "Brand Library",
|
||||
|
||||
@@ -112,7 +112,7 @@ const zhCN = {
|
||||
},
|
||||
media: {
|
||||
title: "媒体管理",
|
||||
description: "当前仓库还没有匹配的后端接口,页面暂保持为设计占位。",
|
||||
description: "统一管理媒体账号绑定、本地插件状态和一键发布执行链路。",
|
||||
},
|
||||
brands: {
|
||||
title: "品牌词库",
|
||||
@@ -196,6 +196,9 @@ const zhCN = {
|
||||
publish: {
|
||||
unpublished: "未发布",
|
||||
publishing: "发布中",
|
||||
success: "发布成功",
|
||||
failed: "发布失败",
|
||||
partial_success: "部分成功",
|
||||
published: "发布成功",
|
||||
publish_success: "发布成功",
|
||||
publish_failed: "发布失败",
|
||||
@@ -230,6 +233,7 @@ const zhCN = {
|
||||
preview: "预览正文",
|
||||
edit: "编辑文章",
|
||||
editDisabled: "只有草稿、生成失败或已完成文章才可编辑",
|
||||
publishDisabled: "只有已完成文章才可发布",
|
||||
versions: "查看版本",
|
||||
deleteConfirm: "确认删除这篇文章吗?",
|
||||
deleteSuccess: "文章已删除",
|
||||
@@ -391,6 +395,7 @@ const zhCN = {
|
||||
drawerTitle: "文章详情",
|
||||
preview: "正文预览",
|
||||
versionHistory: "版本记录",
|
||||
publishedDetails: "已发布详情",
|
||||
untitled: "未命名文章",
|
||||
noContent: "当前文章还没有正文内容",
|
||||
editor: {
|
||||
@@ -412,7 +417,7 @@ const zhCN = {
|
||||
saved: "文章已保存",
|
||||
generating: "文章还在生成中,请稍后再编辑。",
|
||||
locked: "只有已完成文章才可编辑。",
|
||||
publishPending: "发布能力待接入,当前仅保存正文内容。",
|
||||
publishPending: "请先保存文章,再选择需要发布的平台。",
|
||||
},
|
||||
platforms: {
|
||||
zhihu: "知乎",
|
||||
@@ -426,6 +431,90 @@ const zhCN = {
|
||||
},
|
||||
versionUntitled: "未命名版本",
|
||||
},
|
||||
media: {
|
||||
hero: {
|
||||
eyebrow: "Publisher",
|
||||
},
|
||||
plugin: {
|
||||
title: "浏览器发布器",
|
||||
ready: "插件已连接",
|
||||
notInstalled: "插件未连接",
|
||||
installTitle: "请先安装并打开 GEO Publisher 插件",
|
||||
installDesc: "绑定和发布都依赖浏览器本地登录态执行。插件会保存独立安装实例身份,后续即使网页关闭,也能继续运行后台检测任务。",
|
||||
backgroundHint: "插件不会直接复用网页 access token。当前实现会为每个浏览器安装实例注册独立身份,为未来后台收录检测和定时扫描预留能力。",
|
||||
versionLabel: "插件版本",
|
||||
installationLabel: "安装实例 ID",
|
||||
connectedSummary: "本地已登录平台",
|
||||
registerRequired: "插件安装实例尚未注册,请先重新检测。",
|
||||
},
|
||||
actions: {
|
||||
redetect: "重新检测",
|
||||
bind: "去绑定",
|
||||
rebind: "重新绑定",
|
||||
unbind: "解绑",
|
||||
},
|
||||
card: {
|
||||
bound: "已绑定",
|
||||
unbound: "未绑定",
|
||||
unboundHint: "{platform} 还未绑定到当前租户,可以直接发起授权。",
|
||||
needsAttention: "需要处理",
|
||||
expiredHint: "该账号状态异常,建议重新绑定以恢复发布能力。",
|
||||
localMissing: "本地未登录",
|
||||
localMismatch: "本地账号不匹配",
|
||||
readyHint: "当前浏览器已检测到正确账号,可以直接用于发布和后续后台检测。",
|
||||
accountLabel: "SaaS 账号",
|
||||
uidLabel: "平台 UID",
|
||||
localLabel: "本地状态",
|
||||
localConnected: "已检测到登录态",
|
||||
localDisconnected: "未检测到登录态",
|
||||
updatedAt: "最近同步",
|
||||
multiAccount: "已绑定 {count} 个账号",
|
||||
openPlatform: "打开平台官网",
|
||||
},
|
||||
account: {
|
||||
localMissing: "SaaS 已绑定,但当前浏览器未检测到对应登录态。",
|
||||
localMismatch: "当前浏览器登录的是另一个账号,请重新授权或切换账号。",
|
||||
ready: "已就绪",
|
||||
selectable: "可发布",
|
||||
unavailable: "不可用",
|
||||
},
|
||||
empty: {
|
||||
accounts: "当前租户还没有绑定可发布账号。",
|
||||
},
|
||||
messages: {
|
||||
bindSuccess: "{platform} 绑定成功",
|
||||
bindPending: "插件尚未检测到该平台登录态,请先在插件中登录后重试。",
|
||||
unbindSuccess: "账号解绑成功",
|
||||
unbindConfirm: "确认解绑这个平台账号吗?解绑后将无法直接发布。",
|
||||
},
|
||||
publish: {
|
||||
title: "发布",
|
||||
subtitle: "Multi-platform Dispatch",
|
||||
description: "选择当前浏览器已登录且租户已绑定的平台,插件会逐个平台执行真实发布并回写链接。",
|
||||
platformsTitle: "发布平台",
|
||||
platformsHint: "仅展示当前租户已绑定的账号。插件本地登录态异常的平台会自动禁用。",
|
||||
coverTitle: "封面图",
|
||||
coverHint: "当前版本先使用封面素材 URL,后续可以接入上传与裁剪。",
|
||||
coverPlaceholder: "请输入封面素材 URL(可选)",
|
||||
messages: {
|
||||
success: "已提交 {count} 个平台发布任务",
|
||||
partial: "发布执行完成,成功 {success} 个,失败 {failed} 个",
|
||||
selectPlatform: "请先选择至少一个可发布的平台",
|
||||
},
|
||||
},
|
||||
records: {
|
||||
tabTitle: "已发布详情",
|
||||
platform: "已发布平台",
|
||||
status: "发布状态",
|
||||
publishedAt: "发布时间",
|
||||
link: "已发布链接",
|
||||
open: "打开",
|
||||
copy: "复制",
|
||||
empty: "暂无发布记录",
|
||||
linkEmpty: "当前记录还没有可用链接",
|
||||
copySuccess: "链接已复制",
|
||||
},
|
||||
},
|
||||
brands: {
|
||||
eyebrow: "Brand Library",
|
||||
title: "品牌词库",
|
||||
|
||||
Reference in New Issue
Block a user