diff --git a/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js b/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js index b3a957a6..71e6012a 100644 --- a/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js +++ b/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js @@ -4,6 +4,10 @@ import { useState, useEffect, useRef, useCallback } from "react"; import PropTypes from "prop-types"; import { Card, Button, Input, Modal, CardSkeleton, Toggle, ConfirmModal } from "@/shared/components"; import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard"; +import { getCurrentLocale, onLocaleChange } from "@/i18n/runtime"; + +// Locales that unlock wenyan (classical Chinese) caveman levels +const WENYAN_LOCALES = ["zh-CN", "zh-TW"]; const TUNNEL_BENEFITS = [ { icon: "public", title: "Access Anywhere", desc: "Use your API from any network" }, @@ -53,9 +57,9 @@ const CAVEMAN_LEVELS = [ { id: "lite", label: "Lite", desc: "Drop filler, keep grammar" }, { id: "full", label: "Full", desc: "Drop articles, fragments OK" }, { id: "ultra", label: "Ultra", desc: "Telegraphic, max compression" }, - { id: "wenyan-lite", label: "Zip Lite", desc: "Compact classical style, light compression" }, - { id: "wenyan", label: "Zip Full", desc: "Classical Chinese, 80-90% token reduction" }, - { id: "wenyan-ultra", label: "Zip Max", desc: "Extreme classical compression" }, + { id: "wenyan-lite", label: "文 Lite", desc: "Classical Chinese, light compression", wenyan: true }, + { id: "wenyan", label: "文 Full", desc: "Maximum 文言文, 80-90% reduction", wenyan: true }, + { id: "wenyan-ultra", label: "文 Ultra", desc: "Extreme classical compression", wenyan: true }, ]; export default function APIPageClient({ machineId }) { const [keys, setKeys] = useState([]); @@ -72,6 +76,7 @@ export default function APIPageClient({ machineId }) { const [rtkEnabled, setRtkEnabledState] = useState(true); const [cavemanEnabled, setCavemanEnabled] = useState(false); const [cavemanLevel, setCavemanLevel] = useState("full"); + const [locale, setLocale] = useState("en"); // Cloudflare Tunnel state const [tunnelChecking, setTunnelChecking] = useState(true); @@ -127,6 +132,26 @@ export default function APIPageClient({ machineId }) { setIsRemoteHost(!["localhost", "127.0.0.1", "::1"].includes(window.location.hostname)); }, []); + // Track app UI locale to gate wenyan caveman levels + useEffect(() => { + setLocale(getCurrentLocale()); + return onLocaleChange(() => setLocale(getCurrentLocale())); + }, []); + + const isWenyanLocale = WENYAN_LOCALES.includes(locale); + const visibleCavemanLevels = isWenyanLocale + ? CAVEMAN_LEVELS + : CAVEMAN_LEVELS.filter((lvl) => !lvl.wenyan); + + // Reset wenyan level to "ultra" when leaving a Chinese locale + useEffect(() => { + const current = CAVEMAN_LEVELS.find((lvl) => lvl.id === cavemanLevel); + if (current?.wenyan && !isWenyanLocale) { + setCavemanLevel("ultra"); + patchSetting({ cavemanLevel: "ultra" }); + } + }, [isWenyanLocale, cavemanLevel]); + const { copied, copy } = useCopyToClipboard(); // Security gate: block remote exposure while dashboard uses default password or login is off. @@ -1080,7 +1105,7 @@ export default function APIPageClient({ machineId }) { {cavemanEnabled && (