diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-24 17:39:41 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-24 17:39:41 +0200 |
| commit | 8c780b9928db8145b7fe18ecd137384ccfe25d8f (patch) | |
| tree | 5cfc06eec0fdf9bb7fe0a14f45e3ef803bb86a20 /packages/meshbay-hub/src/meshbay_hub/static/locales | |
| parent | 941d1a135dd7b03834576855e8e9fdaa24c4e406 (diff) | |
| download | meshbay-8c780b9928db8145b7fe18ecd137384ccfe25d8f.tar.gz | |
feat(hub): Music app client — album grid, flat list, persistent player
Implements the client half of docs/musicbay.md against MNP 0.8:
- music-app.js: album grid (grouped by artist -> album, from index-time
artist/album fields) or flat folder view, per-group localStorage
toggle like Videos. MusicBrainz (music_meta_req) is only looked up
when a track has no embedded cover at all — well-tagged files never
trigger a network call, unlike Videos where TMDB is unconditional.
Reuses video-app.js's MediaThumb/LazyTile (now exported) rather than
duplicating the chunk-path thumbnail decode + virtualization.
- music-player.js: the persistent player bar — queue, shuffle (Fisher-
Yates, keeps the current track in place when toggled), repeat (off/
all/one), volume (localStorage), prev/next, a one-track prefetch
cache. No MSE, no node-side streaming: a track is downloaded and
decrypted once via file-utils.js's pipelinedDownload, same chunk
pipeline Files already uses, then played from a blob URL.
- group-page.js: owns musicQueue/musicbrainzConfig state and renders
MusicPlayerBar outside the tab-switched area — deliberately, so
playback survives navigating to Chat/Files, the same reasoning the
video/preview modals are shell-owned rather than app-owned.
- apps.js: registers "music". transport.js: fetchMusicMeta (keyed by
path, same reordering-hazard fix as fetchMediaMeta),
setMusicbrainzConfig/setMusicbrainzEnabled (signed ops, mirroring
TMDB's), and the three new ack handlers. group-settings.js: a
MusicBrainz settings section (contact string, per-group toggle) —
the existing Applications checklist already picks up "music" for
free, per apps.md's own claim.
- icon.js: music/pause/skip-next/skip-prev/shuffle/repeat/volume,
drawn in the same stroked style as the existing set.
- i18n: group.tab_music, the music.* and settings_node.musicbrainz_*
keys, translated (not just copied) across all ten locales, Polish
carrying full one/few/many/other plural forms for music.n_tracks.
- webapp.py's _ASSETS, test_hook_ordering.py's STATIC_FILES and
test_transport_contracts.py's SPLIT_FILES gain the two new files.
Full suite (common + hub + node): 1116 passed, no regressions.
`npm run sync-ui` in meshbay-client confirmed both files copied.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KBi7ALLGfwcjBXt57yNMcy
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/locales')
10 files changed, 312 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js index 7f05441..cb542a6 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js @@ -77,6 +77,7 @@ export default { 'group.tab_files': 'Dateien', 'group.tab_chat': 'Chat', 'group.tab_video': 'Videos', + 'group.tab_music': 'Musik', 'group.tab_members': 'Mitglieder', 'group.tab_settings': "Einstellungen", 'members.danger_leave_hint': "Sie verlieren den Zugriff auf die Dateien und den Chat dieser Gruppe.", @@ -176,6 +177,27 @@ export default { 'video.search_no_results': 'Keine Treffer gefunden.', 'video.search_apply_hint': 'Gilt für alle Dateien, die derzeit unter diesem Titel gruppiert sind.', + // Musik + 'music.mode_grid': 'Alben', + 'music.mode_flat': 'Flache Liste', + 'music.empty': 'Keine Musik gefunden.', + 'music.unknown_album': 'Unbekanntes Album', + 'music.play_all': 'Alle abspielen', + 'music.n_tracks': { + one: '{n} Titel', + other: '{n} Titel', + }, + 'music.err_transport': 'Transport nicht verbunden', + 'music.player_play': 'Abspielen', + 'music.player_pause': 'Pause', + 'music.player_prev': 'Vorheriger', + 'music.player_next': 'Nächster', + 'music.player_shuffle': 'Zufallswiedergabe', + 'music.player_repeat_off': 'Wiederholung aus', + 'music.player_repeat_all': 'Alle wiederholen', + 'music.player_repeat_one': 'Einzelnen wiederholen', + 'music.player_volume': 'Lautstärke', + // LAN-Cast 'cast.start': 'Auf Gerät übertragen', 'cast.stop': 'Übertragung beenden', @@ -605,6 +627,15 @@ export default { 'settings_node.video_root_title': 'Videos-Stammordner', 'settings_node.video_root_hint': 'Welcher Ordner (oder Unterordner) als Einstiegspunkt der Videos-App für diese Gruppe dient. In Videos wird nichts angezeigt, und es werden keine TMDB-Abfragen ausgeführt, bis einer ausgewählt wurde.', 'settings_node.video_root_none': '— keiner ausgewählt —', + 'settings_node.musicbrainz_title': 'MusicBrainz-Metadaten', + 'settings_node.musicbrainz_hint': 'Ermöglicht der Musik-App, Cover und kanonische Benennungen von MusicBrainz anzuzeigen, wenn ein Titel kein brauchbares eingebettetes Cover hat. Aus bedeutet nur Tag-/Dateiname-basiertes Durchsuchen, ohne Anfrage an Dritte.', + 'settings_node.musicbrainz_enabled': 'Aktiviert', + 'settings_node.musicbrainz_disabled': 'Deaktiviert', + 'settings_node.musicbrainz_contact_label': 'Kontakt (erforderlich, damit MusicBrainz antwortet)', + 'settings_node.musicbrainz_contact_placeholder': 'du@beispiel.de oder eine Projekt-URL', + 'settings_node.musicbrainz_contact_set': 'Ein Kontakt ist konfiguriert.', + 'settings_node.musicbrainz_contact_unset': 'Kein Kontakt konfiguriert — MusicBrainz-Abfragen bleiben deaktiviert, bis einer festgelegt ist.', + 'settings_node.musicbrainz_save': 'Speichern', 'settings_node.video_root_save': 'Speichern', 'settings_node.video_root_change_confirm': 'Das Ändern des Videos-Stammordners ersetzt, was jedes Mitglied im Videos-Tab sieht. Fortfahren?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js index 7f31bb5..e05b398 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js @@ -78,6 +78,7 @@ export default { 'group.tab_files': 'Files', 'group.tab_chat': 'Chat', 'group.tab_video': 'Videos', + 'group.tab_music': 'Music', 'group.tab_members': 'Members', 'group.tab_settings': "Settings", 'members.danger_leave_hint': "You will lose access to this group's files and chat.", @@ -174,6 +175,27 @@ export default { 'video.search_no_results': 'No matches found.', 'video.search_apply_hint': 'Applies to every file currently grouped under this title.', + // Music + 'music.mode_grid': 'Albums', + 'music.mode_flat': 'Flat list', + 'music.empty': 'No music found.', + 'music.unknown_album': 'Unknown album', + 'music.play_all': 'Play all', + 'music.n_tracks': { + one: '{n} track', + other: '{n} tracks', + }, + 'music.err_transport': 'Transport not connected', + 'music.player_play': 'Play', + 'music.player_pause': 'Pause', + 'music.player_prev': 'Previous', + 'music.player_next': 'Next', + 'music.player_shuffle': 'Shuffle', + 'music.player_repeat_off': 'Repeat off', + 'music.player_repeat_all': 'Repeat all', + 'music.player_repeat_one': 'Repeat one', + 'music.player_volume': 'Volume', + // LAN cast 'cast.start': 'Cast to device', 'cast.stop': 'Stop casting', @@ -430,6 +452,15 @@ export default { 'settings_node.video_root_title': 'Videos root folder', 'settings_node.video_root_hint': 'Which folder (or subfolder) the Videos app treats as its entry point for this group. Nothing shows in Videos, and no TMDB lookups run, until one is chosen.', 'settings_node.video_root_none': '— none chosen —', + 'settings_node.musicbrainz_title': 'MusicBrainz metadata', + 'settings_node.musicbrainz_hint': 'Lets the Music app show cover art and canonical naming from MusicBrainz when a track has no usable embedded cover. Off means tag/filename-only browsing, with no request to a third party.', + 'settings_node.musicbrainz_enabled': 'Enabled', + 'settings_node.musicbrainz_disabled': 'Disabled', + 'settings_node.musicbrainz_contact_label': 'Contact (required for MusicBrainz to answer requests)', + 'settings_node.musicbrainz_contact_placeholder': 'you@example.com or a project URL', + 'settings_node.musicbrainz_contact_set': 'A contact is configured.', + 'settings_node.musicbrainz_contact_unset': 'No contact configured — MusicBrainz lookups stay off until one is set.', + 'settings_node.musicbrainz_save': 'Save', 'settings_node.video_root_save': 'Save', 'settings_node.video_root_change_confirm': 'Changing the Videos root replaces what every member sees in the Videos tab. Continue?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js index d7f0f1e..113ae7a 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js @@ -75,6 +75,7 @@ export default { 'group.tab_files': 'Archivos', 'group.tab_chat': 'Chat', 'group.tab_video': 'Vídeos', + 'group.tab_music': 'Música', 'group.tab_members': 'Miembros', 'group.tab_settings': "Ajustes", 'members.danger_leave_hint': "Perderá el acceso a los archivos y al chat de este grupo.", @@ -174,6 +175,27 @@ export default { 'video.search_no_results': 'No se encontraron coincidencias.', 'video.search_apply_hint': 'Se aplica a todos los archivos agrupados actualmente bajo este título.', + // Música + 'music.mode_grid': 'Álbumes', + 'music.mode_flat': 'Lista plana', + 'music.empty': 'No se encontró música.', + 'music.unknown_album': 'Álbum desconocido', + 'music.play_all': 'Reproducir todo', + 'music.n_tracks': { + one: '{n} pista', + other: '{n} pistas', + }, + 'music.err_transport': 'Transporte no conectado', + 'music.player_play': 'Reproducir', + 'music.player_pause': 'Pausa', + 'music.player_prev': 'Anterior', + 'music.player_next': 'Siguiente', + 'music.player_shuffle': 'Aleatorio', + 'music.player_repeat_off': 'Repetición desactivada', + 'music.player_repeat_all': 'Repetir todo', + 'music.player_repeat_one': 'Repetir una', + 'music.player_volume': 'Volumen', + // LAN cast 'cast.start': 'Enviar a dispositivo', 'cast.stop': 'Detener envío', @@ -600,6 +622,15 @@ export default { 'settings_node.video_root_title': 'Carpeta raíz de Vídeos', 'settings_node.video_root_hint': 'Qué carpeta (o subcarpeta) trata la app Vídeos como su punto de entrada para este grupo. No se muestra nada en Vídeos, ni se realizan búsquedas en TMDB, hasta que se elija una.', 'settings_node.video_root_none': '— ninguna elegida —', + 'settings_node.musicbrainz_title': 'Metadatos de MusicBrainz', + 'settings_node.musicbrainz_hint': 'Permite que la app de Música muestre carátulas y nombres canónicos de MusicBrainz cuando una pista no tiene una carátula incrustada utilizable. Desactivado significa navegación solo por etiquetas/nombre de archivo, sin solicitudes a terceros.', + 'settings_node.musicbrainz_enabled': 'Activado', + 'settings_node.musicbrainz_disabled': 'Desactivado', + 'settings_node.musicbrainz_contact_label': 'Contacto (necesario para que MusicBrainz responda)', + 'settings_node.musicbrainz_contact_placeholder': 'tu@ejemplo.com o una URL de proyecto', + 'settings_node.musicbrainz_contact_set': 'Hay un contacto configurado.', + 'settings_node.musicbrainz_contact_unset': 'Sin contacto configurado — las búsquedas de MusicBrainz permanecen desactivadas hasta que se configure uno.', + 'settings_node.musicbrainz_save': 'Guardar', 'settings_node.video_root_save': 'Guardar', 'settings_node.video_root_change_confirm': 'Cambiar la raíz de Vídeos reemplaza lo que ve cada miembro en la pestaña Vídeos. ¿Continuar?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js index 2befdb9..6a57174 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js @@ -76,6 +76,7 @@ export default { 'group.tab_files': 'Fichiers', 'group.tab_chat': 'Discussion', 'group.tab_video': 'Vidéos', + 'group.tab_music': 'Musique', 'group.tab_members': 'Membres', 'group.tab_settings': "Paramètres", 'members.danger_leave_hint': "Vous perdrez l’accès aux fichiers et à la discussion de ce groupe.", @@ -175,6 +176,27 @@ export default { 'video.search_no_results': 'Aucune correspondance trouvée.', 'video.search_apply_hint': 'S’applique à tous les fichiers actuellement regroupés sous ce titre.', + // Musique + 'music.mode_grid': 'Albums', + 'music.mode_flat': 'Liste à plat', + 'music.empty': 'Aucune musique trouvée.', + 'music.unknown_album': 'Album inconnu', + 'music.play_all': 'Tout lire', + 'music.n_tracks': { + one: '{n} piste', + other: '{n} pistes', + }, + 'music.err_transport': 'Transport non connecté', + 'music.player_play': 'Lecture', + 'music.player_pause': 'Pause', + 'music.player_prev': 'Précédent', + 'music.player_next': 'Suivant', + 'music.player_shuffle': 'Lecture aléatoire', + 'music.player_repeat_off': 'Répétition désactivée', + 'music.player_repeat_all': 'Tout répéter', + 'music.player_repeat_one': 'Répéter le morceau', + 'music.player_volume': 'Volume', + // LAN cast 'cast.start': 'Diffuser sur un appareil', 'cast.stop': 'Arrêter la diffusion', @@ -616,6 +638,15 @@ export default { 'settings_node.video_root_title': 'Dossier racine des Vidéos', 'settings_node.video_root_hint': "Quel dossier (ou sous-dossier) sert de point d'entrée à l'application Vidéos pour ce groupe. Rien ne s'affiche dans Vidéos, et aucune recherche TMDB n'est effectuée, tant qu'aucun n'est choisi.", 'settings_node.video_root_none': '— aucun choisi —', + 'settings_node.musicbrainz_title': 'Métadonnées MusicBrainz', + 'settings_node.musicbrainz_hint': "Permet à l'app Musique d'afficher les pochettes et les noms canoniques depuis MusicBrainz quand un morceau n'a pas de pochette intégrée utilisable. Désactivé signifie une navigation par tags/nom de fichier uniquement, sans requête vers un tiers.", + 'settings_node.musicbrainz_enabled': 'Activé', + 'settings_node.musicbrainz_disabled': 'Désactivé', + 'settings_node.musicbrainz_contact_label': 'Contact (requis pour que MusicBrainz réponde)', + 'settings_node.musicbrainz_contact_placeholder': 'vous@exemple.com ou une URL de projet', + 'settings_node.musicbrainz_contact_set': 'Un contact est configuré.', + 'settings_node.musicbrainz_contact_unset': "Aucun contact configuré — les recherches MusicBrainz restent désactivées tant que rien n'est renseigné.", + 'settings_node.musicbrainz_save': 'Enregistrer', 'settings_node.video_root_save': 'Enregistrer', 'settings_node.video_root_change_confirm': "Changer la racine des Vidéos remplace ce que chaque membre voit dans l'onglet Vidéos. Continuer ?", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js index bdfda75..257318a 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js @@ -76,6 +76,7 @@ export default { 'group.tab_files': 'File', 'group.tab_chat': 'Chat', 'group.tab_video': 'Video', + 'group.tab_music': 'Musica', 'group.tab_members': 'Membri', 'group.tab_settings': "Impostazioni", 'members.danger_leave_hint': "Perderai l’accesso ai file e alla chat di questo gruppo.", @@ -175,6 +176,27 @@ export default { 'video.search_no_results': 'Nessuna corrispondenza trovata.', 'video.search_apply_hint': 'Si applica a tutti i file attualmente raggruppati sotto questo titolo.', + // Musica + 'music.mode_grid': 'Album', + 'music.mode_flat': 'Elenco semplice', + 'music.empty': 'Nessuna musica trovata.', + 'music.unknown_album': 'Album sconosciuto', + 'music.play_all': 'Riproduci tutto', + 'music.n_tracks': { + one: '{n} traccia', + other: '{n} tracce', + }, + 'music.err_transport': 'Trasporto non connesso', + 'music.player_play': 'Riproduci', + 'music.player_pause': 'Pausa', + 'music.player_prev': 'Precedente', + 'music.player_next': 'Successivo', + 'music.player_shuffle': 'Riproduzione casuale', + 'music.player_repeat_off': 'Ripetizione disattivata', + 'music.player_repeat_all': 'Ripeti tutto', + 'music.player_repeat_one': 'Ripeti brano', + 'music.player_volume': 'Volume', + // LAN cast 'cast.start': 'Trasmetti al dispositivo', 'cast.stop': 'Interrompi trasmissione', @@ -614,6 +636,15 @@ export default { 'settings_node.video_root_title': 'Cartella radice di Video', 'settings_node.video_root_hint': "Quale cartella (o sottocartella) l'app Video considera come punto di ingresso per questo gruppo. In Video non viene mostrato nulla, e non viene eseguita alcuna ricerca TMDB, finché non ne viene scelta una.", 'settings_node.video_root_none': '— nessuna scelta —', + 'settings_node.musicbrainz_title': 'Metadati MusicBrainz', + 'settings_node.musicbrainz_hint': "Permette all'app Musica di mostrare copertine e nomi canonici da MusicBrainz quando una traccia non ha una copertina incorporata utilizzabile. Disattivato significa navigazione basata solo su tag/nome file, senza richieste a terzi.", + 'settings_node.musicbrainz_enabled': 'Attivato', + 'settings_node.musicbrainz_disabled': 'Disattivato', + 'settings_node.musicbrainz_contact_label': 'Contatto (necessario perché MusicBrainz risponda)', + 'settings_node.musicbrainz_contact_placeholder': 'tu@esempio.com o un URL di progetto', + 'settings_node.musicbrainz_contact_set': 'È configurato un contatto.', + 'settings_node.musicbrainz_contact_unset': 'Nessun contatto configurato — le ricerche MusicBrainz restano disattivate finché non ne viene impostato uno.', + 'settings_node.musicbrainz_save': 'Salva', 'settings_node.video_root_save': 'Salva', 'settings_node.video_root_change_confirm': 'Cambiare la radice di Video sostituisce ciò che ogni membro vede nella scheda Video. Continuare?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js index f00a0ec..44f9037 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js @@ -74,6 +74,7 @@ export default { 'group.tab_files': 'ファイル', 'group.tab_chat': 'チャット', 'group.tab_video': '動画', + 'group.tab_music': '音楽', 'group.tab_members': 'メンバー', 'group.tab_settings': "設定", 'members.danger_leave_hint': "このグループのファイルとチャットにアクセスできなくなります。", @@ -172,6 +173,27 @@ export default { 'video.search_no_results': '一致する結果が見つかりません。', 'video.search_apply_hint': '現在このタイトルでグループ化されているすべてのファイルに適用されます。', + // 音楽 + 'music.mode_grid': 'アルバム', + 'music.mode_flat': 'フラットリスト', + 'music.empty': '音楽が見つかりません。', + 'music.unknown_album': '不明なアルバム', + 'music.play_all': 'すべて再生', + 'music.n_tracks': { + one: '{n}曲', + other: '{n}曲', + }, + 'music.err_transport': 'トランスポートが接続されていません', + 'music.player_play': '再生', + 'music.player_pause': '一時停止', + 'music.player_prev': '前へ', + 'music.player_next': '次へ', + 'music.player_shuffle': 'シャッフル', + 'music.player_repeat_off': 'リピートオフ', + 'music.player_repeat_all': 'すべてリピート', + 'music.player_repeat_one': '1曲リピート', + 'music.player_volume': '音量', + // LAN cast 'cast.start': 'デバイスにキャスト', 'cast.stop': 'キャストを停止', @@ -598,6 +620,15 @@ export default { 'settings_node.video_root_title': '動画のルートフォルダ', 'settings_node.video_root_hint': 'このグループで動画アプリの起点とするフォルダ(またはサブフォルダ)です。選択されるまで、動画には何も表示されず、TMDB への問い合わせも行われません。', 'settings_node.video_root_none': '— 未選択 —', + 'settings_node.musicbrainz_title': 'MusicBrainzのメタデータ', + 'settings_node.musicbrainz_hint': 'トラックに使用可能な埋め込みカバーがない場合、MusicBrainzのカバーアートと正式名称をMusicアプリで表示できるようにします。オフにするとタグ・ファイル名のみでの閲覧になり、第三者へのリクエストは発生しません。', + 'settings_node.musicbrainz_enabled': '有効', + 'settings_node.musicbrainz_disabled': '無効', + 'settings_node.musicbrainz_contact_label': '連絡先(MusicBrainzが応答するために必要)', + 'settings_node.musicbrainz_contact_placeholder': 'you@example.com またはプロジェクトのURL', + 'settings_node.musicbrainz_contact_set': '連絡先が設定されています。', + 'settings_node.musicbrainz_contact_unset': '連絡先が設定されていません — 設定されるまでMusicBrainzの検索は無効のままです。', + 'settings_node.musicbrainz_save': '保存', 'settings_node.video_root_save': '保存', 'settings_node.video_root_change_confirm': '動画のルートフォルダを変更すると、全メンバーの動画タブの表示内容が変わります。続行しますか?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js index d9ed12e..2fedd70 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js @@ -77,6 +77,7 @@ export default { 'group.tab_files': 'Bestanden', 'group.tab_chat': 'Chat', 'group.tab_video': "Video's", + 'group.tab_music': 'Muziek', 'group.tab_members': 'Leden', 'group.tab_settings': "Instellingen", 'members.danger_leave_hint': "U verliest de toegang tot de bestanden en de chat van deze groep.", @@ -176,6 +177,27 @@ export default { 'video.search_no_results': 'Geen overeenkomsten gevonden.', 'video.search_apply_hint': 'Geldt voor alle bestanden die momenteel onder deze titel zijn gegroepeerd.', + // Muziek + 'music.mode_grid': 'Albums', + 'music.mode_flat': 'Platte lijst', + 'music.empty': 'Geen muziek gevonden.', + 'music.unknown_album': 'Onbekend album', + 'music.play_all': 'Alles afspelen', + 'music.n_tracks': { + one: '{n} nummer', + other: '{n} nummers', + }, + 'music.err_transport': 'Transport niet verbonden', + 'music.player_play': 'Afspelen', + 'music.player_pause': 'Pauzeren', + 'music.player_prev': 'Vorige', + 'music.player_next': 'Volgende', + 'music.player_shuffle': 'Shuffle', + 'music.player_repeat_off': 'Herhalen uit', + 'music.player_repeat_all': 'Alles herhalen', + 'music.player_repeat_one': 'Nummer herhalen', + 'music.player_volume': 'Volume', + // LAN cast 'cast.start': 'Naar apparaat casten', 'cast.stop': 'Casten stoppen', @@ -616,6 +638,15 @@ export default { 'settings_node.video_root_title': "Hoofdmap voor Video's", 'settings_node.video_root_hint': "Welke map (of submap) de Video's-app als startpunt gebruikt voor deze groep. Er wordt niets getoond in Video's, en er worden geen TMDB-opzoekingen uitgevoerd, totdat er een gekozen is.", 'settings_node.video_root_none': '— geen gekozen —', + 'settings_node.musicbrainz_title': 'MusicBrainz-metadata', + 'settings_node.musicbrainz_hint': "Laat de Muziek-app hoesfoto's en canonieke namen van MusicBrainz tonen wanneer een nummer geen bruikbare ingesloten hoes heeft. Uit betekent alleen bladeren op tag/bestandsnaam, zonder verzoek aan derden.", + 'settings_node.musicbrainz_enabled': 'Ingeschakeld', + 'settings_node.musicbrainz_disabled': 'Uitgeschakeld', + 'settings_node.musicbrainz_contact_label': 'Contact (vereist zodat MusicBrainz kan antwoorden)', + 'settings_node.musicbrainz_contact_placeholder': 'jij@voorbeeld.com of een project-URL', + 'settings_node.musicbrainz_contact_set': 'Er is een contact ingesteld.', + 'settings_node.musicbrainz_contact_unset': 'Geen contact ingesteld — MusicBrainz-opzoekingen blijven uit totdat er een is ingesteld.', + 'settings_node.musicbrainz_save': 'Opslaan', 'settings_node.video_root_save': 'Opslaan', 'settings_node.video_root_change_confirm': "Het wijzigen van de hoofdmap voor Video's vervangt wat elk lid ziet in het tabblad Video's. Doorgaan?", diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js index cbd27b1..dac2359 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js @@ -81,6 +81,7 @@ export default { 'group.tab_files': 'Pliki', 'group.tab_chat': 'Czat', 'group.tab_video': 'Wideo', + 'group.tab_music': 'Muzyka', 'group.tab_members': 'Członkowie', 'group.tab_settings': "Ustawienia", 'members.danger_leave_hint': "Utracisz dostęp do plików i czatu tej grupy.", @@ -183,6 +184,29 @@ export default { 'video.search_no_results': 'Nie znaleziono dopasowań.', 'video.search_apply_hint': 'Dotyczy wszystkich plików obecnie zgrupowanych pod tym tytułem.', + // Muzyka + 'music.mode_grid': 'Albumy', + 'music.mode_flat': 'Lista płaska', + 'music.empty': 'Nie znaleziono muzyki.', + 'music.unknown_album': 'Nieznany album', + 'music.play_all': 'Odtwórz wszystko', + 'music.n_tracks': { + one: '{n} utwór', + few: '{n} utwory', + many: '{n} utworów', + other: '{n} utworu', + }, + 'music.err_transport': 'Transport niepołączony', + 'music.player_play': 'Odtwórz', + 'music.player_pause': 'Pauza', + 'music.player_prev': 'Poprzedni', + 'music.player_next': 'Następny', + 'music.player_shuffle': 'Losowo', + 'music.player_repeat_off': 'Powtarzanie wyłączone', + 'music.player_repeat_all': 'Powtórz wszystko', + 'music.player_repeat_one': 'Powtórz utwór', + 'music.player_volume': 'Głośność', + // LAN cast 'cast.start': 'Przesyłaj na urządzenie', 'cast.stop': 'Zatrzymaj przesyłanie', @@ -639,6 +663,15 @@ export default { 'settings_node.video_root_title': 'Katalog główny Wideo', 'settings_node.video_root_hint': 'Który katalog (lub podkatalog) aplikacja Wideo traktuje jako punkt wejścia dla tej grupy. W Wideo nic się nie wyświetla i nie są wykonywane żadne zapytania do TMDB, dopóki nie zostanie wybrany.', 'settings_node.video_root_none': '— nie wybrano —', + 'settings_node.musicbrainz_title': 'Metadane MusicBrainz', + 'settings_node.musicbrainz_hint': 'Pozwala aplikacji Muzyka pokazywać okładki i kanoniczne nazwy z MusicBrainz, gdy utwór nie ma użytecznej wbudowanej okładki. Wyłączone oznacza przeglądanie tylko na podstawie tagów/nazwy pliku, bez żądań do strony trzeciej.', + 'settings_node.musicbrainz_enabled': 'Włączone', + 'settings_node.musicbrainz_disabled': 'Wyłączone', + 'settings_node.musicbrainz_contact_label': 'Kontakt (wymagany, aby MusicBrainz odpowiadał)', + 'settings_node.musicbrainz_contact_placeholder': 'ty@przyklad.com lub URL projektu', + 'settings_node.musicbrainz_contact_set': 'Kontakt jest skonfigurowany.', + 'settings_node.musicbrainz_contact_unset': 'Brak skonfigurowanego kontaktu — wyszukiwania MusicBrainz pozostają wyłączone, dopóki nie zostanie ustawiony.', + 'settings_node.musicbrainz_save': 'Zapisz', 'settings_node.video_root_save': 'Zapisz', 'settings_node.video_root_change_confirm': 'Zmiana katalogu głównego Wideo zastępuje to, co widzi każdy członek w karcie Wideo. Kontynuować?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js index e7bf45c..4251a4b 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js @@ -77,6 +77,7 @@ export default { 'group.tab_files': 'Arquivos', 'group.tab_chat': 'Conversa', 'group.tab_video': 'Vídeos', + 'group.tab_music': 'Música', 'group.tab_members': 'Membros', 'group.tab_settings': "Configurações", 'members.danger_leave_hint': "Você perderá o acesso aos arquivos e ao chat deste grupo.", @@ -176,6 +177,27 @@ export default { 'video.search_no_results': 'Nenhuma correspondência encontrada.', 'video.search_apply_hint': 'Aplica-se a todos os arquivos atualmente agrupados sob este título.', + // Música + 'music.mode_grid': 'Álbuns', + 'music.mode_flat': 'Lista simples', + 'music.empty': 'Nenhuma música encontrada.', + 'music.unknown_album': 'Álbum desconhecido', + 'music.play_all': 'Reproduzir tudo', + 'music.n_tracks': { + one: '{n} faixa', + other: '{n} faixas', + }, + 'music.err_transport': 'Transporte não conectado', + 'music.player_play': 'Reproduzir', + 'music.player_pause': 'Pausar', + 'music.player_prev': 'Anterior', + 'music.player_next': 'Próxima', + 'music.player_shuffle': 'Aleatório', + 'music.player_repeat_off': 'Repetição desativada', + 'music.player_repeat_all': 'Repetir tudo', + 'music.player_repeat_one': 'Repetir faixa', + 'music.player_volume': 'Volume', + // LAN cast 'cast.start': 'Transmitir para dispositivo', 'cast.stop': 'Parar transmissão', @@ -601,6 +623,15 @@ export default { 'settings_node.video_root_title': 'Pasta raiz de Vídeos', 'settings_node.video_root_hint': 'Qual pasta (ou subpasta) o app Vídeos trata como ponto de entrada para este grupo. Nada é exibido em Vídeos, e nenhuma busca no TMDB é feita, até que uma seja escolhida.', 'settings_node.video_root_none': '— nenhuma escolhida —', + 'settings_node.musicbrainz_title': 'Metadados do MusicBrainz', + 'settings_node.musicbrainz_hint': 'Permite que o app Música mostre capas e nomes canônicos do MusicBrainz quando uma faixa não tem uma capa incorporada utilizável. Desativado significa navegação apenas por tags/nome de arquivo, sem solicitação a terceiros.', + 'settings_node.musicbrainz_enabled': 'Ativado', + 'settings_node.musicbrainz_disabled': 'Desativado', + 'settings_node.musicbrainz_contact_label': 'Contato (necessário para o MusicBrainz responder)', + 'settings_node.musicbrainz_contact_placeholder': 'voce@exemplo.com ou uma URL de projeto', + 'settings_node.musicbrainz_contact_set': 'Um contato está configurado.', + 'settings_node.musicbrainz_contact_unset': 'Nenhum contato configurado — as buscas no MusicBrainz permanecem desativadas até que um seja definido.', + 'settings_node.musicbrainz_save': 'Salvar', 'settings_node.video_root_save': 'Salvar', 'settings_node.video_root_change_confirm': 'Alterar a raiz de Vídeos substitui o que cada membro vê na aba Vídeos. Continuar?', diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js index 33a0e25..7e7676b 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js @@ -74,6 +74,7 @@ export default { 'group.tab_files': '文件', 'group.tab_chat': '聊天', 'group.tab_video': '视频', + 'group.tab_music': '音乐', 'group.tab_members': '成员', 'group.tab_settings': "设置", 'members.danger_leave_hint': "您将无法再访问该群组的文件和聊天。", @@ -169,6 +170,27 @@ export default { 'video.search_no_results': '未找到匹配项。', 'video.search_apply_hint': '将应用于当前归类在此标题下的所有文件。', + // 音乐 + 'music.mode_grid': '专辑', + 'music.mode_flat': '平铺列表', + 'music.empty': '未找到音乐。', + 'music.unknown_album': '未知专辑', + 'music.play_all': '全部播放', + 'music.n_tracks': { + one: '{n} 首曲目', + other: '{n} 首曲目', + }, + 'music.err_transport': '传输未连接', + 'music.player_play': '播放', + 'music.player_pause': '暂停', + 'music.player_prev': '上一首', + 'music.player_next': '下一首', + 'music.player_shuffle': '随机播放', + 'music.player_repeat_off': '不重复', + 'music.player_repeat_all': '全部重复', + 'music.player_repeat_one': '单曲重复', + 'music.player_volume': '音量', + // LAN cast 'cast.start': '投射到设备', 'cast.stop': '停止投射', @@ -584,6 +606,15 @@ export default { 'settings_node.video_root_title': '视频根目录', 'settings_node.video_root_hint': '该文件夹(或子文件夹)将作为此群组"视频"应用的入口。在选择之前,"视频"中不会显示任何内容,也不会执行任何 TMDB 查询。', 'settings_node.video_root_none': '— 未选择 —', + 'settings_node.musicbrainz_title': 'MusicBrainz 元数据', + 'settings_node.musicbrainz_hint': '当曲目没有可用的内嵌封面时,允许音乐应用显示来自 MusicBrainz 的封面和规范名称。关闭表示仅按标签/文件名浏览,不向第三方发送请求。', + 'settings_node.musicbrainz_enabled': '已启用', + 'settings_node.musicbrainz_disabled': '已禁用', + 'settings_node.musicbrainz_contact_label': '联系方式(MusicBrainz 需要它才能响应请求)', + 'settings_node.musicbrainz_contact_placeholder': 'you@example.com 或项目 URL', + 'settings_node.musicbrainz_contact_set': '已配置联系方式。', + 'settings_node.musicbrainz_contact_unset': '未配置联系方式 — 在设置之前,MusicBrainz 查询将保持关闭。', + 'settings_node.musicbrainz_save': '保存', 'settings_node.video_root_save': '保存', 'settings_node.video_root_change_confirm': '更改视频根目录会替换每位成员在"视频"标签页中看到的内容。是否继续?', |