diff --git a/frontend/src/components/sora/SoraGeneratePage.vue b/frontend/src/components/sora/SoraGeneratePage.vue new file mode 100644 index 0000000000..1f77edc401 --- /dev/null +++ b/frontend/src/components/sora/SoraGeneratePage.vue @@ -0,0 +1,430 @@ + + + + + + {{ t('sora.welcomeTitle') }} + {{ t('sora.welcomeSubtitle') }} + + + + + + {{ example }} + + + + + + + + + + + ⚠️ + {{ t('sora.noStorageToastMessage') }} + + + + + + + + + + + diff --git a/frontend/src/components/sora/SoraMediaPreview.vue b/frontend/src/components/sora/SoraMediaPreview.vue new file mode 100644 index 0000000000..09a3aea143 --- /dev/null +++ b/frontend/src/components/sora/SoraMediaPreview.vue @@ -0,0 +1,282 @@ + + + + + + + + + + + + {{ t('sora.previewTitle') }} + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/components/sora/SoraProgressCard.vue b/frontend/src/components/sora/SoraProgressCard.vue new file mode 100644 index 0000000000..69b28ef994 --- /dev/null +++ b/frontend/src/components/sora/SoraProgressCard.vue @@ -0,0 +1,609 @@ + + + + + + + {{ statusText }} + + + {{ generation.model }} + + ✕ {{ t('sora.cancel') }} + + + + + + + {{ generation.prompt }} + + + + + ⛔ {{ t('sora.errorCategory') }} + + + {{ generation.error_message }} + + + + + + + + + {{ progressInfoText }} + {{ progressInfoRight }} + + + + + + + + + + + + 🎨 + + + + + + + + + ✓ {{ t('sora.savedToCloud') }} + + + + ☁️ {{ t('sora.save') }} + + + + 📥 {{ t('sora.downloadLocal') }} + + + + ⏱ {{ t('sora.upstreamCountdown', { time: countdownText }) }} {{ t('sora.canDownload') }} + + + {{ t('sora.upstreamExpired') }} + + + + + + + 🔄 {{ generation.status === 'cancelled' ? t('sora.regenrate') : t('sora.retry') }} + + + 🗑 {{ t('sora.delete') }} + + + + + + + + + + + + + + + + diff --git a/frontend/src/components/sora/SoraPromptBar.vue b/frontend/src/components/sora/SoraPromptBar.vue new file mode 100644 index 0000000000..f5f1bfc9d2 --- /dev/null +++ b/frontend/src/components/sora/SoraPromptBar.vue @@ -0,0 +1,738 @@ + + + + + + + + + + {{ f.name }} + + + {{ f.name }} + + + ▼ + + + + + {{ t('sora.selectCredential') }} + + + {{ k.name }}{{ k.group ? ' · ' + k.group.name : '' }} + + + + + {{ s.group?.name || t('sora.subscription') }} + + + + ▼ + + + + ⚠ {{ t('sora.noCredentialHint') }} + + + + ⚠ {{ t('sora.noStorageConfigured') }} + + + + + + + + ✕ + + {{ t('sora.referenceImage') }} + + + + + + + + + + + + + + {{ a.icon }} {{ a.label }} + + + + + + + + + {{ d }}s + + + + + + + + + {{ count }} + + + + + + + + 📎 + + + + + + + + {{ t('sora.generatingCount', { current: activeTaskCount, max: maxConcurrentTasks }) }} + + + + + ✨ + {{ generating ? t('sora.generating') : t('sora.generate') }} + + + + + + + {{ imageError }} + + + + + + diff --git a/frontend/src/components/sora/SoraQuotaBar.vue b/frontend/src/components/sora/SoraQuotaBar.vue new file mode 100644 index 0000000000..4a3af0279b --- /dev/null +++ b/frontend/src/components/sora/SoraQuotaBar.vue @@ -0,0 +1,87 @@ + + + + + + + {{ formatBytes(quota.used_bytes) }} / {{ quota.quota_bytes === 0 ? '∞' : formatBytes(quota.quota_bytes) }} + + + + + + + diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index cfd20bb8c1..d4d5b0b063 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -2414,10 +2414,6 @@ export default { hint: 'Forward requests to a custom relay service. Proxy URL will be passed as a query parameter.', urlHint: 'Relay service URL (e.g., https://relay.example.com)', }, - clientAffinity: { - label: 'Client Affinity Scheduling', - hint: 'When enabled, new sessions prefer accounts previously used by this client to reduce account switching' - } }, expired: 'Expired', proxy: 'Proxy', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index c518aa0251..d4e4e630be 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -2566,10 +2566,6 @@ export default { hint: '启用后将请求转发到自定义中继服务,代理地址将作为 URL 参数传递给中继服务', urlHint: '中继服务地址(如 https://relay.example.com)', }, - clientAffinity: { - label: '客户端亲和调度', - hint: '启用后,新会话会优先调度到该客户端之前使用过的账号,避免频繁切换账号' - } }, expired: '已过期', proxy: '代理',
{{ t('sora.welcomeSubtitle') }}
{{ imageError }}