fix: unify chinese language code as zh-CN
This commit is contained in:
@@ -3,5 +3,5 @@ import { tLang } from "../i18n";
|
||||
|
||||
/** Admin area always uses Chinese, independent of site language. */
|
||||
export function useAdminT() {
|
||||
return useCallback((key: string) => tLang("zh", key), []);
|
||||
return useCallback((key: string) => tLang("zh-CN", key), []);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export function MessageStream({ scope }: MessageStreamProps) {
|
||||
const { items, isLoading, error, hasMore, loadMore, reset } =
|
||||
usePostStream(params);
|
||||
const groups = useGroupedByDay(items, lang);
|
||||
const retryLabel = lang === "zh" ? "重试" : "Retry";
|
||||
const retryLabel = lang === "zh-CN" ? "重试" : "Retry";
|
||||
|
||||
const sentinelRef = useRef<HTMLDivElement>(null);
|
||||
const hasMoreRef = useRef(hasMore);
|
||||
|
||||
@@ -8,7 +8,7 @@ function makePost(id: string, isoDate: string): Post {
|
||||
id,
|
||||
categoryId: 1,
|
||||
categorySlug: "x",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [],
|
||||
isRecommended: false,
|
||||
publishedAt: isoDate,
|
||||
@@ -25,7 +25,7 @@ describe("useGroupedByDay", () => {
|
||||
makePost("c", "2026-02-28T01:00:00.000Z"),
|
||||
makePost("d", "2026-05-16T12:00:00.000Z"),
|
||||
];
|
||||
const { result } = renderHook(() => useGroupedByDay(posts, "zh"));
|
||||
const { result } = renderHook(() => useGroupedByDay(posts, "zh-CN"));
|
||||
expect(result.current.length).toBeGreaterThanOrEqual(2);
|
||||
const allIds = result.current.flatMap((g) => g.items.map((p) => p.id));
|
||||
expect(allIds).toEqual(["a", "b", "c", "d"]);
|
||||
@@ -47,7 +47,7 @@ describe("useGroupedByDay", () => {
|
||||
});
|
||||
|
||||
it("returns empty array for empty input", () => {
|
||||
const { result } = renderHook(() => useGroupedByDay([], "zh"));
|
||||
const { result } = renderHook(() => useGroupedByDay([], "zh-CN"));
|
||||
expect(result.current).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,10 +35,10 @@ function dayLabel(iso: string, lang: string): string {
|
||||
a.getMonth() === b.getMonth() &&
|
||||
a.getDate() === b.getDate();
|
||||
if (isSameDay(d, today)) {
|
||||
return lang === "zh" ? "今天" : "Today";
|
||||
return lang === "zh-CN" ? "今天" : "Today";
|
||||
}
|
||||
if (isSameDay(d, yesterday)) {
|
||||
return lang === "zh" ? "昨天" : "Yesterday";
|
||||
return lang === "zh-CN" ? "昨天" : "Yesterday";
|
||||
}
|
||||
return new Intl.DateTimeFormat(localeFor(lang), {
|
||||
month: "long",
|
||||
|
||||
30
src/i18n.tsx
30
src/i18n.tsx
@@ -6,7 +6,7 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
|
||||
export type Lang = "zh" | "en" | "ja" | "ko" | "vi" | "id" | "ms";
|
||||
export type Lang = "zh-CN" | "en" | "ja" | "ko" | "vi" | "id" | "ms";
|
||||
|
||||
type Dict = Record<string, string>;
|
||||
|
||||
@@ -82,7 +82,7 @@ const zhDict: Dict = {
|
||||
walletMissingProjectId:
|
||||
"请配置 VITE_WALLETCONNECT_PROJECT_ID(Reown Cloud),否则无法使用 WalletConnect/扫码。",
|
||||
walletSetupNeeded: "钱包扫码未启用(请在服务器配置环境变量)",
|
||||
lang_zh: "中文",
|
||||
lang_zh_CN: "中文",
|
||||
lang_en: "English",
|
||||
lang_ja: "日本語",
|
||||
lang_ko: "한국어",
|
||||
@@ -208,7 +208,7 @@ const enDict: Dict = {
|
||||
walletMissingProjectId:
|
||||
"Set VITE_WALLETCONNECT_PROJECT_ID (free on Reown Cloud). Required for WalletConnect / QR login.",
|
||||
walletSetupNeeded: "Wallet QR login disabled (set env on server)",
|
||||
lang_zh: "Chinese",
|
||||
lang_zh_CN: "Chinese",
|
||||
lang_en: "English",
|
||||
lang_ja: "Japanese",
|
||||
lang_ko: "Korean",
|
||||
@@ -262,8 +262,8 @@ const enDict: Dict = {
|
||||
};
|
||||
|
||||
const languageNames: Record<Lang, Dict> = {
|
||||
zh: {
|
||||
lang_zh: "中文",
|
||||
"zh-CN": {
|
||||
lang_zh_CN: "中文",
|
||||
lang_en: "English",
|
||||
lang_ja: "日本語",
|
||||
lang_ko: "한국어",
|
||||
@@ -272,7 +272,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
lang_ms: "Bahasa Melayu",
|
||||
},
|
||||
en: {
|
||||
lang_zh: "Chinese",
|
||||
lang_zh_CN: "Chinese",
|
||||
lang_en: "English",
|
||||
lang_ja: "Japanese",
|
||||
lang_ko: "Korean",
|
||||
@@ -281,7 +281,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
lang_ms: "Malay",
|
||||
},
|
||||
ja: {
|
||||
lang_zh: "中国語",
|
||||
lang_zh_CN: "中国語",
|
||||
lang_en: "英語",
|
||||
lang_ja: "日本語",
|
||||
lang_ko: "韓国語",
|
||||
@@ -290,7 +290,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
lang_ms: "マレー語",
|
||||
},
|
||||
ko: {
|
||||
lang_zh: "중국어",
|
||||
lang_zh_CN: "중국어",
|
||||
lang_en: "영어",
|
||||
lang_ja: "일본어",
|
||||
lang_ko: "한국어",
|
||||
@@ -299,7 +299,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
lang_ms: "말레이어",
|
||||
},
|
||||
vi: {
|
||||
lang_zh: "Tiếng Trung",
|
||||
lang_zh_CN: "Tiếng Trung",
|
||||
lang_en: "Tiếng Anh",
|
||||
lang_ja: "Tiếng Nhật",
|
||||
lang_ko: "Tiếng Hàn",
|
||||
@@ -308,7 +308,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
lang_ms: "Tiếng Mã Lai",
|
||||
},
|
||||
id: {
|
||||
lang_zh: "Bahasa Tionghoa",
|
||||
lang_zh_CN: "Bahasa Tionghoa",
|
||||
lang_en: "Bahasa Inggris",
|
||||
lang_ja: "Bahasa Jepang",
|
||||
lang_ko: "Bahasa Korea",
|
||||
@@ -317,7 +317,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
lang_ms: "Bahasa Melayu",
|
||||
},
|
||||
ms: {
|
||||
lang_zh: "Bahasa Cina",
|
||||
lang_zh_CN: "Bahasa Cina",
|
||||
lang_en: "Bahasa Inggeris",
|
||||
lang_ja: "Bahasa Jepun",
|
||||
lang_ko: "Bahasa Korea",
|
||||
@@ -328,7 +328,7 @@ const languageNames: Record<Lang, Dict> = {
|
||||
};
|
||||
|
||||
const dict: Record<Lang, Dict> = {
|
||||
zh: { ...zhDict, ...languageNames.zh },
|
||||
"zh-CN": { ...zhDict, ...languageNames["zh-CN"] },
|
||||
en: { ...enDict, ...languageNames.en },
|
||||
ja: { ...enDict, ...languageNames.ja },
|
||||
ko: { ...enDict, ...languageNames.ko },
|
||||
@@ -351,9 +351,9 @@ const LANG_KEY = "ark_lang";
|
||||
export function I18nProvider({ children }: { children: React.ReactNode }) {
|
||||
const [lang, setLangState] = useState<Lang>(() => {
|
||||
const s = localStorage.getItem(LANG_KEY);
|
||||
if (s === "zh-CN" || s === "zh-TW") return "zh";
|
||||
if (s === "zh" || s === "zh-TW") return "zh-CN";
|
||||
if (
|
||||
s === "zh" ||
|
||||
s === "zh-CN" ||
|
||||
s === "en" ||
|
||||
s === "ja" ||
|
||||
s === "ko" ||
|
||||
@@ -383,5 +383,5 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
export function langQuery(lang: Lang) {
|
||||
return lang === "zh" ? "zh-CN" : lang;
|
||||
return lang;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Lang } from "./i18n";
|
||||
|
||||
export const LANG_OPTIONS: { code: Lang; label: string }[] = [
|
||||
{ code: "zh", label: "中文" },
|
||||
{ code: "zh-CN", label: "中文" },
|
||||
{ code: "en", label: "English" },
|
||||
{ code: "ja", label: "日本語" },
|
||||
{ code: "ko", label: "한국어" },
|
||||
@@ -12,6 +12,7 @@ export const LANG_OPTIONS: { code: Lang; label: string }[] = [
|
||||
|
||||
export function languageLabel(t: (key: string) => string, code: string) {
|
||||
if (!code) return t("filterLanguageAll");
|
||||
const label = t(`lang_${code}`);
|
||||
return label === `lang_${code}` ? code : label;
|
||||
const key = `lang_${code.replace("-", "_")}`;
|
||||
const label = t(key);
|
||||
return label === key ? code : label;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-001",
|
||||
categoryId: 1,
|
||||
categorySlug: "project",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-001",
|
||||
@@ -55,7 +55,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-002",
|
||||
categoryId: 1,
|
||||
categorySlug: "project",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-002",
|
||||
@@ -79,7 +79,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-013",
|
||||
categoryId: 1,
|
||||
categorySlug: "project",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-013",
|
||||
@@ -100,7 +100,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-003",
|
||||
categoryId: 2,
|
||||
categorySlug: "guide",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-003",
|
||||
@@ -121,7 +121,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-004",
|
||||
categoryId: 2,
|
||||
categorySlug: "guide",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-004",
|
||||
@@ -142,7 +142,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-005",
|
||||
categoryId: 3,
|
||||
categorySlug: "data",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
text:
|
||||
"📊 ARK DeFAI 各大平台现已上线 🔥\n\n" +
|
||||
"🔷 市场数据平台\n" +
|
||||
@@ -163,7 +163,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-006",
|
||||
categoryId: 3,
|
||||
categorySlug: "data",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
text:
|
||||
"📌 收取协议固定 2.5% 手续费。\n\n" +
|
||||
"🔷 贡献值合约\n0x7736b5B84cADDB7661D250D10e60E31F3C905c99\n📌 用于新贡献值机制的 USDT 购买与资金流向管理(通缩销毁 / 储备 RBS)",
|
||||
@@ -178,7 +178,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-007",
|
||||
categoryId: 4,
|
||||
categorySlug: "videos",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
text: "ARK 山东·东营社区 招商复盘·势位重塑\n🔥 ARK DeFai 相位偏移锁死增值弧度。质能裂变诱发认知风暴,海岱动能正于中原合围!🚀",
|
||||
attachments: [
|
||||
{
|
||||
@@ -204,7 +204,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-008",
|
||||
categoryId: 5,
|
||||
categorySlug: "poster",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-008",
|
||||
@@ -228,7 +228,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-009",
|
||||
categoryId: 5,
|
||||
categorySlug: "poster",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-009",
|
||||
@@ -252,7 +252,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-010",
|
||||
categoryId: 6,
|
||||
categorySlug: "meeting",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
text: "📌 ARK DeFAI 方舟晨间时刻\n\n🧠 会议主题:市场概况交流 & 市场问题讨论。\n🕙 会议时间:3月1日(日)10:00\n🎬 直播腾讯会议链接:https://meeting.tencent.com/l/G718S4Sedm38",
|
||||
attachments: [
|
||||
{
|
||||
@@ -277,7 +277,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-011",
|
||||
categoryId: 5,
|
||||
categorySlug: "poster",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: [
|
||||
{
|
||||
id: "a-011a",
|
||||
@@ -323,7 +323,7 @@ export const MOCK_POSTS: Post[] = [
|
||||
id: "p-012",
|
||||
categoryId: 5,
|
||||
categorySlug: "poster",
|
||||
language: "zh",
|
||||
language: "zh-CN",
|
||||
attachments: Array.from({ length: 7 }).map((_, i) => ({
|
||||
id: `a-012-${i}`,
|
||||
kind: "image" as const,
|
||||
|
||||
@@ -37,7 +37,7 @@ export function AdminResourceForm() {
|
||||
const [title, setTitle] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
const [rtype, setRtype] = useState<string>("image");
|
||||
const [language, setLanguage] = useState("zh");
|
||||
const [language, setLanguage] = useState("zh-CN");
|
||||
const [categoryId, setCategoryId] = useState(1);
|
||||
const [coverImage, setCoverImage] = useState("");
|
||||
const [fileUrl, setFileUrl] = useState("");
|
||||
@@ -66,7 +66,7 @@ export function AdminResourceForm() {
|
||||
setTitle(r.title || "");
|
||||
setDescription(r.description || "");
|
||||
setRtype(r.type || "image");
|
||||
setLanguage(r.language || "zh");
|
||||
setLanguage(r.language || "zh-CN");
|
||||
setCategoryId(r.categoryId || 1);
|
||||
setCoverImage(r.coverImage || "");
|
||||
setFileUrl(r.fileUrl || "");
|
||||
@@ -183,7 +183,7 @@ export function AdminResourceForm() {
|
||||
value={language}
|
||||
onChange={(e) => setLanguage(e.target.value)}
|
||||
>
|
||||
<option value="zh">{t("lang_zh")}</option>
|
||||
<option value="zh-CN">{t("lang_zh_CN")}</option>
|
||||
<option value="en">{t("lang_en")}</option>
|
||||
<option value="ja">{t("lang_ja")}</option>
|
||||
<option value="ko">{t("lang_ko")}</option>
|
||||
|
||||
@@ -12,7 +12,7 @@ const t = (key: string) =>
|
||||
type_image: "图片",
|
||||
type_video: "视频",
|
||||
type_music: "音乐",
|
||||
lang_zh: "中文",
|
||||
lang_zh_CN: "中文",
|
||||
lang_en: "English",
|
||||
lang_ja: "日本語",
|
||||
})[key] ?? key;
|
||||
|
||||
@@ -34,8 +34,10 @@ export function resourceLanguageLabel(
|
||||
): string {
|
||||
const lc = langCode.trim().toLowerCase();
|
||||
const normalized =
|
||||
lc === "zh-cn" || lc === "zh-tw" || lc === "zh-hans" ? "zh" : lc;
|
||||
const key = `lang_${normalized}`;
|
||||
lc === "zh" || lc === "zh-cn" || lc === "zh-tw" || lc === "zh-hans"
|
||||
? "zh-CN"
|
||||
: lc;
|
||||
const key = `lang_${normalized.replace("-", "_")}`;
|
||||
const label = t(key);
|
||||
return label !== key ? label : langCode.trim();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user