fix: improve mode toggle robustness and add i18n support
- Make mode detection more robust (handle ::1, 0.0.0.0) - Add getProxyPort() to parse port from ANTHROPIC_BASE_URL dynamically - Add i18n translation keys for mode toggle in all 5 languages - Update settings.html to use translation keys and dynamic port Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,20 @@ window.Components.claudeConfig = () => ({
|
|||||||
currentMode: 'proxy', // 'proxy' or 'paid'
|
currentMode: 'proxy', // 'proxy' or 'paid'
|
||||||
modeLoading: false,
|
modeLoading: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract port from ANTHROPIC_BASE_URL for display
|
||||||
|
* @returns {string} Port number or '8080' as fallback
|
||||||
|
*/
|
||||||
|
getProxyPort() {
|
||||||
|
const baseUrl = this.config?.env?.ANTHROPIC_BASE_URL || '';
|
||||||
|
try {
|
||||||
|
const url = new URL(baseUrl);
|
||||||
|
return url.port || '8080';
|
||||||
|
} catch {
|
||||||
|
return '8080';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Presets state
|
// Presets state
|
||||||
presets: [],
|
presets: [],
|
||||||
selectedPresetName: '',
|
selectedPresetName: '',
|
||||||
|
|||||||
@@ -364,4 +364,14 @@ window.translations.en = {
|
|||||||
mustBeAtMost: "{fieldName} must be at most {max}",
|
mustBeAtMost: "{fieldName} must be at most {max}",
|
||||||
cannotBeEmpty: "{fieldName} cannot be empty",
|
cannotBeEmpty: "{fieldName} cannot be empty",
|
||||||
mustBeTrueOrFalse: "Value must be true or false",
|
mustBeTrueOrFalse: "Value must be true or false",
|
||||||
|
// Mode Toggle (Proxy/Paid)
|
||||||
|
connectionMode: "Connection Mode",
|
||||||
|
proxyMode: "Proxy Mode",
|
||||||
|
paidMode: "Paid Mode",
|
||||||
|
usingLocalProxy: "Using local proxy server (localhost:{port})",
|
||||||
|
usingOfficialApi: "Using official Anthropic API (requires subscription)",
|
||||||
|
paidModeTitle: "Claude CLI is using the official Anthropic API",
|
||||||
|
paidModeDesc: "All proxy configuration has been removed. Claude CLI uses your Anthropic subscription directly.",
|
||||||
|
paidModeHint: "Switch to Proxy mode to configure model routing and presets.",
|
||||||
|
modeToggleFailed: "Failed to switch mode",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -409,4 +409,14 @@ window.translations.id = {
|
|||||||
strategyUpdated: "Strategi diubah ke: {strategy}",
|
strategyUpdated: "Strategi diubah ke: {strategy}",
|
||||||
failedToUpdateStrategy: "Gagal memperbarui strategi",
|
failedToUpdateStrategy: "Gagal memperbarui strategi",
|
||||||
invalidStrategy: "Strategi tidak valid dipilih",
|
invalidStrategy: "Strategi tidak valid dipilih",
|
||||||
|
// Mode Toggle (Proxy/Paid)
|
||||||
|
connectionMode: "Mode Koneksi",
|
||||||
|
proxyMode: "Mode Proxy",
|
||||||
|
paidMode: "Mode Berbayar",
|
||||||
|
usingLocalProxy: "Menggunakan server proxy lokal (localhost:{port})",
|
||||||
|
usingOfficialApi: "Menggunakan API resmi Anthropic (memerlukan langganan)",
|
||||||
|
paidModeTitle: "Claude CLI menggunakan API resmi Anthropic",
|
||||||
|
paidModeDesc: "Semua konfigurasi proxy telah dihapus. Claude CLI menggunakan langganan Anthropic Anda secara langsung.",
|
||||||
|
paidModeHint: "Beralih ke mode Proxy untuk mengonfigurasi routing model dan preset.",
|
||||||
|
modeToggleFailed: "Gagal beralih mode",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -305,4 +305,14 @@ window.translations.pt = {
|
|||||||
strategyUpdated: "Estratégia atualizada para: {strategy}",
|
strategyUpdated: "Estratégia atualizada para: {strategy}",
|
||||||
failedToUpdateStrategy: "Falha ao atualizar estratégia",
|
failedToUpdateStrategy: "Falha ao atualizar estratégia",
|
||||||
invalidStrategy: "Estratégia inválida selecionada",
|
invalidStrategy: "Estratégia inválida selecionada",
|
||||||
|
// Mode Toggle (Proxy/Paid)
|
||||||
|
connectionMode: "Modo de Conexão",
|
||||||
|
proxyMode: "Modo Proxy",
|
||||||
|
paidMode: "Modo Pago",
|
||||||
|
usingLocalProxy: "Usando servidor proxy local (localhost:{port})",
|
||||||
|
usingOfficialApi: "Usando API oficial da Anthropic (requer assinatura)",
|
||||||
|
paidModeTitle: "Claude CLI está usando a API oficial da Anthropic",
|
||||||
|
paidModeDesc: "Toda configuração de proxy foi removida. Claude CLI usa sua assinatura Anthropic diretamente.",
|
||||||
|
paidModeHint: "Mude para modo Proxy para configurar roteamento de modelos e presets.",
|
||||||
|
modeToggleFailed: "Falha ao alternar modo",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -355,4 +355,14 @@ window.translations.tr = {
|
|||||||
strategyUpdated: "Strateji şu şekilde güncellendi: {strategy}",
|
strategyUpdated: "Strateji şu şekilde güncellendi: {strategy}",
|
||||||
failedToUpdateStrategy: "Strateji güncellenemedi",
|
failedToUpdateStrategy: "Strateji güncellenemedi",
|
||||||
invalidStrategy: "Geçersiz strateji seçildi",
|
invalidStrategy: "Geçersiz strateji seçildi",
|
||||||
|
// Mode Toggle (Proxy/Paid)
|
||||||
|
connectionMode: "Bağlantı Modu",
|
||||||
|
proxyMode: "Proxy Modu",
|
||||||
|
paidMode: "Ücretli Mod",
|
||||||
|
usingLocalProxy: "Yerel proxy sunucusu kullanılıyor (localhost:{port})",
|
||||||
|
usingOfficialApi: "Resmi Anthropic API kullanılıyor (abonelik gerektirir)",
|
||||||
|
paidModeTitle: "Claude CLI resmi Anthropic API kullanıyor",
|
||||||
|
paidModeDesc: "Tüm proxy yapılandırması kaldırıldı. Claude CLI doğrudan Anthropic aboneliğinizi kullanır.",
|
||||||
|
paidModeHint: "Model yönlendirme ve ön ayarları yapılandırmak için Proxy moduna geçin.",
|
||||||
|
modeToggleFailed: "Mod değiştirilemedi",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -370,4 +370,14 @@ window.translations.zh = {
|
|||||||
strategyUpdated: "策略已更新为: {strategy}",
|
strategyUpdated: "策略已更新为: {strategy}",
|
||||||
failedToUpdateStrategy: "更新策略失败",
|
failedToUpdateStrategy: "更新策略失败",
|
||||||
invalidStrategy: "选择了无效的策略",
|
invalidStrategy: "选择了无效的策略",
|
||||||
|
// Mode Toggle (Proxy/Paid)
|
||||||
|
connectionMode: "连接模式",
|
||||||
|
proxyMode: "代理模式",
|
||||||
|
paidMode: "付费模式",
|
||||||
|
usingLocalProxy: "使用本地代理服务器 (localhost:{port})",
|
||||||
|
usingOfficialApi: "使用官方 Anthropic API (需要订阅)",
|
||||||
|
paidModeTitle: "Claude CLI 正在使用官方 Anthropic API",
|
||||||
|
paidModeDesc: "所有代理配置已移除。Claude CLI 直接使用您的 Anthropic 订阅。",
|
||||||
|
paidModeHint: "切换到代理模式以配置模型路由和预设。",
|
||||||
|
modeToggleFailed: "切换模式失败",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -199,35 +199,36 @@
|
|||||||
|
|
||||||
<!-- Mode Toggle (Proxy/Paid) -->
|
<!-- Mode Toggle (Proxy/Paid) -->
|
||||||
<div class="card bg-space-900/30 border border-space-border/50 p-5">
|
<div class="card bg-space-900/30 border border-space-border/50 p-5">
|
||||||
<label class="label text-xs uppercase text-gray-500 font-semibold mb-3">Connection Mode</label>
|
<label class="label text-xs uppercase text-gray-500 font-semibold mb-3"
|
||||||
|
x-text="$store.global.t('connectionMode')">Connection Mode</label>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-sm font-semibold"
|
<span class="text-sm font-semibold"
|
||||||
:class="currentMode === 'proxy' ? 'text-neon-purple' : 'text-neon-green'">
|
:class="currentMode === 'proxy' ? 'text-neon-purple' : 'text-neon-green'">
|
||||||
<template x-if="currentMode === 'proxy'"><span>🔌 Proxy Mode</span></template>
|
<template x-if="currentMode === 'proxy'"><span>🔌 <span x-text="$store.global.t('proxyMode')">Proxy Mode</span></span></template>
|
||||||
<template x-if="currentMode === 'paid'"><span>💳 Paid Mode</span></template>
|
<template x-if="currentMode === 'paid'"><span>💳 <span x-text="$store.global.t('paidMode')">Paid Mode</span></span></template>
|
||||||
</span>
|
</span>
|
||||||
<span x-show="modeLoading"
|
<span x-show="modeLoading"
|
||||||
class="loading loading-spinner loading-xs text-gray-400"></span>
|
class="loading loading-spinner loading-xs text-gray-400"></span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-[11px] text-gray-500">
|
<span class="text-[11px] text-gray-500">
|
||||||
<template x-if="currentMode === 'proxy'"><span>Using local proxy server
|
<template x-if="currentMode === 'proxy'"><span x-text="$store.global.t('usingLocalProxy', {port: getProxyPort()})">Using local proxy server</span></template>
|
||||||
(localhost:8080)</span></template>
|
<template x-if="currentMode === 'paid'"><span x-text="$store.global.t('usingOfficialApi')">Using official Anthropic API (requires subscription)</span></template>
|
||||||
<template x-if="currentMode === 'paid'"><span>Using official Anthropic API (requires
|
|
||||||
subscription)</span></template>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<span class="text-xs font-medium"
|
<span class="text-xs font-medium"
|
||||||
:class="currentMode === 'proxy' ? 'text-neon-purple' : 'text-gray-500'">Proxy</span>
|
:class="currentMode === 'proxy' ? 'text-neon-purple' : 'text-gray-500'"
|
||||||
|
x-text="$store.global.t('proxyMode').split(' ')[0]">Proxy</span>
|
||||||
<input type="checkbox" class="toggle toggle-sm"
|
<input type="checkbox" class="toggle toggle-sm"
|
||||||
:class="currentMode === 'paid' ? 'toggle-success' : 'toggle-secondary'"
|
:class="currentMode === 'paid' ? 'toggle-success' : 'toggle-secondary'"
|
||||||
:checked="currentMode === 'paid'" :disabled="modeLoading"
|
:checked="currentMode === 'paid'" :disabled="modeLoading"
|
||||||
@change="toggleMode($event.target.checked ? 'paid' : 'proxy')"
|
@change="toggleMode($event.target.checked ? 'paid' : 'proxy')"
|
||||||
aria-label="Toggle between Proxy and Paid mode">
|
aria-label="Toggle between Proxy and Paid mode">
|
||||||
<span class="text-xs font-medium"
|
<span class="text-xs font-medium"
|
||||||
:class="currentMode === 'paid' ? 'text-neon-green' : 'text-gray-500'">Paid</span>
|
:class="currentMode === 'paid' ? 'text-neon-green' : 'text-gray-500'"
|
||||||
|
x-text="$store.global.t('paidMode').split(' ')[0]">Paid</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -241,12 +242,9 @@
|
|||||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm font-semibold text-neon-green">Claude CLI is using the official Anthropic
|
<p class="text-sm font-semibold text-neon-green" x-text="$store.global.t('paidModeTitle')">Claude CLI is using the official Anthropic API</p>
|
||||||
API</p>
|
<p class="text-[11px] text-gray-400 mt-1" x-text="$store.global.t('paidModeDesc')">All proxy configuration has been removed. Claude CLI uses your Anthropic subscription directly.</p>
|
||||||
<p class="text-[11px] text-gray-400 mt-1">All proxy configuration has been removed. Claude
|
<p class="text-[10px] text-gray-500 mt-2" x-text="$store.global.t('paidModeHint')">Switch to Proxy mode to configure model routing and presets.</p>
|
||||||
CLI uses your Anthropic subscription directly.</p>
|
|
||||||
<p class="text-[10px] text-gray-500 mt-2">Switch to Proxy mode to configure model routing
|
|
||||||
and presets.</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -628,7 +628,12 @@ export function mountWebUI(app, dirname, accountManager) {
|
|||||||
const baseUrl = claudeConfig.env?.ANTHROPIC_BASE_URL || '';
|
const baseUrl = claudeConfig.env?.ANTHROPIC_BASE_URL || '';
|
||||||
|
|
||||||
// Determine mode based on ANTHROPIC_BASE_URL
|
// Determine mode based on ANTHROPIC_BASE_URL
|
||||||
const isProxy = baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1');
|
const isProxy = baseUrl && (
|
||||||
|
baseUrl.includes('localhost') ||
|
||||||
|
baseUrl.includes('127.0.0.1') ||
|
||||||
|
baseUrl.includes('::1') ||
|
||||||
|
baseUrl.includes('0.0.0.0')
|
||||||
|
);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
status: 'ok',
|
status: 'ok',
|
||||||
|
|||||||
Reference in New Issue
Block a user