aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-24 17:39:41 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-24 17:39:41 +0200
commit8c780b9928db8145b7fe18ecd137384ccfe25d8f (patch)
tree5cfc06eec0fdf9bb7fe0a14f45e3ef803bb86a20 /packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
parent941d1a135dd7b03834576855e8e9fdaa24c4e406 (diff)
downloadmeshbay-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/es.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/es.js31
1 files changed, 31 insertions, 0 deletions
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?',