feat(localasr): Windows 端千问3 ASR 改为灰显 disabled + 提示

This commit is contained in:
baiqing committed 2026-05-12 17:26:52 +08:00
1 parent ad6cd93b10
commit a981815b8b
6 files changed
+63 -26

No files matched your search

+1
View File
@@ -668,6 +668,7 @@ export const en: typeof zhCN = {
desc: 'Manage on-device ASR models. Windows can use Microsoft Foundry Local Whisper; Qwen3-ASR model management stays separate.',
qwenTitle: 'Qwen3-ASR model manager',
engineUnavailable: 'The Qwen3-ASR inference engine is not bundled on this platform. You can still download models, but Qwen3-ASR cannot be activated here yet.',
qwenUnavailableOnWindows: 'Qwen3-ASR is not supported on Windows yet. Please use Foundry Local Whisper above instead.',
foundryTitle: 'Windows Foundry Local Whisper',
foundryDesc: 'Windows uses Microsoft Foundry Local Whisper to recognize speech on this device with no ASR API key. First prepare downloads local runtime components and a model, then loads it. LLM polishing still uses your configured LLM provider; if none is configured, the existing raw transcript fallback still applies.',
foundryAvailable: 'Available on Windows',
+1
View File
@@ -670,6 +670,7 @@ export const ja: typeof zhCN = {
desc: '本機の ASR モデルを管理します。Windows では Microsoft Foundry Local Whisper を使用でき、Qwen3-ASR のモデル管理は独立しています。',
qwenTitle: 'Qwen3-ASR モデル管理',
engineUnavailable: '現在のプラットフォームには Qwen3-ASR 推論エンジンが同梱されていません。モデルのダウンロードは可能ですが、ここではまだ Qwen3-ASR を有効化できません。',
qwenUnavailableOnWindows: 'Windows では Qwen3-ASR にまだ対応していません。上記の Foundry Local Whisper をご利用ください。',
foundryTitle: 'Windows Foundry Local Whisper',
foundryDesc: 'Windows では Microsoft Foundry Local Whisper が本機上で音声を認識し、ASR API Key は不要です。初回準備ではローカル実行コンポーネントとモデルをダウンロードして読み込みます。LLM 整文は設定済みの LLM プロバイダーを引き続き使用し、未設定の場合は従来どおり生の転写結果にフォールバックします。',
foundryAvailable: 'Windows で利用可能',
+1
View File
@@ -670,6 +670,7 @@ export const ko: typeof zhCN = {
desc: '기기 내 ASR 모델을 관리합니다. Windows 에서는 Microsoft Foundry Local Whisper 를 사용할 수 있으며, Qwen3-ASR 모델 관리는 별도로 유지됩니다.',
qwenTitle: 'Qwen3-ASR 모델 관리',
engineUnavailable: '현재 플랫폼에는 Qwen3-ASR 추론 엔진이 포함되어 있지 않습니다. 모델은 다운로드할 수 있지만 여기서는 아직 Qwen3-ASR 을 활성화할 수 없습니다.',
qwenUnavailableOnWindows: 'Windows 에서는 아직 Qwen3-ASR 을 지원하지 않습니다. 위의 Foundry Local Whisper 를 사용해 주세요.',
foundryTitle: 'Windows Foundry Local Whisper',
foundryDesc: 'Windows 는 Microsoft Foundry Local Whisper 로 이 기기에서 음성을 인식하며 ASR API Key 가 필요 없습니다. 첫 준비 시 로컬 런타임 구성 요소와 모델을 다운로드한 뒤 로드합니다. LLM 정리는 계속 설정된 LLM 공급자를 사용하며, 설정되지 않은 경우 기존 원문 전사 폴백을 그대로 사용합니다.',
foundryAvailable: 'Windows 에서 사용 가능',
+1
View File
@@ -666,6 +666,7 @@ export const zhCN = {
desc: '管理本机 ASR 模型。Windows 可使用 Microsoft Foundry Local Whisper;Qwen3-ASR 模型管理保持独立。',
qwenTitle: 'Qwen3-ASR 模型管理',
engineUnavailable: '当前平台暂未集成 Qwen3-ASR 推理引擎。可下载模型,但暂时无法启用 Qwen3-ASR。',
qwenUnavailableOnWindows: 'Windows 暂不支持 Qwen3-ASR,请使用上方 Foundry Local Whisper。',
foundryTitle: 'Windows Foundry Local Whisper',
foundryDesc: 'Windows 使用 Microsoft Foundry Local Whisper 在本机识别语音,无需 ASR API Key。首次准备会在本机下载运行组件和模型并加载;LLM 润色仍使用你已配置的 LLM 提供商,未配置时沿用原始转写回退。',
foundryAvailable: 'Windows 可用',
+1
View File
@@ -668,6 +668,7 @@ export const zhTW: typeof zhCN = {
desc: '管理本機 ASR 模型。Windows 可使用 Microsoft Foundry Local Whisper;Qwen3-ASR 模型管理保持獨立。',
qwenTitle: 'Qwen3-ASR 模型管理',
engineUnavailable: '當前平臺暫未集成 Qwen3-ASR 推理引擎。可下載模型,但暫時無法啟用 Qwen3-ASR。',
qwenUnavailableOnWindows: 'Windows 暫不支援 Qwen3-ASR,請使用上方的 Foundry Local Whisper。',
foundryTitle: 'Windows Foundry Local Whisper',
foundryDesc: 'Windows 使用 Microsoft Foundry Local Whisper 在本機識別語音,無需 ASR API Key。首次準備會在本機下載運行組件和模型並加載;LLM 潤色仍使用你已配置的 LLM 提供商,未配置時沿用原始轉寫回退。',
foundryAvailable: 'Windows 可用',
+58 -26
View File
@@ -758,12 +758,26 @@ export function LocalAsr({ embedded = false }: LocalAsrProps = {}) {
</Card>
)}
{/* Qwen3 模型管理区——只在 macOS 渲染(后端 #[cfg(target_os = "macos")] 独占)。
Windows / Linux 看见镜像源 / 下载 / 模型列表都是 dead UI。Foundry 块自身已经
被上方 IS_WINDOWS 守卫,错误 Card(共享 setError,被 Foundry handler 也写)
保持无条件露出。 */}
{IS_MAC && (<>
{!engineAvailable && (
{/* Qwen3 模型管理区——macOS 是实体后端(#[cfg(target_os = "macos")]),Windows
上 backend 永远 unavailable,但 PO 要求 Windows 用户仍能看见这块,整体
灰显 + 禁用交互 + 顶部横幅说明不可用,引导他们使用上方 Foundry Local Whisper。
Linux 当前没有任何本地 ASR 提供,沿用 IS_MAC 隐藏(dead UI 仍然要藏)。 */}
{(IS_MAC || IS_WINDOWS) && (<>
{IS_WINDOWS && (
<Card style={{ marginBottom: 16, background: 'rgba(255, 235, 200, 0.4)' }}>
<div role="alert" style={{ fontSize: 13, color: 'var(--ol-ink-2)' }}>
{t('localAsr.qwenUnavailableOnWindows')}
</div>
</Card>
)}
<div
aria-disabled={IS_WINDOWS || undefined}
style={
IS_WINDOWS
? { opacity: 0.5, filter: 'grayscale(0.4)', pointerEvents: 'none' as const }
: undefined
}>
{IS_MAC && !engineAvailable && (
<Card style={{ marginBottom: 16, background: 'rgba(255, 235, 200, 0.4)' }}>
<div style={{ fontSize: 13, color: 'var(--ol-ink-2)' }}>
{t('localAsr.engineUnavailable')}
@@ -851,6 +865,7 @@ export function LocalAsr({ embedded = false }: LocalAsrProps = {}) {
</div>
</Card>
)}
</div>
</>)}
{error && (
@@ -859,26 +874,43 @@ export function LocalAsr({ embedded = false }: LocalAsrProps = {}) {
</Card>
)}
{IS_MAC && (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
{models.map(model => (
<ModelRow
key={model.id}
model={model}
remoteSize={remoteSizes[model.id]}
progress={progress[model.id]}
isActive={settings?.activeModel === model.id}
engineAvailable={engineAvailable}
disabled={busyModelId !== null && busyModelId !== model.id}
testing={testingModelId === model.id}
testResult={testResults[model.id]}
onDownload={() => void handleDownload(model.id)}
onCancel={() => void handleCancel(model.id)}
onDelete={() => void handleDelete(model.id)}
onSetActive={() => void handleSetActiveModel(model.id)}
onTest={() => void handleTest(model.id)}
/>
))}
{(IS_MAC || IS_WINDOWS) && (
<div
aria-disabled={IS_WINDOWS || undefined}
style={
IS_WINDOWS
? { opacity: 0.5, filter: 'grayscale(0.4)', pointerEvents: 'none' as const }
: undefined
}>
{IS_MAC ? (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
{models.map(model => (
<ModelRow
key={model.id}
model={model}
remoteSize={remoteSizes[model.id]}
progress={progress[model.id]}
isActive={settings?.activeModel === model.id}
engineAvailable={engineAvailable}
disabled={busyModelId !== null && busyModelId !== model.id}
testing={testingModelId === model.id}
testResult={testResults[model.id]}
onDownload={() => void handleDownload(model.id)}
onCancel={() => void handleCancel(model.id)}
onDelete={() => void handleDelete(model.id)}
onSetActive={() => void handleSetActiveModel(model.id)}
onTest={() => void handleTest(model.id)}
/>
))}
</div>
) : (
/* Windows 灰显占位:后端列表为空,给一个静态 Card 表明这里"本该是模型列表"。 */
<Card>
<div style={{ fontSize: 13, color: 'var(--ol-ink-3)' }}>
{t('localAsr.qwenUnavailableOnWindows')}
</div>
</Card>
)}
</div>
)}
</Wrapper>