diff --git a/astro.config.mjs b/astro.config.mjs index 71b125f..e82d97b 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -6,7 +6,7 @@ import AstroPWA from '@vite-pwa/astro'; export default defineConfig({ i18n: { defaultLocale: 'en', - locales: ['en', 'zh'], + locales: ['en', 'zh-CN', 'zh-TW', 'ja'], routing: { prefixDefaultLocale: false, }, diff --git a/src/components/LanguageSwitcher.astro b/src/components/LanguageSwitcher.astro index fa1ebec..26a6379 100644 --- a/src/components/LanguageSwitcher.astro +++ b/src/components/LanguageSwitcher.astro @@ -1,27 +1,23 @@ --- import { getSupportedLangs, getTranslator } from '@/i18n/utils'; -import i18n from '@/i18n'; import { IoChevronDown } from 'react-icons/io5'; const { url } = Astro; -// 使用 fallbackLng 作为回退值 -const currentLocale = - Astro.currentLocale || - (Array.isArray(i18n.options.fallbackLng) - ? i18n.options.fallbackLng[0] - : i18n.options.fallbackLng) || - 'en'; +const defaultLocaleCode = 'en'; // 明确默认语言代码 + +const currentLocale = Astro.currentLocale || defaultLocaleCode; const t = await getTranslator(currentLocale); -const supportedLangs = getSupportedLangs(); -const defaultLocaleCode = 'en'; +const supportedLangs = getSupportedLangs(); // 如 ['en', 'zh-CN-CN', 'zh-CN-TW', 'ja'] let basePath = url.pathname; -const prefix = `/${currentLocale}`; +const currentLangPrefix = `/${currentLocale}`; -// 只有当当前语言不是硬编码的默认语言时,才需要尝试移除前缀 -if (currentLocale !== defaultLocaleCode && basePath.startsWith(prefix)) { - basePath = basePath.substring(prefix.length) || '/'; +if ( + currentLocale !== defaultLocaleCode && + basePath.startsWith(currentLangPrefix) +) { + basePath = basePath.substring(currentLangPrefix.length) || '/'; // 获取前缀后的部分,空则为根 } if (basePath !== '/' && !basePath.startsWith('/')) { basePath = '/' + basePath; @@ -45,8 +41,9 @@ const currentLangName = const isDefaultLang = langCode === defaultLocaleCode; let targetPath = isDefaultLang ? basePath : `/${langCode}${basePath}`; targetPath = targetPath.replace('//', '/'); - if (targetPath === '' && isDefaultLang) targetPath = '/'; - if (targetPath === '' && !isDefaultLang) targetPath = `/${langCode}`; + if (isDefaultLang && targetPath === '') targetPath = '/'; + if (!isDefaultLang && targetPath === `/${langCode}/`) + targetPath = `/${langCode}`; return (
  • @@ -124,6 +121,8 @@ const currentLangName = .language-list { position: absolute; top: calc(100% + 4px); + + /* 根据需要调整 left/right */ right: 0; left: auto; z-index: 60; diff --git a/src/i18n.ts b/src/i18n.ts index 5b76db5..041274b 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -2,22 +2,28 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import enTranslation from './locales/en/translation.json'; -import zhTranslation from './locales/zh/translation.json'; +import zh_CN_Translation from './locales/zh-CN/translation.json'; +import zh_TW_Translation from './locales/zh-TW/translation.json'; +import jaTranslation from './locales/ja/translation.json'; const resources = { en: { translation: enTranslation, }, - zh: { - translation: zhTranslation, + ja: { + translation: jaTranslation, + }, + 'zh-CN': { + translation: zh_CN_Translation, + }, + 'zh-TW': { + translation: zh_TW_Translation, }, }; i18n.use(initReactI18next).init({ - debug: true, fallbackLng: 'en', interpolation: { escapeValue: false }, - lng: 'en', missingKeyHandler: (lngs, ns, key, fallbackValue, updateMissing, options) => { const resolvedLng = lngs && lngs.length > 0 ? lngs[0] : i18n.language; const value = i18n.getResource(resolvedLng, ns || 'translation', key); diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts index 76a68b1..d58821d 100644 --- a/src/i18n/utils.ts +++ b/src/i18n/utils.ts @@ -1,18 +1,10 @@ import i18n from '@/i18n'; import type { TFunction } from 'i18next'; -/** - * 获取指定语言的翻译函数 (t function)。 - * 这个函数是异步的,以防 i18next 需要异步加载资源或切换语言。 - * @param lng - 语言代码 (例如 'en', 'zh')。如果未提供,则使用当前或回退语言。 - * @returns Promise - 返回一个解析为翻译函数的 Promise。 - */ export async function getTranslator(lng?: string): Promise { const targetLng = lng || i18n.language || (i18n.options.fallbackLng as string[])[0]; - // 如果 i18n 实例的当前语言与目标语言不一致,则切换语言 - // 注意:changeLanguage 是异步的 if (i18n.language !== targetLng) { await i18n.changeLanguage(targetLng); } @@ -20,10 +12,6 @@ export async function getTranslator(lng?: string): Promise { return i18n.t; } -/** - * 获取当前支持的语言列表 - * @returns string[] - */ export function getSupportedLangs(): string[] { return Object.keys(i18n.options.resources || {}); } diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 14f45bb..95633e3 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -6,7 +6,9 @@ }, "languages": { "en": "English", - "zh": "简体中文" + "zh-CN": "简体中文", + "zh-TW": "繁體中文", + "ja": "日本語" }, "common": { "save": "Save", diff --git a/src/locales/ja/translation.json b/src/locales/ja/translation.json new file mode 100644 index 0000000..2f51ded --- /dev/null +++ b/src/locales/ja/translation.json @@ -0,0 +1,360 @@ +{ + "site": { + "title": "Moodist:集中とリラックスのための環境サウンド", + "description": "Moodistは、厳選された{{count}}種類のサウンドを備えた、無料のオープンソース環境サウンドジェネレーターです。この多機能ツールで、リラックス、集中、または創造性のための理想的な雰囲気を作りましょう。", + "ogSiteName": "Moodist" + }, + "languages": { + "en": "English", + "zh-CN": "简体中文", + "zh-TW": "繁體中文", + "ja": "日本語" + }, + "common": { + "save": "保存", + "untitled": "無題", + "copy": "コピー", + "copied": "コピーしました!", + "override": "上書き", + "done": "完了!", + "reset": "リセット", + "play": "再生", + "close": "閉じる", + "reload": "再読み込み", + "start": "開始", + "pause": "一時停止", + "stop": "停止", + "back": "戻る", + "restart": "再開", + "cancel": "キャンセル", + "delete": "削除", + "plural-suffix": "" + }, + "hero": { + "logo-alt": "Moodist ロゴ", + "title-line1": "Moodist", + "title-line2": "集中とリラックスのための環境音", + "desc-prefix": "無料、そして", + "desc-open-source": "オープンソース", + "sounds-count": "{{count}} 種類のサウンド" + }, + "about": { + "section1": { + "title": "無料の環境サウンド", + "body": "日々の喧騒から逃れて、心を落ち着かせたいですか?集中力を高めたり、安らかな眠りに誘う完璧なサウンドスケープが必要ですか?Moodistは、あなたのための無料オープンソース環境サウンドジェネレーターです!サブスクリプションや登録は不要。Moodistで、心地よく没入感のあるオーディオ体験の世界を完全に無料で解き放ちましょう。" + }, + "section2": { + "title": "厳選されたサウンド", + "body": "厳選された{{count}}種類のサウンドの広範なライブラリに飛び込みましょう。自然愛好家は、小川の穏やかなせせらぎ、リズミカルな波の音、またはキャンプファイヤーのパチパチと燃える暖かさの中に安らぎを見つけるでしょう。カフェの柔らかなざわめき、電車の規則的なガタンゴトンという音、または交通の静かなホワイトノイズで、街の風景が生き生きと蘇ります。より深い集中やリラクゼーションを求める方のために、Moodistはあなたの心の状態を高めるように設計されたバイノーラルビートとカラーノイズを提供します。" + }, + "section3": { + "title": "あなたのサウンドスケープを作成", + "body": "Moodistの魅力は、そのシンプルさとカスタマイズ性にあります。複雑なメニューや紛らわしいオプションはありません。希望のサウンドを選択し、音量バランスを調整して再生ボタンを押すだけです。鳥の優しいさえずりと心地よい雨音をブレンドしたいですか?問題ありません!好きなだけサウンドを重ねて、あなただけのサウンドスケープ・オアシスを作りましょう。" + }, + "section4": { + "title": "あらゆる瞬間のためのサウンド", + "body": "長い一日の後にリラックスしたいとき、仕事中に集中力を高めたいとき、または安らかな眠りに就きたいとき、Moodistはあなたにぴったりのサウンドスケープを用意しています。そして何よりも素晴らしいのは、完全に無料でオープンソースであるため、何の制約もなくその利点を享受できることです。今日からMoodistを使い始めて、あなたの新しい静寂と集中の聖域を発見してください!" + } + }, + "donate": { + "prompt": "Moodistをお楽しみですか?", + "link-text": "寄付でサポートをお願いします!", + "section-title": "プロジェクトを支援", + "section-desc": "Moodistを広告なしで無料に保つためにご協力ください。", + "section-button": "コーヒー代を寄付する" + }, + "source": { + "title": "オープンソース", + "desc": "Moodistは無料でオープンソースです!" + }, + "toolbar": { + "menu-aria-label": "メニュー", + "global-volume-label": "全体の音量", + "items": { + "presets": "プリセット", + "share": "サウンドを共有", + "shuffle": "サウンドをシャッフル", + "sleep-timer": "スリープタイマー", + "countdown": "カウントダウンタイマー", + "pomodoro": "ポモドーロタイマー", + "notepad": "メモ帳", + "todo": "ToDoリスト", + "breathing": "呼吸エクササイズ", + "binaural": "バイノーラルビート", + "isochronic": "アイソクロニックトーン", + "shortcuts": "ショートカット", + "buy-me-a-coffee": "コーヒーをおごる", + "source-code": "ソースコード" + } + }, + "scroll-to-top": { + "aria-label": "トップへスクロール" + }, + "unselect": { + "tooltip": "すべてのサウンドの選択を解除します。", + "aria-label": "すべてのサウンドの選択を解除", + "restore": { + "tooltip": "選択解除したサウンドを復元します。", + "aria-label": "選択解除したサウンドを復元" + } + }, + "favorite": { + "add": { + "aria-label": "{{label}} サウンドをお気に入りに追加" + }, + "remove": { + "aria-label": "{{label}} サウンドをお気に入りから削除" + } + }, + "volume": { + "aria-label": "{{label}} サウンドの音量" + }, + "play-error": "再生するサウンドを選択してください。", + "use-moodist": "Moodistを使う", + "modals": { + "presets": { + "title": "サウンドプリセット", + "your-presets-title": "マイプリセット", + "empty": "まだプリセットがありません。", + "new-preset-title": "新規プリセット", + "placeholder": "プリセット名", + "play-button-tooltip": "プリセットを再生", + "play-button-aria-label": "プリセット {{label}} を再生", + "delete-button-tooltip": "プリセットを削除", + "delete-button-aria-label": "プリセット {{label}} を削除", + "no-selected-warning": "プリセットを作成するには、まずいくつかのサウンドを選択してください。" + }, + "share-link": { + "title": "サウンドセレクションを共有!", + "description": "以下のリンクをコピーして、共有したい相手に送ってください。", + "copy-button-aria-label": "リンクをコピー" + }, + "shared": { + "title": "新しいサウンドミックスが検出されました!", + "description": "誰かが以下のミックスをあなたと共有しました。現在のセレクションを上書きしますか?", + "snackbar-message": "完了!新しいセレクションを再生できます。" + }, + "sleep-timer": { + "title": "スリープタイマー", + "description": "一定時間後にサウンドを停止します。", + "hours-label": "時間", + "minutes-label": "分" + }, + "countdown": { + "title": "カウントダウンタイマー", + "description": "シンプルなカウントダウンタイマーです。", + "placeholder-hh": "時", + "placeholder-mm": "分", + "placeholder-ss": "秒" + }, + "pomodoro": { + "title": "ポモドーロタイマー", + "settings-tooltip": "時間を変更", + "completed": "{{count}} 回完了", + "tabs": { + "pomodoro": "作業", + "short-break": "短い休憩", + "long-break": "長い休憩" + }, + "settings": { + "title": "時間を変更", + "pomodoro-label": "作業時間", + "short-break-label": "短い休憩時間", + "long-break-label": "長い休憩時間", + "minutes-unit": "分" + } + }, + "notepad": { + "title-label": "メモ帳", + "copy-tooltip": "メモをコピー", + "download-tooltip": "メモをダウンロード", + "clear-tooltip": "メモをクリア", + "restore-tooltip": "メモを復元", + "placeholder": "考え事を書き留めましょう...", + "counter-stats": "{{chars}} 文字 • {{words}} 単語" + }, + "todo": { + "title": "ToDoリスト", + "description": "シンプルなToDoリストです。", + "add-placeholder": "やることを入力...", + "add-button": "追加", + "your-todos-label": "あなたのToDo", + "empty": "ToDoはまだありません。", + "delete-button-aria-label": "ToDoを削除" + }, + "breathing": { + "title": "呼吸エクササイズ", + "phases": { + "inhale": "吸って", + "exhale": "吐いて", + "hold": "止めて" + }, + "exercises": { + "box": "ボックス呼吸法", + "resonant": "レゾナント呼吸法", + "478": "4-7-8呼吸法" + } + }, + "generators": { + "presets-label": "プリセット:", + "base-frequency-label": "基本周波数 (Hz):", + "volume-label": "音量:", + "presets": { + "delta": "デルタ波 (深い睡眠) 2 Hz", + "theta": "シータ波 (瞑想) 5 Hz", + "alpha": "アルファ波 (リラックス) 10 Hz", + "beta": "ベータ波 (集中) 20 Hz", + "gamma": "ガンマ波 (認知) 40 Hz", + "custom": "カスタム" + } + }, + "binaural": { + "title": "バイノーラルビート", + "description": "バイノーラルビートジェネレーター。", + "beat-frequency-label": "ビート周波数 (Hz):" + }, + "isochronic": { + "title": "アイソクロニックトーン", + "description": "アイソクロニックトーンジェネレーター。", + "tone-frequency-label": "トーン周波数 (Hz):" + }, + "shortcuts": { + "title": "キーボードショートカット", + "labels": { + "toggle-play": "再生/一時停止 切り替え", + "unselect-all": "全サウンドの選択を解除" + } + }, + "reload": { + "title": "新しいコンテンツが利用可能です", + "description": "新しいコンテンツが利用可能です。更新するには再読み込みボタンをクリックしてください。", + "closeButton": "閉じる", + "reloadButton": "再読み込み" + } + }, + "sounds": { + "show-less": "少なく表示", + "show-more": "もっと表示", + "aria-label": "{{name}} サウンド", + "favorites": { + "title": "お気に入り" + }, + "animals": { + "title": "動物", + "birds": "鳥のさえずり", + "seagulls": "カモメ", + "crickets": "コオロギ", + "wolf": "オオカミの遠吠え", + "owl": "フクロウ", + "frog": "カエル", + "dog-barking": "犬の吠え声", + "horse-galopp": "馬のギャロップ", + "cat-purring": "猫のゴロゴロ", + "crows": "カラス", + "whale": "クジラ", + "beehive": "ミツバチの巣", + "woodpecker": "キツツキ", + "chickens": "ニワトリ", + "cows": "牛", + "sheep": "羊" + }, + "binaural": { + "title": "バイノーラル", + "binaural-delta": "デルタ波 (深い睡眠)", + "binaural-theta": "シータ波 (瞑想)", + "binaural-alpha": "アルファ波 (リラックス)", + "binaural-beta": "ベータ波 (集中)", + "binaural-gamma": "ガンマ波 (認知)" + }, + "nature": { + "title": "自然", + "river": "川", + "waves": "波", + "campfire": "キャンプファイヤー", + "wind": "風", + "howling-wind": "風のうなり", + "wind-in-trees": "木々の間の風", + "waterfall": "滝", + "walk-in-snow": "雪の上を歩く", + "walk-on-leaves": "落ち葉の上を歩く", + "walk-on-gravel": "砂利の上を歩く", + "droplets": "水滴", + "jungle": "ジャングル" + }, + "noise": { + "title": "ノイズ", + "white-noise": "ホワイトノイズ", + "pink-noise": "ピンクノイズ", + "brown-noise": "ブラウンノイズ" + }, + "places": { + "title": "場所", + "cafe": "カフェ", + "airport": "空港", + "church": "教会", + "temple": "寺院", + "construction-site": "建設現場", + "underwater": "水中", + "crowded-bar": "混雑したバー", + "night-village": "夜の村", + "subway-station": "地下鉄の駅", + "office": "オフィス", + "supermarket": "スーパーマーケット", + "carousel": "メリーゴーランド", + "laboratory": "研究室", + "laundry-room": "ランドリールーム", + "restaurant": "レストラン", + "library": "図書館" + }, + "rain": { + "title": "雨", + "light-rain": "小雨", + "heavy-rain": "大雨", + "thunder": "雷", + "rain-on-window": "窓に当たる雨", + "rain-on-car-roof": "車の屋根に当たる雨", + "rain-on-umbrella": "傘に当たる雨", + "rain-on-tent": "テントに当たる雨", + "rain-on-leaves": "葉に当たる雨" + }, + "things": { + "title": "物", + "keyboard": "キーボード", + "typewriter": "タイプライター", + "paper": "紙", + "clock": "時計", + "wind-chimes": "風鈴", + "singing-bowl": "シンギングボウル", + "ceiling-fan": "シーリングファン", + "dryer": "乾燥機", + "slide-projector": "スライドプロジェクター", + "boiling-water": "沸騰したお湯", + "bubbles": "泡", + "tuning-radio": "ラジオのチューニング", + "morse-code": "モールス信号", + "washing-machine": "洗濯機", + "vinyl-effect": "レコードノイズ", + "windshield-wipers": "ワイパー" + }, + "transport": { + "title": "乗り物", + "train": "電車", + "inside-a-train": "電車の中", + "airplane": "飛行機", + "submarine": "潜水艦", + "sailboat": "帆船", + "rowing-boat": "手漕ぎボート" + }, + "urban": { + "title": "都市", + "highway": "高速道路", + "road": "道路", + "ambulance-siren": "救急車のサイレン", + "busy-street": "賑やかな通り", + "crowd": "人混み", + "traffic": "交通", + "fireworks": "花火" + } + }, + "created-by": "{{authorLink}} によって作成されました" +} diff --git a/src/locales/zh/translation.json b/src/locales/zh-CN/translation.json similarity index 99% rename from src/locales/zh/translation.json rename to src/locales/zh-CN/translation.json index fd16a4a..c468097 100644 --- a/src/locales/zh/translation.json +++ b/src/locales/zh-CN/translation.json @@ -6,7 +6,9 @@ }, "languages": { "en": "English", - "zh": "简体中文" + "zh-CN": "简体中文", + "zh-TW": "繁體中文", + "ja": "日本語" }, "common": { "save": "保存", diff --git a/src/locales/zh-TW/translation.json b/src/locales/zh-TW/translation.json new file mode 100644 index 0000000..a1c7339 --- /dev/null +++ b/src/locales/zh-TW/translation.json @@ -0,0 +1,360 @@ +{ + "site": { + "title": "Moodist:營造專注與平靜的環境之聲", + "description": "Moodist 是一款免費且開源的環境聲音產生器,收錄了 {{count}} 種精心挑選的聲音。用這款多功能工具為放鬆、專注或激發創造力打造理想氛圍。", + "ogSiteName": "Moodist" + }, + "languages": { + "en": "English", + "zh-CN": "简体中文", + "zh-TW": "繁體中文", + "ja": "日本語" + }, + "common": { + "save": "儲存", + "untitled": "未命名", + "copy": "複製", + "copied": "已複製!", + "override": "覆蓋", + "done": "完成!", + "reset": "重設", + "play": "播放", + "close": "關閉", + "reload": "重新載入", + "start": "開始", + "pause": "暫停", + "stop": "停止", + "back": "返回", + "restart": "重新開始", + "cancel": "取消", + "delete": "刪除", + "plural-suffix": "" + }, + "hero": { + "logo-alt": "Moodist 標誌", + "title-line1": "Moodist", + "title-line2": "專注與平靜的環境之聲", + "desc-prefix": "免費且", + "desc-open-source": "完全開源", + "sounds-count": "{{count}} 種聲音" + }, + "about": { + "section1": { + "title": "免費環境聲音", + "body": "渴望逃離日常喧囂,尋覓片刻寧靜?需要理想的聲音環境來提升專注力,或是安然入睡?不妨試試 Moodist——您的免費開源環境聲音產生器!無需訂閱註冊,即可免費解鎖一個舒緩、沉浸式的音訊世界。" + }, + "section2": { + "title": "精選環境聲音", + "body": "探索包含 {{count}} 種精心挑選聲音的豐富音庫。自然愛好者們可以在潺潺溪流、規律的海浪拍岸,或是劈啪作響的溫暖營火中尋得慰藉;城市景觀則透過咖啡館的輕柔低語、火車有節奏的行進聲,或是平和的交通白噪音生動再現。對於尋求更深層次專注或放鬆的使用者,Moodist 還提供了旨在幫助調整心境的雙耳節拍和彩色噪音。" + }, + "section3": { + "title": "打造您的專屬音景", + "body": "Moodist 的魅力在於其簡潔與個人化。沒有複雜的選單或令人困惑的選項——只需選擇心儀的聲音,調整音量平衡,即可播放。想將鳥兒的輕柔啁啾與舒緩的雨聲混合?沒問題!隨心疊加任意數量的聲音,創造您的專屬聲音綠洲。" + }, + "section4": { + "title": "滿足不同時刻的需求", + "body": "無論您是想在漫長一天後放鬆身心,在工作學習時集中注意力,還是需要安寧的氛圍助您入睡,Moodist 都有適合您的理想音景。最棒的是,它完全免費且開源,讓您可以無任何負擔地享受。立即開始使用 Moodist,發現屬於您的寧靜與專注空間!" + } + }, + "donate": { + "prompt": "喜歡 Moodist 嗎?", + "link-text": "透過贊助支持我們!", + "section-title": "支持專案", + "section-desc": "幫助 Moodist 保持免費和無廣告。", + "section-button": "贊助一杯咖啡" + }, + "source": { + "title": "開源", + "desc": "Moodist 是免費且開源的!" + }, + "toolbar": { + "menu-aria-label": "選單", + "global-volume-label": "全域音量", + "items": { + "presets": "預設", + "share": "分享聲音", + "shuffle": "隨機組合", + "sleep-timer": "睡眠定時器", + "countdown": "倒數計時器", + "pomodoro": "番茄工作法", + "notepad": "記事簿", + "todo": "待辦清單", + "breathing": "呼吸練習", + "binaural": "雙耳節拍", + "isochronic": "等時聲頻", + "shortcuts": "快速鍵", + "buy-me-a-coffee": "請我喝杯咖啡", + "source-code": "原始碼" + } + }, + "scroll-to-top": { + "aria-label": "捲動到頂部" + }, + "unselect": { + "tooltip": "取消選擇所有聲音。", + "aria-label": "取消選擇所有聲音", + "restore": { + "tooltip": "還原上次的選擇。", + "aria-label": "還原上次的選擇" + } + }, + "favorite": { + "add": { + "aria-label": "收藏 {{label}} 聲音" + }, + "remove": { + "aria-label": "取消收藏 {{label}} 聲音" + } + }, + "volume": { + "aria-label": "{{label}} 聲音音量" + }, + "play-error": "請先選擇要播放的聲音。", + "use-moodist": "開始使用 Moodist", + "modals": { + "presets": { + "title": "聲音預設", + "your-presets-title": "我的預設", + "empty": "您還沒有儲存任何預設。", + "new-preset-title": "新增預設", + "placeholder": "預設名稱", + "play-button-tooltip": "播放預設", + "play-button-aria-label": "播放預設 {{label}}", + "delete-button-tooltip": "刪除預設", + "delete-button-aria-label": "刪除預設 {{label}}", + "no-selected-warning": "請先選擇聲音,再建立預設。" + }, + "share-link": { + "title": "分享您的聲音組合", + "description": "複製下方連結,分享給他人。", + "copy-button-aria-label": "複製連結" + }, + "shared": { + "title": "偵測到分享的聲音組合!", + "description": "有人向您分享了以下聲音組合,是否覆蓋目前選擇?", + "snackbar-message": "載入成功!現在可以播放分享的組合了。" + }, + "sleep-timer": { + "title": "睡眠定時器", + "description": "在設定的時間後自動停止播放聲音。", + "hours-label": "小時", + "minutes-label": "分鐘" + }, + "countdown": { + "title": "倒數計時器", + "description": "簡潔實用的倒數計時器。", + "placeholder-hh": "時", + "placeholder-mm": "分", + "placeholder-ss": "秒" + }, + "pomodoro": { + "title": "番茄工作法", + "settings-tooltip": "設定時長", + "completed": "已完成 {{count}} 個番茄鐘", + "tabs": { + "pomodoro": "工作", + "short-break": "短休息", + "long-break": "長休息" + }, + "settings": { + "title": "設定時長", + "pomodoro-label": "工作時長", + "short-break-label": "短休息時長", + "long-break-label": "長休息時長", + "minutes-unit": "分鐘" + } + }, + "notepad": { + "title-label": "隨手記", + "copy-tooltip": "複製筆記", + "download-tooltip": "下載筆記", + "clear-tooltip": "清空筆記", + "restore-tooltip": "還原筆記", + "placeholder": "記錄您的想法...", + "counter-stats": "{{chars}} 個字元 • {{words}} 個詞語" + }, + "todo": { + "title": "待辦清單", + "description": "簡潔實用的待辦事項列表。", + "add-placeholder": "新增待辦事項...", + "add-button": "新增", + "your-todos-label": "我的待辦", + "empty": "這裡還沒有待辦事項。", + "delete-button-aria-label": "刪除此待辦事項" + }, + "breathing": { + "title": "呼吸練習", + "phases": { + "inhale": "吸氣", + "exhale": "吐氣", + "hold": "屏息" + }, + "exercises": { + "box": "方形呼吸法", + "resonant": "同步呼吸法", + "478": "4-7-8 呼吸法" + } + }, + "generators": { + "presets-label": "預設:", + "base-frequency-label": "基礎頻率 (Hz):", + "volume-label": "音量:", + "presets": { + "delta": "Delta 波 (深度睡眠) 2 Hz", + "theta": "Theta 波 (冥想) 5 Hz", + "alpha": "Alpha 波 (放鬆) 10 Hz", + "beta": "Beta 波 (專注) 20 Hz", + "gamma": "Gamma 波 (認知) 40 Hz", + "custom": "自訂" + } + }, + "binaural": { + "title": "雙耳節拍", + "description": "產生雙耳節拍聲音。", + "beat-frequency-label": "節拍頻率 (Hz):" + }, + "isochronic": { + "title": "等時聲頻", + "description": "產生等時聲頻聲音。", + "tone-frequency-label": "聲頻頻率 (Hz):" + }, + "shortcuts": { + "title": "鍵盤快速鍵", + "labels": { + "toggle-play": "播放/暫停", + "unselect-all": "取消全選聲音" + } + }, + "reload": { + "title": "有新的更新可用", + "description": "偵測到新版本,點擊「重新載入」按鈕以更新。", + "closeButton": "關閉", + "reloadButton": "重新載入" + } + }, + "sounds": { + "show-less": "收合", + "show-more": "展開更多", + "aria-label": "{{name}} 聲音", + "favorites": { + "title": "我的收藏" + }, + "animals": { + "title": "動物", + "birds": "鳥鳴", + "seagulls": "海鷗", + "crickets": "蟋蟀", + "wolf": "狼嚎", + "owl": "貓頭鷹", + "frog": "蛙鳴", + "dog-barking": "狗吠", + "horse-galopp": "馬蹄聲", + "cat-purring": "貓呼嚕聲", + "crows": "烏鴉", + "whale": "鯨魚", + "beehive": "蜂巢", + "woodpecker": "啄木鳥", + "chickens": "雞鳴", + "cows": "牛叫", + "sheep": "羊叫" + }, + "binaural": { + "title": "腦波", + "binaural-delta": "Delta 波 (深度睡眠)", + "binaural-theta": "Theta 波 (冥想)", + "binaural-alpha": "Alpha 波 (放鬆)", + "binaural-beta": "Beta 波 (專注)", + "binaural-gamma": "Gamma 波 (認知)" + }, + "nature": { + "title": "自然", + "river": "河流", + "waves": "海浪", + "campfire": "營火", + "wind": "風聲", + "howling-wind": "風嘯聲", + "wind-in-trees": "林間風聲", + "waterfall": "瀑布", + "walk-in-snow": "雪地腳步", + "walk-on-leaves": "落葉腳步", + "walk-on-gravel": "碎石腳步", + "droplets": "水滴", + "jungle": "叢林聲" + }, + "noise": { + "title": "噪音", + "white-noise": "白噪音", + "pink-noise": "粉紅噪音", + "brown-noise": "布朗噪音" + }, + "places": { + "title": "場所", + "cafe": "咖啡館", + "airport": "機場", + "church": "教堂", + "temple": "寺廟", + "construction-site": "建築工地", + "underwater": "水下", + "crowded-bar": "嘈雜酒吧", + "night-village": "鄉村夜晚", + "subway-station": "地鐵站", + "office": "辦公室", + "supermarket": "超級市場", + "carousel": "旋轉木馬", + "laboratory": "實驗室", + "laundry-room": "洗衣間", + "restaurant": "餐廳", + "library": "圖書館" + }, + "rain": { + "title": "雨聲", + "light-rain": "小雨", + "heavy-rain": "大雨", + "thunder": "雷聲", + "rain-on-window": "雨打窗戶", + "rain-on-car-roof": "雨打車頂", + "rain-on-umbrella": "雨打雨傘", + "rain-on-tent": "雨打帳篷", + "rain-on-leaves": "雨打樹葉" + }, + "things": { + "title": "物品", + "keyboard": "鍵盤聲", + "typewriter": "打字機聲", + "paper": "紙張翻動", + "clock": "時鐘滴答", + "wind-chimes": "風鈴", + "singing-bowl": "頌缽", + "ceiling-fan": "吊扇", + "dryer": "烘乾機", + "slide-projector": "幻燈機", + "boiling-water": "沸水", + "bubbles": "氣泡", + "tuning-radio": "收音機調頻", + "morse-code": "摩斯電碼", + "washing-machine": "洗衣機", + "vinyl-effect": "黑膠唱片噪音", + "windshield-wipers": "雨刷" + }, + "transport": { + "title": "交通", + "train": "火車聲", + "inside-a-train": "車廂內", + "airplane": "飛機聲", + "submarine": "潛艇聲", + "sailboat": "帆船航行", + "rowing-boat": "划艇聲" + }, + "urban": { + "title": "城市", + "highway": "高速公路", + "road": "街道", + "ambulance-siren": "救護車警笛", + "busy-street": "繁忙街道", + "crowd": "人群嘈雜", + "traffic": "交通噪音", + "fireworks": "煙火" + } + }, + "created-by": "由 {{authorLink}} 建立" +} diff --git a/src/pages/zh/index.astro b/src/pages/ja/index.astro similarity index 100% rename from src/pages/zh/index.astro rename to src/pages/ja/index.astro diff --git a/src/pages/zh-CN/index.astro b/src/pages/zh-CN/index.astro new file mode 100644 index 0000000..821c8bc --- /dev/null +++ b/src/pages/zh-CN/index.astro @@ -0,0 +1,20 @@ +--- +import Layout from '@/layouts/layout.astro'; +import Donate from '@/components/donate.astro'; +import Hero from '@/components/hero.astro'; +import About from '@/components/about.astro'; +import Source from '@/components/source.astro'; +import Footer from '@/components/footer.astro'; +import { App } from '@/components/app'; + +const currentLocale = Astro.currentLocale || 'en'; +--- + + + + + + + +