From 34752801783815700422649b6a06930f55288716 Mon Sep 17 00:00:00 2001 From: InstaZDLL Date: Sat, 16 May 2026 16:20:16 +0200 Subject: [PATCH 1/3] fix(locale): translate home daily mix section and tray menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #29 - add home.dailyMix keys (title, regenerate, emptyTitle, …) to all 17 locales — HomeView previously fell back to hard-coded French strings. - localise the system tray menu: seed labels in English, stash MenuItem handles in app state, expose set_tray_labels Tauri command, push the translated labels from i18n once i18nReady resolves and on every languageChanged. --- src-tauri/src/commands/mod.rs | 1 + src-tauri/src/commands/tray.rs | 54 ++++++++++++++++++++++++++++++++++ src-tauri/src/lib.rs | 41 ++++++++++++++++++++------ src/i18n/index.ts | 24 ++++++++++++++- src/i18n/locales/ar.json | 19 ++++++++++++ src/i18n/locales/de.json | 19 ++++++++++++ src/i18n/locales/en.json | 19 ++++++++++++ src/i18n/locales/es.json | 19 ++++++++++++ src/i18n/locales/fr.json | 19 ++++++++++++ src/i18n/locales/hi.json | 19 ++++++++++++ src/i18n/locales/id.json | 19 ++++++++++++ src/i18n/locales/it.json | 19 ++++++++++++ src/i18n/locales/ja.json | 19 ++++++++++++ src/i18n/locales/kr.json | 19 ++++++++++++ src/i18n/locales/nl.json | 19 ++++++++++++ src/i18n/locales/pt-BR.json | 19 ++++++++++++ src/i18n/locales/pt.json | 19 ++++++++++++ src/i18n/locales/ru.json | 19 ++++++++++++ src/i18n/locales/tr.json | 19 ++++++++++++ src/i18n/locales/zh-CN.json | 19 ++++++++++++ src/i18n/locales/zh-TW.json | 19 ++++++++++++ src/lib/tauri/tray.ts | 13 ++++++++ 22 files changed, 446 insertions(+), 10 deletions(-) create mode 100644 src-tauri/src/commands/tray.rs create mode 100644 src/lib/tauri/tray.ts diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index 9032e5e..75e16fe 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -33,4 +33,5 @@ pub mod smart_playlists; pub mod spotify; pub mod stats; pub mod track; +pub mod tray; pub mod wrapped; diff --git a/src-tauri/src/commands/tray.rs b/src-tauri/src/commands/tray.rs new file mode 100644 index 0000000..d9d6654 --- /dev/null +++ b/src-tauri/src/commands/tray.rs @@ -0,0 +1,54 @@ +//! Tray menu localisation bridge. +//! +//! The system tray menu (Play/Pause, Previous, Next, Open WaveFlow, Quit) +//! is created in Rust at startup before the frontend has loaded i18next, +//! so the labels are seeded in English and the frontend pushes a +//! localised set once `i18nReady` resolves — and again on every +//! `languageChanged`. The `MenuItem` handles are stashed in +//! [`TrayMenuItems`] so this command can call `set_text` without +//! rebuilding the menu. + +use tauri::{menu::MenuItem, AppHandle, Manager, Runtime, State}; + +/// Holds the five user-facing tray `MenuItem`s so their labels can be +/// retitled at runtime when the UI language changes. +pub struct TrayMenuItems { + pub play_pause: MenuItem, + pub previous: MenuItem, + pub next: MenuItem, + pub show: MenuItem, + pub quit: MenuItem, +} + +#[derive(serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TrayLabels { + pub play_pause: String, + pub previous: String, + pub next: String, + pub show: String, + pub quit: String, +} + +#[tauri::command] +pub fn set_tray_labels( + app: AppHandle, + labels: TrayLabels, +) -> Result<(), String> { + let Some(items) = app.try_state::>() else { + return Ok(()); + }; + apply(&items, &labels).map_err(|e| e.to_string()) +} + +fn apply( + items: &State<'_, TrayMenuItems>, + labels: &TrayLabels, +) -> tauri::Result<()> { + items.play_pause.set_text(&labels.play_pause)?; + items.previous.set_text(&labels.previous)?; + items.next.set_text(&labels.next)?; + items.show.set_text(&labels.show)?; + items.quit.set_text(&labels.quit)?; + Ok(()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a6dbdd0..5e1d78e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -42,7 +42,7 @@ use queue::Direction; use state::AppState; use watcher::WatcherManager; -/// Set to `true` by the tray "Quitter" menu before calling `app.exit()`. +/// Set to `true` by the tray "Quit" menu before calling `app.exit()`. /// `WindowEvent::CloseRequested` checks the flag: if armed, the close /// proceeds to actual shutdown; otherwise the close is intercepted and /// the window is hidden instead (close-to-tray default). @@ -295,25 +295,47 @@ pub fn run() { // System tray (status icon). // - // Menu: Lecture/Pause, Précédent, Suivant, Ouvrir WaveFlow, - // Quitter. Left-click on the icon mirrors "Ouvrir WaveFlow" - // for the common case where the window was hidden via the + // Labels are seeded in English because Rust runs before the + // frontend has had a chance to load i18next; the React layer + // pushes a localised set via `set_tray_labels` once + // `i18nReady` resolves, and again on every `languageChanged` + // event. The `MenuItem` handles are stashed in + // `TrayMenuItems` so retitling doesn't rebuild the menu. + // Left-click on the icon mirrors "Open WaveFlow" for the + // common case where the window was hidden via the // close-to-tray path. Tooltip is updated to "Title — Artist" // by `commands::player::emit_track_changed` whenever a new // track starts. + let play_pause_item = + MenuItem::with_id(app, "play_pause", "Play / Pause", true, None::<&str>)?; + let previous_item = + MenuItem::with_id(app, "previous", "Previous", true, None::<&str>)?; + let next_item = MenuItem::with_id(app, "next", "Next", true, None::<&str>)?; + let show_item = + MenuItem::with_id(app, "show", "Open WaveFlow", true, None::<&str>)?; + let quit_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?; + let menu = Menu::with_items( app, &[ - &MenuItem::with_id(app, "play_pause", "Lecture / Pause", true, None::<&str>)?, - &MenuItem::with_id(app, "previous", "Précédent", true, None::<&str>)?, - &MenuItem::with_id(app, "next", "Suivant", true, None::<&str>)?, + &play_pause_item, + &previous_item, + &next_item, &PredefinedMenuItem::separator(app)?, - &MenuItem::with_id(app, "show", "Ouvrir WaveFlow", true, None::<&str>)?, + &show_item, &PredefinedMenuItem::separator(app)?, - &MenuItem::with_id(app, "quit", "Quitter", true, None::<&str>)?, + &quit_item, ], )?; + app.manage(commands::tray::TrayMenuItems { + play_pause: play_pause_item, + previous: previous_item, + next: next_item, + show: show_item, + quit: quit_item, + }); + let icon = app .default_window_icon() .cloned() @@ -464,6 +486,7 @@ pub fn run() { commands::preferences::set_minimize_to_tray, commands::preferences::get_auto_start, commands::preferences::set_auto_start, + commands::tray::set_tray_labels, commands::lyrics::get_lyrics, commands::lyrics::fetch_lyrics, commands::lyrics::import_lrc_file, diff --git a/src/i18n/index.ts b/src/i18n/index.ts index b796975..7c9b241 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -1,4 +1,5 @@ import i18n from "i18next"; +import { setTrayLabels } from "../lib/tauri/tray"; import type { BackendModule, InitOptions, @@ -139,6 +140,23 @@ function applyDocumentLanguage(code: string | undefined) { document.documentElement.dir = i18n.dir(normalizedCode); } +// Push the localised tray menu labels to the Rust backend. The tray +// is built at startup with English seed strings (frontend hasn't had +// time to load i18next yet); this re-titles each item once the user +// language is known and on every subsequent `languageChanged`. +function pushTrayLabels() { + setTrayLabels({ + playPause: i18n.t("system.tray.playPause"), + previous: i18n.t("system.tray.previous"), + next: i18n.t("system.tray.next"), + show: i18n.t("system.tray.show"), + quit: i18n.t("system.tray.quit"), + }).catch(() => { + // Tauri command unavailable (e.g. running outside the desktop + // shell during a Vite-only dev session) — drop silently. + }); +} + const dynamicLocaleBackend: BackendModule = { type: "backend", init( @@ -189,8 +207,12 @@ export const i18nReady = i18n }) .then(() => { applyDocumentLanguage(i18n.resolvedLanguage ?? i18n.language); + pushTrayLabels(); }); -i18n.on("languageChanged", applyDocumentLanguage); +i18n.on("languageChanged", (code) => { + applyDocumentLanguage(code); + pushTrayLabels(); +}); export default i18n; diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json index 4678c0d..e39f53d 100644 --- a/src/i18n/locales/ar.json +++ b/src/i18n/locales/ar.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "أُضيف حديثاً" }, + "dailyMix": { + "title": "من أجلك", + "regenerate": "إعادة التوليد", + "regenerating": "جارٍ التوليد…", + "emptyTitle": "لا يوجد Daily Mix بعد", + "emptyDescription": "استمع إلى بعض المقطوعات ثم اضغط على إعادة التوليد لإنشاء مزيجك الخاص.", + "label": "Daily Mix", + "trackCount_one": "{{count}} مقطوعة", + "trackCount_other": "{{count}} مقطوعة" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "ملخّصك لعام {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} ملف", "doneTitle": "اكتمل التحليل", "doneSubtitle": "تمت إضافة {{added}} · تحديث {{updated}} · تخطّي {{skipped}}" + }, + "system": { + "tray": { + "playPause": "تشغيل / إيقاف مؤقت", + "previous": "السابق", + "next": "التالي", + "show": "فتح WaveFlow", + "quit": "خروج" + } } } diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index cac7edb..047b824 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Kürzlich hinzugefügt" }, + "dailyMix": { + "title": "Für dich", + "regenerate": "Neu generieren", + "regenerating": "Wird generiert…", + "emptyTitle": "Noch kein Daily Mix", + "emptyDescription": "Höre ein paar Titel und klicke dann auf Neu generieren, um deine persönlichen Mixe zu erstellen.", + "label": "Daily Mix", + "trackCount_one": "{{count}} Titel", + "trackCount_other": "{{count}} Titel" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Dein Rückblick {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} Dateien", "doneTitle": "Analyse abgeschlossen", "doneSubtitle": "{{added}} hinzugefügt · {{updated}} aktualisiert · {{skipped}} übersprungen" + }, + "system": { + "tray": { + "playPause": "Wiedergabe / Pause", + "previous": "Zurück", + "next": "Weiter", + "show": "WaveFlow öffnen", + "quit": "Beenden" + } } } diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 2932054..27451f9 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Recently added" }, + "dailyMix": { + "title": "For you", + "regenerate": "Regenerate", + "regenerating": "Generating…", + "emptyTitle": "No Daily Mix yet", + "emptyDescription": "Listen to a few tracks then click Regenerate to create your personalised mixes.", + "label": "Daily Mix", + "trackCount_one": "{{count}} track", + "trackCount_other": "{{count}} tracks" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Your {{year}} recap", @@ -1352,5 +1362,14 @@ "runningSubtitle": "{{current}} / {{total}} files", "doneTitle": "Scan complete", "doneSubtitle": "{{added}} added · {{updated}} updated · {{skipped}} skipped" + }, + "system": { + "tray": { + "playPause": "Play / Pause", + "previous": "Previous", + "next": "Next", + "show": "Open WaveFlow", + "quit": "Quit" + } } } diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 919c15b..c1cd557 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Añadidos recientemente" }, + "dailyMix": { + "title": "Para ti", + "regenerate": "Regenerar", + "regenerating": "Generando…", + "emptyTitle": "Aún no hay Daily Mix", + "emptyDescription": "Escucha algunas canciones y luego pulsa Regenerar para crear tus mixes personalizados.", + "label": "Daily Mix", + "trackCount_one": "{{count}} pista", + "trackCount_other": "{{count}} pistas" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Tu resumen {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} archivos", "doneTitle": "Análisis completado", "doneSubtitle": "{{added}} añadidos · {{updated}} actualizados · {{skipped}} omitidos" + }, + "system": { + "tray": { + "playPause": "Reproducir / Pausa", + "previous": "Anterior", + "next": "Siguiente", + "show": "Abrir WaveFlow", + "quit": "Salir" + } } } diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 0fde95f..fce1c54 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Récemment ajoutés" }, + "dailyMix": { + "title": "Pour vous", + "regenerate": "Régénérer", + "regenerating": "Génération…", + "emptyTitle": "Pas encore de Daily Mix", + "emptyDescription": "Écoute quelques morceaux puis clique sur Régénérer pour créer tes mixes personnalisés.", + "label": "Daily Mix", + "trackCount_one": "{{count}} morceau", + "trackCount_other": "{{count}} morceaux" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Votre rétro {{year}}", @@ -1352,5 +1362,14 @@ "runningSubtitle": "{{current}} / {{total}} fichiers", "doneTitle": "Analyse terminée", "doneSubtitle": "{{added}} ajoutés · {{updated}} mis à jour · {{skipped}} ignorés" + }, + "system": { + "tray": { + "playPause": "Lecture / Pause", + "previous": "Précédent", + "next": "Suivant", + "show": "Ouvrir WaveFlow", + "quit": "Quitter" + } } } diff --git a/src/i18n/locales/hi.json b/src/i18n/locales/hi.json index fcbceb6..f35788a 100644 --- a/src/i18n/locales/hi.json +++ b/src/i18n/locales/hi.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "हाल ही में जोड़े गए" }, + "dailyMix": { + "title": "आपके लिए", + "regenerate": "फिर बनाएँ", + "regenerating": "बनाया जा रहा है…", + "emptyTitle": "अभी कोई Daily Mix नहीं", + "emptyDescription": "कुछ ट्रैक सुनें फिर अपने व्यक्तिगत मिक्स बनाने के लिए फिर बनाएँ पर क्लिक करें।", + "label": "Daily Mix", + "trackCount_one": "{{count}} ट्रैक", + "trackCount_other": "{{count}} ट्रैक" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "आपका {{year}} रीकैप", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} फ़ाइलें", "doneTitle": "स्कैन पूर्ण", "doneSubtitle": "{{added}} जोड़े · {{updated}} अपडेट · {{skipped}} छोड़े" + }, + "system": { + "tray": { + "playPause": "चलाएँ / रोकें", + "previous": "पिछला", + "next": "अगला", + "show": "WaveFlow खोलें", + "quit": "बंद करें" + } } } diff --git a/src/i18n/locales/id.json b/src/i18n/locales/id.json index f8bb0df..b5420b2 100644 --- a/src/i18n/locales/id.json +++ b/src/i18n/locales/id.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Baru ditambahkan" }, + "dailyMix": { + "title": "Untuk kamu", + "regenerate": "Buat ulang", + "regenerating": "Membuat…", + "emptyTitle": "Belum ada Daily Mix", + "emptyDescription": "Dengarkan beberapa lagu lalu klik Buat ulang untuk membuat mix personal kamu.", + "label": "Daily Mix", + "trackCount_one": "{{count}} lagu", + "trackCount_other": "{{count}} lagu" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Ringkasan {{year}} kamu", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} berkas", "doneTitle": "Pemindaian selesai", "doneSubtitle": "{{added}} ditambahkan · {{updated}} diperbarui · {{skipped}} dilewati" + }, + "system": { + "tray": { + "playPause": "Putar / Jeda", + "previous": "Sebelumnya", + "next": "Berikutnya", + "show": "Buka WaveFlow", + "quit": "Keluar" + } } } diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index ad063cd..1a091ba 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Aggiunti di recente" }, + "dailyMix": { + "title": "Per te", + "regenerate": "Rigenera", + "regenerating": "Generazione…", + "emptyTitle": "Nessun Daily Mix ancora", + "emptyDescription": "Ascolta qualche brano poi clicca su Rigenera per creare i tuoi mix personalizzati.", + "label": "Daily Mix", + "trackCount_one": "{{count}} brano", + "trackCount_other": "{{count}} brani" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Il tuo riepilogo {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} file", "doneTitle": "Scansione completata", "doneSubtitle": "{{added}} aggiunti · {{updated}} aggiornati · {{skipped}} ignorati" + }, + "system": { + "tray": { + "playPause": "Riproduci / Pausa", + "previous": "Precedente", + "next": "Successivo", + "show": "Apri WaveFlow", + "quit": "Esci" + } } } diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index 8d8375f..77d4014 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "最近追加された曲" }, + "dailyMix": { + "title": "あなたへのおすすめ", + "regenerate": "再生成", + "regenerating": "生成中…", + "emptyTitle": "Daily Mix はまだありません", + "emptyDescription": "数曲再生してから「再生成」を押すと、あなた専用のミックスが作成されます。", + "label": "Daily Mix", + "trackCount_one": "{{count}} 曲", + "trackCount_other": "{{count}} 曲" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "{{year}}年のあなた", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} ファイル", "doneTitle": "スキャン完了", "doneSubtitle": "{{added}} 追加 · {{updated}} 更新 · {{skipped}} スキップ" + }, + "system": { + "tray": { + "playPause": "再生 / 一時停止", + "previous": "前へ", + "next": "次へ", + "show": "WaveFlow を開く", + "quit": "終了" + } } } diff --git a/src/i18n/locales/kr.json b/src/i18n/locales/kr.json index 8d0116f..524916a 100644 --- a/src/i18n/locales/kr.json +++ b/src/i18n/locales/kr.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "최근 추가됨" }, + "dailyMix": { + "title": "당신을 위한 추천", + "regenerate": "다시 생성", + "regenerating": "생성 중…", + "emptyTitle": "아직 Daily Mix가 없습니다", + "emptyDescription": "몇 곡을 재생한 뒤 다시 생성을 눌러 개인 맞춤 믹스를 만들어 보세요.", + "label": "Daily Mix", + "trackCount_one": "{{count}} 곡", + "trackCount_other": "{{count}} 곡" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "{{year}}년 결산", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}}개 파일", "doneTitle": "스캔 완료", "doneSubtitle": "{{added}}개 추가 · {{updated}}개 업데이트 · {{skipped}}개 건너뜀" + }, + "system": { + "tray": { + "playPause": "재생 / 일시정지", + "previous": "이전", + "next": "다음", + "show": "WaveFlow 열기", + "quit": "종료" + } } } diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json index c72e06f..b5526ac 100644 --- a/src/i18n/locales/nl.json +++ b/src/i18n/locales/nl.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Onlangs toegevoegd" }, + "dailyMix": { + "title": "Voor jou", + "regenerate": "Opnieuw genereren", + "regenerating": "Genereren…", + "emptyTitle": "Nog geen Daily Mix", + "emptyDescription": "Luister naar een paar nummers en klik dan op Opnieuw genereren om je gepersonaliseerde mixen te maken.", + "label": "Daily Mix", + "trackCount_one": "{{count}} nummer", + "trackCount_other": "{{count}} nummers" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Jouw {{year}} samenvatting", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} bestanden", "doneTitle": "Scan voltooid", "doneSubtitle": "{{added}} toegevoegd · {{updated}} bijgewerkt · {{skipped}} overgeslagen" + }, + "system": { + "tray": { + "playPause": "Afspelen / Pauze", + "previous": "Vorige", + "next": "Volgende", + "show": "WaveFlow openen", + "quit": "Afsluiten" + } } } diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json index 5cea733..75120e1 100644 --- a/src/i18n/locales/pt-BR.json +++ b/src/i18n/locales/pt-BR.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Adicionados recentemente" }, + "dailyMix": { + "title": "Para você", + "regenerate": "Regenerar", + "regenerating": "Gerando…", + "emptyTitle": "Nenhum Daily Mix ainda", + "emptyDescription": "Ouça algumas faixas e depois clique em Regenerar para criar suas mixes personalizadas.", + "label": "Daily Mix", + "trackCount_one": "{{count}} faixa", + "trackCount_other": "{{count}} faixas" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Sua retrospectiva {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} arquivos", "doneTitle": "Análise concluída", "doneSubtitle": "{{added}} adicionados · {{updated}} atualizados · {{skipped}} ignorados" + }, + "system": { + "tray": { + "playPause": "Reproduzir / Pausar", + "previous": "Anterior", + "next": "Próximo", + "show": "Abrir WaveFlow", + "quit": "Sair" + } } } diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json index e246d6a..495ef5a 100644 --- a/src/i18n/locales/pt.json +++ b/src/i18n/locales/pt.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Adicionados recentemente" }, + "dailyMix": { + "title": "Para ti", + "regenerate": "Regenerar", + "regenerating": "A gerar…", + "emptyTitle": "Ainda sem Daily Mix", + "emptyDescription": "Ouve algumas faixas e depois clica em Regenerar para criar os teus mixes personalizados.", + "label": "Daily Mix", + "trackCount_one": "{{count}} faixa", + "trackCount_other": "{{count}} faixas" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "A tua retrospetiva {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} ficheiros", "doneTitle": "Análise concluída", "doneSubtitle": "{{added}} adicionados · {{updated}} atualizados · {{skipped}} ignorados" + }, + "system": { + "tray": { + "playPause": "Reproduzir / Pausa", + "previous": "Anterior", + "next": "Seguinte", + "show": "Abrir WaveFlow", + "quit": "Sair" + } } } diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index c83209d..c6d3e25 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Недавно добавленные" }, + "dailyMix": { + "title": "Для тебя", + "regenerate": "Обновить", + "regenerating": "Создание…", + "emptyTitle": "Daily Mix ещё нет", + "emptyDescription": "Послушай несколько треков и нажми Обновить, чтобы создать свои персональные миксы.", + "label": "Daily Mix", + "trackCount_one": "{{count}} трек", + "trackCount_other": "{{count}} треков" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "Ваш итог {{year}}", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} файлов", "doneTitle": "Сканирование завершено", "doneSubtitle": "{{added}} добавлено · {{updated}} обновлено · {{skipped}} пропущено" + }, + "system": { + "tray": { + "playPause": "Воспроизвести / Пауза", + "previous": "Назад", + "next": "Далее", + "show": "Открыть WaveFlow", + "quit": "Выйти" + } } } diff --git a/src/i18n/locales/tr.json b/src/i18n/locales/tr.json index d6f7963..8b80080 100644 --- a/src/i18n/locales/tr.json +++ b/src/i18n/locales/tr.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "Yakın zamanda eklenenler" }, + "dailyMix": { + "title": "Senin için", + "regenerate": "Yeniden oluştur", + "regenerating": "Oluşturuluyor…", + "emptyTitle": "Henüz Daily Mix yok", + "emptyDescription": "Birkaç parça dinle, sonra kişisel mikslerini oluşturmak için Yeniden oluştur'a tıkla.", + "label": "Daily Mix", + "trackCount_one": "{{count}} parça", + "trackCount_other": "{{count}} parça" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "{{year}} özetin", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} dosya", "doneTitle": "Tarama tamamlandı", "doneSubtitle": "{{added}} eklendi · {{updated}} güncellendi · {{skipped}} atlandı" + }, + "system": { + "tray": { + "playPause": "Oynat / Duraklat", + "previous": "Önceki", + "next": "Sonraki", + "show": "WaveFlow'u aç", + "quit": "Çık" + } } } diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 3551fd4..82c7bcf 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "最近添加" }, + "dailyMix": { + "title": "为你推荐", + "regenerate": "重新生成", + "regenerating": "生成中…", + "emptyTitle": "暂无 Daily Mix", + "emptyDescription": "先听几首歌,然后点击重新生成以创建你的个性化合辑。", + "label": "Daily Mix", + "trackCount_one": "{{count}} 首", + "trackCount_other": "{{count}} 首" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "你的 {{year}} 年度回顾", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} 个文件", "doneTitle": "扫描完成", "doneSubtitle": "已添加 {{added}} · 已更新 {{updated}} · 已跳过 {{skipped}}" + }, + "system": { + "tray": { + "playPause": "播放 / 暂停", + "previous": "上一首", + "next": "下一首", + "show": "打开 WaveFlow", + "quit": "退出" + } } } diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index 9ee4c18..00305be 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -213,6 +213,16 @@ "recentlyAdded": { "title": "最近新增" }, + "dailyMix": { + "title": "為你推薦", + "regenerate": "重新產生", + "regenerating": "產生中…", + "emptyTitle": "還沒有 Daily Mix", + "emptyDescription": "先聽幾首歌,然後點擊重新產生來建立你的個人化合輯。", + "label": "Daily Mix", + "trackCount_one": "{{count}} 首", + "trackCount_other": "{{count}} 首" + }, "wrapped": { "eyebrow": "WaveFlow Wrapped", "title": "你的 {{year}} 年度回顧", @@ -1277,5 +1287,14 @@ "runningSubtitle": "{{current}} / {{total}} 個檔案", "doneTitle": "掃描完成", "doneSubtitle": "已新增 {{added}} · 已更新 {{updated}} · 已略過 {{skipped}}" + }, + "system": { + "tray": { + "playPause": "播放 / 暫停", + "previous": "上一首", + "next": "下一首", + "show": "開啟 WaveFlow", + "quit": "結束" + } } } diff --git a/src/lib/tauri/tray.ts b/src/lib/tauri/tray.ts new file mode 100644 index 0000000..d3054be --- /dev/null +++ b/src/lib/tauri/tray.ts @@ -0,0 +1,13 @@ +import { invoke } from "@tauri-apps/api/core"; + +export interface TrayLabels { + playPause: string; + previous: string; + next: string; + show: string; + quit: string; +} + +export function setTrayLabels(labels: TrayLabels): Promise { + return invoke("set_tray_labels", { labels }); +} From dd1d7a7bffab98600505bdfda218c53a8142f6ea Mon Sep 17 00:00:00 2001 From: InstaZDLL Date: Sat, 16 May 2026 16:24:52 +0200 Subject: [PATCH 2/3] fix(locale): declare missing keys in playlist modal, spotify integration, and progress bar Audit revealed 22 t() call sites whose key was absent from every locale file, so the inline fallback (mix of English and French) was the actual rendered string regardless of the user's language. Adds the keys with proper translations across all 17 locales. - playlistModal.coverChoose / coverMenu / coverChange / coverRemove / coverAutoHint / coverManualHint - sidebar.nav.spotify, playlistView.smartLabel, player.seek - settings.integrations.spotify.* (title, subtitle, clientIdPlaceholder, redirectHint, connectedAs, disconnect, connecting, connect) - spotify.deviceReady / devicePending / searchPlaceholder / tracks / playlists --- src/i18n/locales/ar.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/de.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/en.json | 34 +++++++++++++++++++++++++++++----- src/i18n/locales/es.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/fr.json | 34 +++++++++++++++++++++++++++++----- src/i18n/locales/hi.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/id.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/it.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/ja.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/kr.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/nl.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/pt-BR.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/pt.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/ru.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/tr.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/zh-CN.json | 34 ++++++++++++++++++++++++++++++---- src/i18n/locales/zh-TW.json | 34 ++++++++++++++++++++++++++++++---- 17 files changed, 508 insertions(+), 70 deletions(-) diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json index e39f53d..b6350b3 100644 --- a/src/i18n/locales/ar.json +++ b/src/i18n/locales/ar.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "الصفحة الرئيسية" + "home": "الصفحة الرئيسية", + "spotify": "Spotify" }, "sections": { "open": "فتح", @@ -600,7 +601,8 @@ "slider": "شريط تمرير السرعة", "custom": "سرعة مخصصة", "pitchHint": "تتبع طبقة الصوت السرعة (بدون تمديد زمني)." - } + }, + "seek": "الموضع" }, "queue": { "title": "قائمة انتظار التشغيل", @@ -674,7 +676,13 @@ "iconLabel": "أيقونة", "iconAria": "أيقونة {{icon}}", "submit": "إنشاء", - "editSubmit": "حفظ" + "editSubmit": "حفظ", + "coverChoose": "اختر صورة", + "coverMenu": "خيارات الغلاف", + "coverChange": "تغيير الصورة", + "coverRemove": "إزالة الصورة", + "coverAutoHint": "غلاف تلقائي — يُحدَّث مع المحتوى", + "coverManualHint": "صورة مخصّصة" }, "playlistView": { "badge": "قائمة التشغيل", @@ -697,7 +705,8 @@ "noneTitle": "لم يتم تحديد أي قائمة تشغيل", "noneDescription": "اختر قائمة تشغيل من الشريط الجانبي لعرضها هنا.", "notFoundTitle": "لا يمكن العثور على قائمة التشغيل", - "notFoundDescription": "هذه القائمة الموسيقية لم تعد موجودة في الملف الشخصي النشط." + "notFoundDescription": "هذه القائمة الموسيقية لم تعد موجودة في الملف الشخصي النشط.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "إضافة إلى قائمة التشغيل", @@ -1117,6 +1126,16 @@ "statusRunning": "يعمل", "statusStopped": "متوقف", "copyUrl": "نسخ الرابط" + }, + "spotify": { + "title": "Spotify", + "subtitle": "اربط Spotify Premium باستخدام Client ID الخاص بك من Spotify Developer.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "أضف Redirect URI هذا في Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "متصل باسم", + "disconnect": "قطع الاتصال", + "connecting": "جارٍ الاتصال…", + "connect": "الاتصال بـ Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "فتح WaveFlow", "quit": "خروج" } + }, + "spotify": { + "deviceReady": "جهاز Spotify الخاص بـ WaveFlow جاهز", + "devicePending": "جارٍ تحضير تشغيل Spotify…", + "searchPlaceholder": "البحث في Spotify", + "tracks": "المقطوعات", + "playlists": "قوائم التشغيل" } } diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index 047b824..f9d36af 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Startseite" + "home": "Startseite", + "spotify": "Spotify" }, "sections": { "open": "Öffnen", @@ -600,7 +601,8 @@ "slider": "Geschwindigkeitsregler", "custom": "Benutzerdefinierte Geschwindigkeit", "pitchHint": "Tonhöhe folgt der Geschwindigkeit (kein Time-Stretching)." - } + }, + "seek": "Position" }, "queue": { "title": "Warteschlange abspielen", @@ -674,7 +676,13 @@ "iconLabel": "Symbol", "iconAria": "{{icon}}-Symbol", "submit": "Erstellen", - "editSubmit": "Speichern" + "editSubmit": "Speichern", + "coverChoose": "Foto wählen", + "coverMenu": "Cover-Optionen", + "coverChange": "Foto ändern", + "coverRemove": "Foto entfernen", + "coverAutoHint": "Automatisches Cover — passt sich dem Inhalt an", + "coverManualHint": "Eigenes Bild" }, "playlistView": { "badge": "Playlist", @@ -697,7 +705,8 @@ "noneTitle": "Es wurde keine Wiedergabeliste ausgewählt", "noneDescription": "Wähle eine Wiedergabeliste in der Seitenleiste aus, um sie hier anzuzeigen.", "notFoundTitle": "Playlist nicht gefunden", - "notFoundDescription": "Diese Wiedergabeliste ist im aktiven Profil nicht mehr vorhanden." + "notFoundDescription": "Diese Wiedergabeliste ist im aktiven Profil nicht mehr vorhanden.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Zur Wiedergabeliste hinzufügen", @@ -1117,6 +1126,16 @@ "statusRunning": "Aktiv", "statusStopped": "Gestoppt", "copyUrl": "URL kopieren" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Verbinde Spotify Premium mit deiner eigenen Spotify Developer Client-ID.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Füge diese Redirect URI im Spotify Developer Dashboard hinzu: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Verbunden als", + "disconnect": "Trennen", + "connecting": "Verbindung wird hergestellt…", + "connect": "Spotify verbinden" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "WaveFlow öffnen", "quit": "Beenden" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify-Gerät bereit", + "devicePending": "Spotify-Wiedergabe wird vorbereitet…", + "searchPlaceholder": "Spotify durchsuchen", + "tracks": "Titel", + "playlists": "Playlists" } } diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 27451f9..b960886 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Home" + "home": "Home", + "spotify": "Spotify" }, "sections": { "open": "Open", @@ -608,7 +609,8 @@ "slider": "Speed slider", "custom": "Custom speed", "pitchHint": "Pitch tracks speed (no time-stretching)." - } + }, + "seek": "Seek" }, "queue": { "title": "Play queue", @@ -682,7 +684,13 @@ "iconLabel": "Icon", "iconAria": "{{icon}} icon", "submit": "Create", - "editSubmit": "Save" + "editSubmit": "Save", + "coverChoose": "Choose photo", + "coverMenu": "Cover options", + "coverChange": "Change photo", + "coverRemove": "Remove photo", + "coverAutoHint": "Auto cover — updates with the contents", + "coverManualHint": "Custom image" }, "playlistView": { "badge": "Playlist", @@ -705,7 +713,8 @@ "noneTitle": "No playlist selected", "noneDescription": "Select a playlist from the sidebar to view it here.", "notFoundTitle": "Playlist not found", - "notFoundDescription": "This playlist no longer exists in the active profile." + "notFoundDescription": "This playlist no longer exists in the active profile.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Add to a playlist", @@ -1155,6 +1164,16 @@ "statusRunning": "Running", "statusStopped": "Stopped", "copyUrl": "Copy URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Connect Spotify Premium with your own Spotify Developer Client ID.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Add this Redirect URI in Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Connected as", + "disconnect": "Disconnect", + "connecting": "Connecting…", + "connect": "Connect Spotify" } }, "crossfade": { @@ -1355,7 +1374,12 @@ "openSettings": "Open Settings", "notConnectedTitle": "Spotify is not connected", "notConnectedMessage": "Your Client ID is set. Sign in to your Spotify Premium account from Settings to load your playlists and play music.", - "emptyPlaylist": "No tracks available in this playlist (Spotify may not expose local files or playlists you don't own)." + "emptyPlaylist": "No tracks available in this playlist (Spotify may not expose local files or playlists you don't own).", + "deviceReady": "WaveFlow Spotify device ready", + "devicePending": "Preparing Spotify playback…", + "searchPlaceholder": "Search Spotify", + "tracks": "Tracks", + "playlists": "Playlists" }, "scanProgress": { "runningTitle": "Scanning library…", diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index c1cd557..e2cdb7b 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Inicio" + "home": "Inicio", + "spotify": "Spotify" }, "sections": { "open": "Abrir", @@ -600,7 +601,8 @@ "slider": "Control de velocidad", "custom": "Velocidad personalizada", "pitchHint": "El tono sigue la velocidad (sin time-stretching)." - } + }, + "seek": "Posición" }, "queue": { "title": "Cola de reproducción", @@ -674,7 +676,13 @@ "iconLabel": "Icono", "iconAria": "Icono{{icon}}", "submit": "Crear", - "editSubmit": "Guardar" + "editSubmit": "Guardar", + "coverChoose": "Elegir foto", + "coverMenu": "Opciones de portada", + "coverChange": "Cambiar foto", + "coverRemove": "Quitar foto", + "coverAutoHint": "Portada automática — se actualiza con el contenido", + "coverManualHint": "Imagen personalizada" }, "playlistView": { "badge": "Lista de reproducción", @@ -697,7 +705,8 @@ "noneTitle": "No hay ninguna lista de reproducción seleccionada", "noneDescription": "Elige una lista de reproducción en la barra lateral para verla aquí.", "notFoundTitle": "No se encuentra la lista de reproducción", - "notFoundDescription": "Esta lista de reproducción ya no existe en el perfil activo." + "notFoundDescription": "Esta lista de reproducción ya no existe en el perfil activo.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Añadir a una lista de reproducción", @@ -1117,6 +1126,16 @@ "statusRunning": "Activo", "statusStopped": "Detenido", "copyUrl": "Copiar URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Conecta Spotify Premium con tu propio Client ID de Spotify Developer.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Añade este Redirect URI en Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Conectado como", + "disconnect": "Desconectar", + "connecting": "Conectando…", + "connect": "Conectar Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "Abrir WaveFlow", "quit": "Salir" } + }, + "spotify": { + "deviceReady": "Dispositivo Spotify WaveFlow listo", + "devicePending": "Preparando la reproducción de Spotify…", + "searchPlaceholder": "Buscar en Spotify", + "tracks": "Canciones", + "playlists": "Listas" } } diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index fce1c54..b557cd4 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Accueil" + "home": "Accueil", + "spotify": "Spotify" }, "sections": { "open": "Ouvrir", @@ -608,7 +609,8 @@ "slider": "Curseur de vitesse", "custom": "Vitesse personnalisée", "pitchHint": "Le ton suit la vitesse (pas de désynchronisation tonale)." - } + }, + "seek": "Position" }, "queue": { "title": "File de lecture", @@ -682,7 +684,13 @@ "iconLabel": "Icône", "iconAria": "Icône {{icon}}", "submit": "Créer", - "editSubmit": "Enregistrer" + "editSubmit": "Enregistrer", + "coverChoose": "Choisir une photo", + "coverMenu": "Options de pochette", + "coverChange": "Changer la photo", + "coverRemove": "Retirer la photo", + "coverAutoHint": "Cover automatique — se met à jour avec le contenu", + "coverManualHint": "Image personnalisée" }, "playlistView": { "badge": "Playlist", @@ -705,7 +713,8 @@ "noneTitle": "Aucune playlist sélectionnée", "noneDescription": "Choisis une playlist dans la barre latérale pour la voir ici.", "notFoundTitle": "Playlist introuvable", - "notFoundDescription": "Cette playlist n'existe plus dans le profil actif." + "notFoundDescription": "Cette playlist n'existe plus dans le profil actif.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Ajouter à une playlist", @@ -1155,6 +1164,16 @@ "statusRunning": "Actif", "statusStopped": "Arrêté", "copyUrl": "Copier l'URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Connecte Spotify Premium avec ton propre Client ID Spotify Developer.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Ajoute cette Redirect URI dans le Spotify Developer Dashboard : http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Connecté en tant que", + "disconnect": "Déconnecter", + "connecting": "Connexion…", + "connect": "Connecter Spotify" } }, "crossfade": { @@ -1355,7 +1374,12 @@ "openSettings": "Ouvrir les paramètres", "notConnectedTitle": "Spotify n'est pas connecté", "notConnectedMessage": "Ton Client ID est configuré. Connecte ton compte Spotify Premium depuis les Paramètres pour charger tes playlists et lancer la lecture.", - "emptyPlaylist": "Aucune piste lisible dans cette playlist (Spotify peut bloquer les fichiers locaux ou les playlists que tu ne possèdes pas)." + "emptyPlaylist": "Aucune piste lisible dans cette playlist (Spotify peut bloquer les fichiers locaux ou les playlists que tu ne possèdes pas).", + "deviceReady": "Appareil Spotify WaveFlow prêt", + "devicePending": "Préparation de la lecture Spotify…", + "searchPlaceholder": "Rechercher sur Spotify", + "tracks": "Morceaux", + "playlists": "Playlists" }, "scanProgress": { "runningTitle": "Analyse en cours…", diff --git a/src/i18n/locales/hi.json b/src/i18n/locales/hi.json index f35788a..61ae44c 100644 --- a/src/i18n/locales/hi.json +++ b/src/i18n/locales/hi.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "होम" + "home": "होम", + "spotify": "Spotify" }, "sections": { "open": "खोलें", @@ -600,7 +601,8 @@ "slider": "गति स्लाइडर", "custom": "कस्टम गति", "pitchHint": "पिच गति का अनुसरण करती है (कोई टाइम-स्ट्रेचिंग नहीं)।" - } + }, + "seek": "स्थिति" }, "queue": { "title": "प्ले क्यू", @@ -674,7 +676,13 @@ "iconLabel": "चिह्न", "iconAria": "{{icon}} आइकन", "submit": "बनाएँ", - "editSubmit": "बचाएँ" + "editSubmit": "बचाएँ", + "coverChoose": "फ़ोटो चुनें", + "coverMenu": "कवर विकल्प", + "coverChange": "फ़ोटो बदलें", + "coverRemove": "फ़ोटो हटाएँ", + "coverAutoHint": "स्वतः कवर — सामग्री के साथ अपडेट होता है", + "coverManualHint": "कस्टम छवि" }, "playlistView": { "badge": "प्लेलिस्ट", @@ -697,7 +705,8 @@ "noneTitle": "कोई प्लेलिस्ट चयनित नहीं है", "noneDescription": "इसे यहाँ देखने के लिए साइडबार से एक प्लेलिस्ट चुनें।", "notFoundTitle": "प्लेलिस्ट नहीं मिली", - "notFoundDescription": "यह प्लेलिस्ट अब सक्रिय प्रोफ़ाइल में मौजूद नहीं है।" + "notFoundDescription": "यह प्लेलिस्ट अब सक्रिय प्रोफ़ाइल में मौजूद नहीं है।", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "प्लेलिस्ट में जोड़ें", @@ -1117,6 +1126,16 @@ "statusRunning": "चल रहा है", "statusStopped": "रुका हुआ", "copyUrl": "URL कॉपी करें" + }, + "spotify": { + "title": "Spotify", + "subtitle": "अपने Spotify Developer Client ID से Spotify Premium कनेक्ट करें।", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Spotify Developer Dashboard में यह Redirect URI जोड़ें: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "इस रूप में कनेक्ट", + "disconnect": "डिस्कनेक्ट", + "connecting": "कनेक्ट हो रहा है…", + "connect": "Spotify कनेक्ट करें" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "WaveFlow खोलें", "quit": "बंद करें" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify डिवाइस तैयार", + "devicePending": "Spotify प्लेबैक तैयार हो रहा है…", + "searchPlaceholder": "Spotify में खोजें", + "tracks": "ट्रैक", + "playlists": "प्लेलिस्ट" } } diff --git a/src/i18n/locales/id.json b/src/i18n/locales/id.json index b5420b2..007b70d 100644 --- a/src/i18n/locales/id.json +++ b/src/i18n/locales/id.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Beranda" + "home": "Beranda", + "spotify": "Spotify" }, "sections": { "open": "Buka", @@ -600,7 +601,8 @@ "slider": "Penggeser kecepatan", "custom": "Kecepatan kustom", "pitchHint": "Nada mengikuti kecepatan (tanpa time-stretching)." - } + }, + "seek": "Posisi" }, "queue": { "title": "Antrian putar", @@ -674,7 +676,13 @@ "iconLabel": "Ikon", "iconAria": "{{icon}} ikon", "submit": "Buat", - "editSubmit": "Simpan" + "editSubmit": "Simpan", + "coverChoose": "Pilih foto", + "coverMenu": "Opsi sampul", + "coverChange": "Ganti foto", + "coverRemove": "Hapus foto", + "coverAutoHint": "Sampul otomatis — diperbarui mengikuti isi", + "coverManualHint": "Gambar khusus" }, "playlistView": { "badge": "Daftar Putar", @@ -697,7 +705,8 @@ "noneTitle": "Belum ada daftar putar yang dipilih", "noneDescription": "Pilih daftar putar dari bilah samping untuk melihatnya di sini.", "notFoundTitle": "Daftar putar tidak ditemukan", - "notFoundDescription": "Daftar putar ini tidak lagi tersedia di profil aktif." + "notFoundDescription": "Daftar putar ini tidak lagi tersedia di profil aktif.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Tambahkan ke daftar putar", @@ -1117,6 +1126,16 @@ "statusRunning": "Aktif", "statusStopped": "Dihentikan", "copyUrl": "Salin URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Hubungkan Spotify Premium dengan Spotify Developer Client ID milikmu.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Tambahkan Redirect URI ini di Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Terhubung sebagai", + "disconnect": "Putuskan", + "connecting": "Menghubungkan…", + "connect": "Hubungkan Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "Buka WaveFlow", "quit": "Keluar" } + }, + "spotify": { + "deviceReady": "Perangkat Spotify WaveFlow siap", + "devicePending": "Menyiapkan pemutaran Spotify…", + "searchPlaceholder": "Cari di Spotify", + "tracks": "Lagu", + "playlists": "Playlist" } } diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index 1a091ba..fbfd6a3 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Home" + "home": "Home", + "spotify": "Spotify" }, "sections": { "open": "Apri", @@ -600,7 +601,8 @@ "slider": "Cursore velocità", "custom": "Velocità personalizzata", "pitchHint": "L'intonazione segue la velocità (nessun time-stretching)." - } + }, + "seek": "Posizione" }, "queue": { "title": "Coda di riproduzione", @@ -674,7 +676,13 @@ "iconLabel": "Icona", "iconAria": "Icona{{icon}}", "submit": "Crea", - "editSubmit": "Salva" + "editSubmit": "Salva", + "coverChoose": "Scegli foto", + "coverMenu": "Opzioni copertina", + "coverChange": "Cambia foto", + "coverRemove": "Rimuovi foto", + "coverAutoHint": "Copertina automatica — si aggiorna con il contenuto", + "coverManualHint": "Immagine personalizzata" }, "playlistView": { "badge": "Playlist", @@ -697,7 +705,8 @@ "noneTitle": "Nessuna playlist selezionata", "noneDescription": "Scegli una playlist dalla barra laterale per visualizzarla qui.", "notFoundTitle": "Playlist non trovata", - "notFoundDescription": "Questa playlist non è più presente nel profilo attivo." + "notFoundDescription": "Questa playlist non è più presente nel profilo attivo.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Aggiungi a una playlist", @@ -1117,6 +1126,16 @@ "statusRunning": "Attivo", "statusStopped": "Fermo", "copyUrl": "Copia URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Collega Spotify Premium con il tuo Client ID di Spotify Developer.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Aggiungi questo Redirect URI nel Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Connesso come", + "disconnect": "Disconnetti", + "connecting": "Connessione…", + "connect": "Collega Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "Apri WaveFlow", "quit": "Esci" } + }, + "spotify": { + "deviceReady": "Dispositivo Spotify WaveFlow pronto", + "devicePending": "Preparazione della riproduzione Spotify…", + "searchPlaceholder": "Cerca su Spotify", + "tracks": "Brani", + "playlists": "Playlist" } } diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index 77d4014..3890e4a 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "ホーム" + "home": "ホーム", + "spotify": "Spotify" }, "sections": { "open": "開く", @@ -600,7 +601,8 @@ "slider": "速度スライダー", "custom": "カスタム速度", "pitchHint": "ピッチは速度に追従します(タイムストレッチなし)。" - } + }, + "seek": "再生位置" }, "queue": { "title": "再生キュー", @@ -674,7 +676,13 @@ "iconLabel": "アイコン", "iconAria": "{{icon}}のアイコン", "submit": "作成", - "editSubmit": "保存" + "editSubmit": "保存", + "coverChoose": "写真を選ぶ", + "coverMenu": "カバーのオプション", + "coverChange": "写真を変更", + "coverRemove": "写真を削除", + "coverAutoHint": "自動カバー — 内容に合わせて更新されます", + "coverManualHint": "カスタム画像" }, "playlistView": { "badge": "プレイリスト", @@ -697,7 +705,8 @@ "noneTitle": "選択されているプレイリストはありません", "noneDescription": "サイドバーからプレイリストを選んで、ここに表示させてください。", "notFoundTitle": "プレイリストが見つかりません", - "notFoundDescription": "このプレイリストは、現在のプロフィールには存在しません。" + "notFoundDescription": "このプレイリストは、現在のプロフィールには存在しません。", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "プレイリストに追加", @@ -1117,6 +1126,16 @@ "statusRunning": "稼働中", "statusStopped": "停止中", "copyUrl": "URL をコピー" + }, + "spotify": { + "title": "Spotify", + "subtitle": "自分の Spotify Developer Client ID で Spotify Premium に接続します。", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "この Redirect URI を Spotify Developer Dashboard に追加してください: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "接続中:", + "disconnect": "切断", + "connecting": "接続中…", + "connect": "Spotify に接続" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "WaveFlow を開く", "quit": "終了" } + }, + "spotify": { + "deviceReady": "WaveFlow の Spotify デバイスが利用可能です", + "devicePending": "Spotify の再生を準備中…", + "searchPlaceholder": "Spotify を検索", + "tracks": "曲", + "playlists": "プレイリスト" } } diff --git a/src/i18n/locales/kr.json b/src/i18n/locales/kr.json index 524916a..e68d917 100644 --- a/src/i18n/locales/kr.json +++ b/src/i18n/locales/kr.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "홈" + "home": "홈", + "spotify": "Spotify" }, "sections": { "open": "열기", @@ -600,7 +601,8 @@ "slider": "속도 슬라이더", "custom": "사용자 정의 속도", "pitchHint": "피치가 속도를 따라갑니다 (타임 스트레칭 없음)." - } + }, + "seek": "재생 위치" }, "queue": { "title": "재생 대기열", @@ -674,7 +676,13 @@ "iconLabel": "아이콘", "iconAria": "{{icon}} 아이콘", "submit": "만들기", - "editSubmit": "저장" + "editSubmit": "저장", + "coverChoose": "사진 선택", + "coverMenu": "커버 옵션", + "coverChange": "사진 변경", + "coverRemove": "사진 제거", + "coverAutoHint": "자동 커버 — 콘텐츠에 맞게 업데이트됩니다", + "coverManualHint": "사용자 지정 이미지" }, "playlistView": { "badge": "재생 목록", @@ -697,7 +705,8 @@ "noneTitle": "선택된 재생 목록이 없습니다", "noneDescription": "사이드바에서 재생 목록을 선택하면 여기에 표시됩니다.", "notFoundTitle": "재생 목록을 찾을 수 없습니다", - "notFoundDescription": "이 재생 목록은 현재 프로필에서 더 이상 존재하지 않습니다." + "notFoundDescription": "이 재생 목록은 현재 프로필에서 더 이상 존재하지 않습니다.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "재생 목록에 추가", @@ -1117,6 +1126,16 @@ "statusRunning": "실행 중", "statusStopped": "중지됨", "copyUrl": "URL 복사" + }, + "spotify": { + "title": "Spotify", + "subtitle": "자신의 Spotify Developer Client ID로 Spotify Premium에 연결하세요.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "이 Redirect URI를 Spotify Developer Dashboard에 추가하세요: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "연결됨:", + "disconnect": "연결 해제", + "connecting": "연결 중…", + "connect": "Spotify 연결" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "WaveFlow 열기", "quit": "종료" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify 기기 준비 완료", + "devicePending": "Spotify 재생 준비 중…", + "searchPlaceholder": "Spotify 검색", + "tracks": "트랙", + "playlists": "플레이리스트" } } diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json index b5526ac..cc72d07 100644 --- a/src/i18n/locales/nl.json +++ b/src/i18n/locales/nl.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Home" + "home": "Home", + "spotify": "Spotify" }, "sections": { "open": "Openen", @@ -600,7 +601,8 @@ "slider": "Snelheidsschuif", "custom": "Aangepaste snelheid", "pitchHint": "Toonhoogte volgt snelheid (geen time-stretching)." - } + }, + "seek": "Positie" }, "queue": { "title": "Wachtrij afspelen", @@ -674,7 +676,13 @@ "iconLabel": "Pictogram", "iconAria": "Pictogram '{{icon}}'", "submit": "Aanmaken", - "editSubmit": "Opslaan" + "editSubmit": "Opslaan", + "coverChoose": "Foto kiezen", + "coverMenu": "Hoesopties", + "coverChange": "Foto wijzigen", + "coverRemove": "Foto verwijderen", + "coverAutoHint": "Automatische hoes — past zich aan de inhoud aan", + "coverManualHint": "Aangepaste afbeelding" }, "playlistView": { "badge": "Afspeellijst", @@ -697,7 +705,8 @@ "noneTitle": "Er is geen afspeellijst geselecteerd", "noneDescription": "Kies een afspeellijst in de zijbalk om deze hier te bekijken.", "notFoundTitle": "Afspeellijst niet gevonden", - "notFoundDescription": "Deze afspeellijst is niet meer aanwezig in het actieve profiel." + "notFoundDescription": "Deze afspeellijst is niet meer aanwezig in het actieve profiel.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Aan een afspeellijst toevoegen", @@ -1117,6 +1126,16 @@ "statusRunning": "Actief", "statusStopped": "Gestopt", "copyUrl": "URL kopiëren" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Verbind Spotify Premium met je eigen Spotify Developer Client ID.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Voeg deze Redirect URI toe in Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Verbonden als", + "disconnect": "Verbinding verbreken", + "connecting": "Verbinden…", + "connect": "Spotify verbinden" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "WaveFlow openen", "quit": "Afsluiten" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify-apparaat klaar", + "devicePending": "Spotify-weergave voorbereiden…", + "searchPlaceholder": "Spotify doorzoeken", + "tracks": "Nummers", + "playlists": "Afspeellijsten" } } diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json index 75120e1..e3380c5 100644 --- a/src/i18n/locales/pt-BR.json +++ b/src/i18n/locales/pt-BR.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Página inicial" + "home": "Página inicial", + "spotify": "Spotify" }, "sections": { "open": "Abrir", @@ -600,7 +601,8 @@ "slider": "Controle de velocidade", "custom": "Velocidade personalizada", "pitchHint": "O tom acompanha a velocidade (sem time-stretching)." - } + }, + "seek": "Posição" }, "queue": { "title": "Fila de reprodução", @@ -674,7 +676,13 @@ "iconLabel": "Ícone", "iconAria": "Ícone{{icon}}", "submit": "Criar", - "editSubmit": "Salvar" + "editSubmit": "Salvar", + "coverChoose": "Escolher foto", + "coverMenu": "Opções de capa", + "coverChange": "Trocar foto", + "coverRemove": "Remover foto", + "coverAutoHint": "Capa automática — atualiza com o conteúdo", + "coverManualHint": "Imagem personalizada" }, "playlistView": { "badge": "Lista de reprodução", @@ -697,7 +705,8 @@ "noneTitle": "Nenhuma lista de reprodução selecionada", "noneDescription": "Escolha uma lista de reprodução na barra lateral para visualizá-la aqui.", "notFoundTitle": "Playlist não encontrada", - "notFoundDescription": "Essa lista de reprodução não existe mais no perfil ativo." + "notFoundDescription": "Essa lista de reprodução não existe mais no perfil ativo.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Adicionar a uma lista de reprodução", @@ -1117,6 +1126,16 @@ "statusRunning": "Ativo", "statusStopped": "Parado", "copyUrl": "Copiar URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Conecte o Spotify Premium com seu próprio Client ID do Spotify Developer.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Adicione este Redirect URI no Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Conectado como", + "disconnect": "Desconectar", + "connecting": "Conectando…", + "connect": "Conectar Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "Abrir WaveFlow", "quit": "Sair" } + }, + "spotify": { + "deviceReady": "Dispositivo Spotify do WaveFlow pronto", + "devicePending": "Preparando a reprodução do Spotify…", + "searchPlaceholder": "Pesquisar no Spotify", + "tracks": "Faixas", + "playlists": "Playlists" } } diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json index 495ef5a..3cf2973 100644 --- a/src/i18n/locales/pt.json +++ b/src/i18n/locales/pt.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Página inicial" + "home": "Página inicial", + "spotify": "Spotify" }, "sections": { "open": "Abrir", @@ -600,7 +601,8 @@ "slider": "Cursor de velocidade", "custom": "Velocidade personalizada", "pitchHint": "O tom acompanha a velocidade (sem time-stretching)." - } + }, + "seek": "Posição" }, "queue": { "title": "Fila de reprodução", @@ -674,7 +676,13 @@ "iconLabel": "Ícone", "iconAria": "Ícone {{icon}}", "submit": "Criar", - "editSubmit": "Guardar" + "editSubmit": "Guardar", + "coverChoose": "Escolher foto", + "coverMenu": "Opções de capa", + "coverChange": "Mudar foto", + "coverRemove": "Remover foto", + "coverAutoHint": "Capa automática — atualiza com o conteúdo", + "coverManualHint": "Imagem personalizada" }, "playlistView": { "badge": "Lista de reprodução", @@ -697,7 +705,8 @@ "noneTitle": "Nenhuma lista de reprodução selecionada", "noneDescription": "Escolhe uma lista de reprodução na barra lateral para a veres aqui.", "notFoundTitle": "Lista de reprodução não encontrada", - "notFoundDescription": "Esta lista de reprodução já não existe no perfil ativo." + "notFoundDescription": "Esta lista de reprodução já não existe no perfil ativo.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Adicionar a uma lista de reprodução", @@ -1117,6 +1126,16 @@ "statusRunning": "Ativo", "statusStopped": "Parado", "copyUrl": "Copiar URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Liga o Spotify Premium com o teu próprio Client ID do Spotify Developer.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Adiciona este Redirect URI no Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Ligado como", + "disconnect": "Desligar", + "connecting": "A ligar…", + "connect": "Ligar Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "Abrir WaveFlow", "quit": "Sair" } + }, + "spotify": { + "deviceReady": "Dispositivo Spotify WaveFlow pronto", + "devicePending": "A preparar a reprodução do Spotify…", + "searchPlaceholder": "Pesquisar no Spotify", + "tracks": "Faixas", + "playlists": "Playlists" } } diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index c6d3e25..2ea19c3 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Главная" + "home": "Главная", + "spotify": "Spotify" }, "sections": { "open": "Открыть", @@ -600,7 +601,8 @@ "slider": "Ползунок скорости", "custom": "Своя скорость", "pitchHint": "Высота тона следует за скоростью (без time-stretching)." - } + }, + "seek": "Перемотка" }, "queue": { "title": "Очередь воспроизведения", @@ -674,7 +676,13 @@ "iconLabel": "Значок", "iconAria": "{{icon}} значок", "submit": "Создать", - "editSubmit": "Сохранить" + "editSubmit": "Сохранить", + "coverChoose": "Выбрать фото", + "coverMenu": "Параметры обложки", + "coverChange": "Изменить фото", + "coverRemove": "Удалить фото", + "coverAutoHint": "Авто-обложка — обновляется вместе с содержимым", + "coverManualHint": "Своё изображение" }, "playlistView": { "badge": "Плейлист", @@ -697,7 +705,8 @@ "noneTitle": "Плейлист не выбран", "noneDescription": "Выберите плейлист в боковой панели, чтобы просмотреть его здесь.", "notFoundTitle": "Плейлист не найден", - "notFoundDescription": "Этот плейлист больше не существует в активном профиле." + "notFoundDescription": "Этот плейлист больше не существует в активном профиле.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Добавить в плейлист", @@ -1117,6 +1126,16 @@ "statusRunning": "Активен", "statusStopped": "Остановлен", "copyUrl": "Скопировать URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Подключи Spotify Premium со своим Spotify Developer Client ID.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Добавь этот Redirect URI в Spotify Developer Dashboard: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Подключено как", + "disconnect": "Отключить", + "connecting": "Подключение…", + "connect": "Подключить Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "Открыть WaveFlow", "quit": "Выйти" } + }, + "spotify": { + "deviceReady": "Устройство Spotify WaveFlow готово", + "devicePending": "Подготовка воспроизведения Spotify…", + "searchPlaceholder": "Искать в Spotify", + "tracks": "Треки", + "playlists": "Плейлисты" } } diff --git a/src/i18n/locales/tr.json b/src/i18n/locales/tr.json index 8b80080..b89fd75 100644 --- a/src/i18n/locales/tr.json +++ b/src/i18n/locales/tr.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "Ana Sayfa" + "home": "Ana Sayfa", + "spotify": "Spotify" }, "sections": { "open": "Aç", @@ -600,7 +601,8 @@ "slider": "Hız kaydırıcısı", "custom": "Özel hız", "pitchHint": "Perde hızla birlikte değişir (time-stretching yok)." - } + }, + "seek": "İlerleme" }, "queue": { "title": "Oynatma kuyruğu", @@ -674,7 +676,13 @@ "iconLabel": "Simge", "iconAria": "{{icon}} simge", "submit": "Oluştur", - "editSubmit": "Kaydet" + "editSubmit": "Kaydet", + "coverChoose": "Fotoğraf seç", + "coverMenu": "Kapak seçenekleri", + "coverChange": "Fotoğrafı değiştir", + "coverRemove": "Fotoğrafı kaldır", + "coverAutoHint": "Otomatik kapak — içerikle birlikte güncellenir", + "coverManualHint": "Özel görsel" }, "playlistView": { "badge": "Çalma listesi", @@ -697,7 +705,8 @@ "noneTitle": "Hiçbir çalma listesi seçilmedi", "noneDescription": "Yan çubuktan bir çalma listesi seçin ve burada görüntüleyin.", "notFoundTitle": "Çalma listesi bulunamadı", - "notFoundDescription": "Bu çalma listesi artık aktif profilde mevcut değil." + "notFoundDescription": "Bu çalma listesi artık aktif profilde mevcut değil.", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "Çalma listesine ekle", @@ -1117,6 +1126,16 @@ "statusRunning": "Çalışıyor", "statusStopped": "Durduruldu", "copyUrl": "URL kopyala" + }, + "spotify": { + "title": "Spotify", + "subtitle": "Spotify Premium'u kendi Spotify Developer Client ID'nle bağla.", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "Bu Redirect URI'yi Spotify Developer Dashboard'a ekle: http://127.0.0.1:49387/spotify/callback", + "connectedAs": "Bağlı kullanıcı:", + "disconnect": "Bağlantıyı kes", + "connecting": "Bağlanıyor…", + "connect": "Spotify'a bağlan" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "WaveFlow'u aç", "quit": "Çık" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify cihazı hazır", + "devicePending": "Spotify çalma hazırlanıyor…", + "searchPlaceholder": "Spotify'da ara", + "tracks": "Parçalar", + "playlists": "Çalma listeleri" } } diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 82c7bcf..086c7a0 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "首页" + "home": "首页", + "spotify": "Spotify" }, "sections": { "open": "打开", @@ -600,7 +601,8 @@ "slider": "速度滑块", "custom": "自定义速度", "pitchHint": "音高随速度变化(无时间拉伸)。" - } + }, + "seek": "播放位置" }, "queue": { "title": "播放列表", @@ -674,7 +676,13 @@ "iconLabel": "图标", "iconAria": "{{icon}} 图标", "submit": "创建", - "editSubmit": "保存" + "editSubmit": "保存", + "coverChoose": "选择照片", + "coverMenu": "封面选项", + "coverChange": "更换照片", + "coverRemove": "移除照片", + "coverAutoHint": "自动封面 — 随内容自动更新", + "coverManualHint": "自定义图片" }, "playlistView": { "badge": "播放列表", @@ -697,7 +705,8 @@ "noneTitle": "未选择任何播放列表", "noneDescription": "在侧边栏中选择一个播放列表,即可在此处查看。", "notFoundTitle": "找不到播放列表", - "notFoundDescription": "该播放列表在当前个人资料中已不存在。" + "notFoundDescription": "该播放列表在当前个人资料中已不存在。", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "添加到播放列表", @@ -1117,6 +1126,16 @@ "statusRunning": "运行中", "statusStopped": "已停止", "copyUrl": "复制 URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "使用你自己的 Spotify Developer Client ID 连接 Spotify Premium。", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "在 Spotify Developer Dashboard 中添加此 Redirect URI:http://127.0.0.1:49387/spotify/callback", + "connectedAs": "已连接为", + "disconnect": "断开连接", + "connecting": "正在连接…", + "connect": "连接 Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "打开 WaveFlow", "quit": "退出" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify 设备已就绪", + "devicePending": "正在准备 Spotify 播放…", + "searchPlaceholder": "搜索 Spotify", + "tracks": "曲目", + "playlists": "播放列表" } } diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index 00305be..e9cf6c9 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -54,7 +54,8 @@ }, "sidebar": { "nav": { - "home": "首頁" + "home": "首頁", + "spotify": "Spotify" }, "sections": { "open": "開啟", @@ -600,7 +601,8 @@ "slider": "速度滑桿", "custom": "自訂速度", "pitchHint": "音高隨速度變化(無時間拉伸)。" - } + }, + "seek": "播放位置" }, "queue": { "title": "播放佇列", @@ -674,7 +676,13 @@ "iconLabel": "圖示", "iconAria": "{{icon}} 圖示", "submit": "建立", - "editSubmit": "儲存" + "editSubmit": "儲存", + "coverChoose": "選擇照片", + "coverMenu": "封面選項", + "coverChange": "更換照片", + "coverRemove": "移除照片", + "coverAutoHint": "自動封面 — 隨內容自動更新", + "coverManualHint": "自訂圖片" }, "playlistView": { "badge": "播放清單", @@ -697,7 +705,8 @@ "noneTitle": "尚未選取任何播放清單", "noneDescription": "請在側邊欄中選擇一個播放清單,即可在此處查看。", "notFoundTitle": "找不到播放清單", - "notFoundDescription": "此播放清單在該活躍帳戶中已不存在。" + "notFoundDescription": "此播放清單在該活躍帳戶中已不存在。", + "smartLabel": "Daily Mix" }, "trackActions": { "addToPlaylist": "加入播放清單", @@ -1117,6 +1126,16 @@ "statusRunning": "執行中", "statusStopped": "已停止", "copyUrl": "複製 URL" + }, + "spotify": { + "title": "Spotify", + "subtitle": "使用你自己的 Spotify Developer Client ID 連接 Spotify Premium。", + "clientIdPlaceholder": "Spotify Client ID", + "redirectHint": "在 Spotify Developer Dashboard 中加入此 Redirect URI:http://127.0.0.1:49387/spotify/callback", + "connectedAs": "已連接為", + "disconnect": "中斷連線", + "connecting": "正在連接…", + "connect": "連接 Spotify" } }, "crossfade": { @@ -1296,5 +1315,12 @@ "show": "開啟 WaveFlow", "quit": "結束" } + }, + "spotify": { + "deviceReady": "WaveFlow Spotify 裝置已就緒", + "devicePending": "正在準備 Spotify 播放…", + "searchPlaceholder": "搜尋 Spotify", + "tracks": "曲目", + "playlists": "播放清單" } } From fe3aa197e8422724a7fca5b54fb7b382c68668a5 Mon Sep 17 00:00:00 2001 From: InstaZDLL Date: Sat, 16 May 2026 16:33:57 +0200 Subject: [PATCH 3/3] fix(locale): add missing spotify.emptyPlaylist key to 15 locales The key was only declared in en and fr; the other 15 locales fell back to English. Addresses coderabbit review on #32. --- src/i18n/locales/ar.json | 3 ++- src/i18n/locales/de.json | 3 ++- src/i18n/locales/es.json | 3 ++- src/i18n/locales/hi.json | 3 ++- src/i18n/locales/id.json | 3 ++- src/i18n/locales/it.json | 3 ++- src/i18n/locales/ja.json | 3 ++- src/i18n/locales/kr.json | 3 ++- src/i18n/locales/nl.json | 3 ++- src/i18n/locales/pt-BR.json | 3 ++- src/i18n/locales/pt.json | 3 ++- src/i18n/locales/ru.json | 3 ++- src/i18n/locales/tr.json | 3 ++- src/i18n/locales/zh-CN.json | 3 ++- src/i18n/locales/zh-TW.json | 3 ++- 15 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json index b6350b3..f5eae8f 100644 --- a/src/i18n/locales/ar.json +++ b/src/i18n/locales/ar.json @@ -1321,6 +1321,7 @@ "devicePending": "جارٍ تحضير تشغيل Spotify…", "searchPlaceholder": "البحث في Spotify", "tracks": "المقطوعات", - "playlists": "قوائم التشغيل" + "playlists": "قوائم التشغيل", + "emptyPlaylist": "لا توجد مقطوعات متاحة في قائمة التشغيل هذه (قد لا يعرض Spotify الملفات المحلية أو قوائم التشغيل التي لا تملكها)." } } diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index f9d36af..12c59d3 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -1321,6 +1321,7 @@ "devicePending": "Spotify-Wiedergabe wird vorbereitet…", "searchPlaceholder": "Spotify durchsuchen", "tracks": "Titel", - "playlists": "Playlists" + "playlists": "Playlists", + "emptyPlaylist": "Keine abspielbaren Titel in dieser Playlist (Spotify blendet lokale Dateien oder Playlists, die dir nicht gehören, möglicherweise aus)." } } diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index e2cdb7b..82114e7 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -1321,6 +1321,7 @@ "devicePending": "Preparando la reproducción de Spotify…", "searchPlaceholder": "Buscar en Spotify", "tracks": "Canciones", - "playlists": "Listas" + "playlists": "Listas", + "emptyPlaylist": "No hay pistas disponibles en esta lista (Spotify puede no exponer los archivos locales o las playlists que no son tuyas)." } } diff --git a/src/i18n/locales/hi.json b/src/i18n/locales/hi.json index 61ae44c..014e44e 100644 --- a/src/i18n/locales/hi.json +++ b/src/i18n/locales/hi.json @@ -1321,6 +1321,7 @@ "devicePending": "Spotify प्लेबैक तैयार हो रहा है…", "searchPlaceholder": "Spotify में खोजें", "tracks": "ट्रैक", - "playlists": "प्लेलिस्ट" + "playlists": "प्लेलिस्ट", + "emptyPlaylist": "इस प्लेलिस्ट में कोई ट्रैक उपलब्ध नहीं है (Spotify स्थानीय फ़ाइलें या आपकी न होने वाली प्लेलिस्ट दिखाने से रोक सकता है)।" } } diff --git a/src/i18n/locales/id.json b/src/i18n/locales/id.json index 007b70d..99bad68 100644 --- a/src/i18n/locales/id.json +++ b/src/i18n/locales/id.json @@ -1321,6 +1321,7 @@ "devicePending": "Menyiapkan pemutaran Spotify…", "searchPlaceholder": "Cari di Spotify", "tracks": "Lagu", - "playlists": "Playlist" + "playlists": "Playlist", + "emptyPlaylist": "Tidak ada lagu yang tersedia di playlist ini (Spotify mungkin tidak menampilkan file lokal atau playlist yang bukan milikmu)." } } diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index fbfd6a3..0aff270 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -1321,6 +1321,7 @@ "devicePending": "Preparazione della riproduzione Spotify…", "searchPlaceholder": "Cerca su Spotify", "tracks": "Brani", - "playlists": "Playlist" + "playlists": "Playlist", + "emptyPlaylist": "Nessuna traccia disponibile in questa playlist (Spotify potrebbe non esporre i file locali o le playlist che non possiedi)." } } diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index 3890e4a..0815bcb 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -1321,6 +1321,7 @@ "devicePending": "Spotify の再生を準備中…", "searchPlaceholder": "Spotify を検索", "tracks": "曲", - "playlists": "プレイリスト" + "playlists": "プレイリスト", + "emptyPlaylist": "このプレイリストには再生可能な曲がありません(Spotify はローカルファイルや所有していないプレイリストを公開しないことがあります)。" } } diff --git a/src/i18n/locales/kr.json b/src/i18n/locales/kr.json index e68d917..678f2b8 100644 --- a/src/i18n/locales/kr.json +++ b/src/i18n/locales/kr.json @@ -1321,6 +1321,7 @@ "devicePending": "Spotify 재생 준비 중…", "searchPlaceholder": "Spotify 검색", "tracks": "트랙", - "playlists": "플레이리스트" + "playlists": "플레이리스트", + "emptyPlaylist": "이 플레이리스트에서 재생할 수 있는 트랙이 없습니다 (Spotify가 로컬 파일이나 본인 소유가 아닌 플레이리스트를 노출하지 않을 수 있습니다)." } } diff --git a/src/i18n/locales/nl.json b/src/i18n/locales/nl.json index cc72d07..2c78f90 100644 --- a/src/i18n/locales/nl.json +++ b/src/i18n/locales/nl.json @@ -1321,6 +1321,7 @@ "devicePending": "Spotify-weergave voorbereiden…", "searchPlaceholder": "Spotify doorzoeken", "tracks": "Nummers", - "playlists": "Afspeellijsten" + "playlists": "Afspeellijsten", + "emptyPlaylist": "Geen beschikbare nummers in deze afspeellijst (Spotify toont lokale bestanden of afspeellijsten die je niet bezit mogelijk niet)." } } diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json index e3380c5..de786da 100644 --- a/src/i18n/locales/pt-BR.json +++ b/src/i18n/locales/pt-BR.json @@ -1321,6 +1321,7 @@ "devicePending": "Preparando a reprodução do Spotify…", "searchPlaceholder": "Pesquisar no Spotify", "tracks": "Faixas", - "playlists": "Playlists" + "playlists": "Playlists", + "emptyPlaylist": "Sem faixas disponíveis nesta playlist (o Spotify pode não expor arquivos locais ou playlists que você não possui)." } } diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json index 3cf2973..a30fe22 100644 --- a/src/i18n/locales/pt.json +++ b/src/i18n/locales/pt.json @@ -1321,6 +1321,7 @@ "devicePending": "A preparar a reprodução do Spotify…", "searchPlaceholder": "Pesquisar no Spotify", "tracks": "Faixas", - "playlists": "Playlists" + "playlists": "Playlists", + "emptyPlaylist": "Sem faixas disponíveis nesta playlist (o Spotify pode não expor ficheiros locais ou playlists que não possuis)." } } diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 2ea19c3..d0b0139 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -1321,6 +1321,7 @@ "devicePending": "Подготовка воспроизведения Spotify…", "searchPlaceholder": "Искать в Spotify", "tracks": "Треки", - "playlists": "Плейлисты" + "playlists": "Плейлисты", + "emptyPlaylist": "В этом плейлисте нет доступных треков (Spotify может не отдавать локальные файлы или чужие плейлисты)." } } diff --git a/src/i18n/locales/tr.json b/src/i18n/locales/tr.json index b89fd75..4d542cf 100644 --- a/src/i18n/locales/tr.json +++ b/src/i18n/locales/tr.json @@ -1321,6 +1321,7 @@ "devicePending": "Spotify çalma hazırlanıyor…", "searchPlaceholder": "Spotify'da ara", "tracks": "Parçalar", - "playlists": "Çalma listeleri" + "playlists": "Çalma listeleri", + "emptyPlaylist": "Bu çalma listesinde kullanılabilir parça yok (Spotify yerel dosyaları veya sahibi olmadığın listeleri göstermeyebilir)." } } diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 086c7a0..e5a0bea 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -1321,6 +1321,7 @@ "devicePending": "正在准备 Spotify 播放…", "searchPlaceholder": "搜索 Spotify", "tracks": "曲目", - "playlists": "播放列表" + "playlists": "播放列表", + "emptyPlaylist": "此播放列表中没有可用的曲目(Spotify 可能不会公开本地文件或非你拥有的播放列表)。" } } diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index e9cf6c9..ca81c95 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -1321,6 +1321,7 @@ "devicePending": "正在準備 Spotify 播放…", "searchPlaceholder": "搜尋 Spotify", "tracks": "曲目", - "playlists": "播放清單" + "playlists": "播放清單", + "emptyPlaylist": "此播放清單中沒有可用的曲目(Spotify 可能不會公開本機檔案或非你擁有的播放清單)。" } }