refactor(settings): remove unused features, implement working i18n
- Remove Compact Mode toggle (feature was not implemented) - Remove Storage Limit dropdown from Downloads (always 2GB, not functional) - Connect language dropdown to svelte-i18n system - Language setting now properly persists and changes app locale - Add comprehensive translations for en and es locales - Settings view now uses $t() for all translatable strings - Support for Auto language detection based on browser locale
This commit is contained in:
1 parent
2568862aa6
commit
5c869eeae9
3 files changed
+560
-193
No files matched your search
@@ -11,7 +11,6 @@
|
||||
getDownloadCacheStats,
|
||||
clearDownloadCache,
|
||||
openDownloadCacheFolder,
|
||||
setDownloadCacheLimit,
|
||||
type DownloadCacheStats
|
||||
} from '$lib/stores/downloadState';
|
||||
import { clearCache as clearLyricsCache } from '$lib/stores/lyricsStore';
|
||||
@@ -26,6 +25,8 @@
|
||||
setSystemNotificationsEnabled,
|
||||
loadSystemNotificationsPreference
|
||||
} from '$lib/services/playbackService';
|
||||
import { setLocale, locale, t } from '$lib/i18n';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
interface Props {
|
||||
onBack?: () => void;
|
||||
@@ -63,7 +64,6 @@
|
||||
// Download cache state (offline storage)
|
||||
let downloadStats = $state<DownloadCacheStats | null>(null);
|
||||
let isClearingDownloads = $state(false);
|
||||
let downloadCacheLimit = $state('2 GB'); // Default 2GB
|
||||
|
||||
// Lyrics cache state
|
||||
let isClearingLyrics = $state(false);
|
||||
@@ -119,6 +119,21 @@
|
||||
'warm': 'Warm'
|
||||
};
|
||||
|
||||
// Language mapping: display name -> locale code
|
||||
const languageToLocale: Record<string, string | null> = {
|
||||
'Auto': null,
|
||||
'English': 'en',
|
||||
'Español': 'es'
|
||||
};
|
||||
|
||||
const localeToLanguage: Record<string, string> = {
|
||||
'en': 'English',
|
||||
'es': 'Español'
|
||||
};
|
||||
|
||||
// Available languages (only those with translations)
|
||||
const availableLanguages = ['Auto', 'English', 'Español'];
|
||||
|
||||
// Audio settings
|
||||
let streamingQuality = $state('Hi-Res');
|
||||
let preferHighest = $state(true);
|
||||
@@ -147,7 +162,6 @@
|
||||
|
||||
// Appearance settings
|
||||
let theme = $state('Dark');
|
||||
let compactMode = $state(false);
|
||||
let toastsEnabled = $state(true);
|
||||
let systemNotificationsEnabled = $state(true);
|
||||
let language = $state('Auto');
|
||||
@@ -196,10 +210,12 @@
|
||||
preferHighest = savedPreferHighest === 'true';
|
||||
}
|
||||
|
||||
// Load language setting
|
||||
const savedLanguage = localStorage.getItem('qbz-language');
|
||||
if (savedLanguage) {
|
||||
language = savedLanguage;
|
||||
// Load language setting from i18n locale
|
||||
const currentLocale = get(locale);
|
||||
if (currentLocale && localeToLanguage[currentLocale]) {
|
||||
language = localeToLanguage[currentLocale];
|
||||
} else {
|
||||
language = 'Auto';
|
||||
}
|
||||
|
||||
// Load UI zoom level
|
||||
@@ -519,7 +535,18 @@
|
||||
|
||||
function handleLanguageChange(lang: string) {
|
||||
language = lang;
|
||||
localStorage.setItem('qbz-language', lang);
|
||||
const localeCode = languageToLocale[lang];
|
||||
if (localeCode) {
|
||||
// Set specific locale
|
||||
setLocale(localeCode);
|
||||
} else {
|
||||
// 'Auto' - use browser locale, defaulting to 'en'
|
||||
const browserLocale = navigator.language.split('-')[0];
|
||||
const supportedLocale = ['en', 'es'].includes(browserLocale) ? browserLocale : 'en';
|
||||
setLocale(supportedLocale);
|
||||
// Clear the stored locale so it uses browser detection on next load
|
||||
localStorage.removeItem('qbz-locale');
|
||||
}
|
||||
}
|
||||
|
||||
interface AudioSettings {
|
||||
@@ -624,18 +651,6 @@
|
||||
async function loadDownloadStats() {
|
||||
try {
|
||||
downloadStats = await getDownloadCacheStats();
|
||||
// Set the limit dropdown to match current limit
|
||||
if (downloadStats.limitBytes) {
|
||||
const limitGb = downloadStats.limitBytes / (1024 * 1024 * 1024);
|
||||
if (limitGb <= 0.5) downloadCacheLimit = '500 MB';
|
||||
else if (limitGb <= 1) downloadCacheLimit = '1 GB';
|
||||
else if (limitGb <= 2) downloadCacheLimit = '2 GB';
|
||||
else if (limitGb <= 5) downloadCacheLimit = '5 GB';
|
||||
else if (limitGb <= 10) downloadCacheLimit = '10 GB';
|
||||
else downloadCacheLimit = 'Unlimited';
|
||||
} else {
|
||||
downloadCacheLimit = 'Unlimited';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to load download stats:', err);
|
||||
}
|
||||
@@ -662,27 +677,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDownloadLimitChange(limit: string) {
|
||||
downloadCacheLimit = limit;
|
||||
let limitMb: number | null = null;
|
||||
|
||||
switch (limit) {
|
||||
case '500 MB': limitMb = 500; break;
|
||||
case '1 GB': limitMb = 1024; break;
|
||||
case '2 GB': limitMb = 2048; break;
|
||||
case '5 GB': limitMb = 5120; break;
|
||||
case '10 GB': limitMb = 10240; break;
|
||||
case 'Unlimited': limitMb = null; break;
|
||||
}
|
||||
|
||||
try {
|
||||
await setDownloadCacheLimit(limitMb);
|
||||
await loadDownloadStats();
|
||||
} catch (err) {
|
||||
console.error('Failed to set download limit:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleClearCache() {
|
||||
if (isClearing) return;
|
||||
isClearing = true;
|
||||
@@ -750,15 +744,15 @@
|
||||
{#if onBack}
|
||||
<button class="back-btn" onclick={onBack}>
|
||||
<ArrowLeft size={16} />
|
||||
<span>Back</span>
|
||||
<span>{$t('actions.back')}</span>
|
||||
</button>
|
||||
{/if}
|
||||
<h1 class="title">Settings</h1>
|
||||
<h1 class="title">{$t('settings.title')}</h1>
|
||||
</div>
|
||||
|
||||
<!-- Account Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Account</h3>
|
||||
<h3 class="section-title">{$t('settings.account.title')}</h3>
|
||||
<div class="account-card">
|
||||
<div class="avatar">{userName.charAt(0).toUpperCase()}</div>
|
||||
<div class="account-info">
|
||||
@@ -768,15 +762,15 @@
|
||||
{/if}
|
||||
<div class="subscription">{subscription}</div>
|
||||
</div>
|
||||
<button class="logout-btn" onclick={onLogout}>Logout</button>
|
||||
<button class="logout-btn" onclick={onLogout}>{$t('settings.account.logout')}</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Audio Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Audio</h3>
|
||||
<h3 class="section-title">{$t('settings.audio.title')}</h3>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Streaming Quality</span>
|
||||
<span class="setting-label">{$t('settings.audio.streamingQuality')}</span>
|
||||
<Dropdown
|
||||
value={streamingQuality}
|
||||
options={['MP3', 'CD Quality', 'Hi-Res', 'Hi-Res+']}
|
||||
@@ -784,12 +778,12 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Prefer highest available</span>
|
||||
<span class="setting-label">{$t('settings.audio.preferHighest')}</span>
|
||||
<Toggle enabled={preferHighest} onchange={handlePreferHighestChange} />
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="label-with-tooltip">
|
||||
<span class="setting-label">Output Device</span>
|
||||
<span class="setting-label">{$t('settings.audio.outputDevice')}</span>
|
||||
<Tooltip text="Select your preferred audio output device. Changes take effect on app restart." />
|
||||
</div>
|
||||
<Dropdown
|
||||
@@ -803,48 +797,48 @@
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="label-with-tooltip">
|
||||
<span class="setting-label">Exclusive Mode</span>
|
||||
<Tooltip text="Locks the audio device for exclusive use by QBZ for better quality" />
|
||||
<span class="setting-label">{$t('settings.audio.exclusiveMode')}</span>
|
||||
<Tooltip text={$t('settings.audio.exclusiveModeDesc')} />
|
||||
</div>
|
||||
<Toggle enabled={exclusiveMode} onchange={handleExclusiveModeChange} />
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<div class="label-with-tooltip">
|
||||
<span class="setting-label">DAC Passthrough</span>
|
||||
<Tooltip text="Bypass the system audio mixer to send audio directly to your DAC at its native sample rate. Recommended for external DACs." />
|
||||
<span class="setting-label">{$t('settings.audio.dacPassthrough')}</span>
|
||||
<Tooltip text={$t('settings.audio.dacPassthroughDesc')} />
|
||||
</div>
|
||||
<Toggle enabled={dacPassthrough} onchange={handleDacPassthroughChange} />
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">Sample Rate</span>
|
||||
<span class="setting-label">{$t('settings.audio.currentSampleRate')}</span>
|
||||
<span class="setting-value">192 kHz</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Playback Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Playback</h3>
|
||||
<h3 class="section-title">{$t('settings.playback.title')}</h3>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Gapless Playback</span>
|
||||
<span class="setting-label">{$t('settings.playback.gapless')}</span>
|
||||
<Toggle enabled={gaplessPlayback} onchange={(v) => (gaplessPlayback = v)} />
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Crossfade</span>
|
||||
<span class="setting-label">{$t('settings.playback.crossfade')}</span>
|
||||
<div class="slider-container">
|
||||
<VolumeSlider value={crossfade} onchange={(v) => (crossfade = v)} max={12} showValue />
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">Normalize Volume</span>
|
||||
<span class="setting-label">{$t('settings.playback.normalizeVolume')}</span>
|
||||
<Toggle enabled={normalizeVolume} onchange={(v) => (normalizeVolume = v)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Appearance Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Appearance</h3>
|
||||
<h3 class="section-title">{$t('settings.appearance.title')}</h3>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Theme</span>
|
||||
<span class="setting-label">{$t('settings.appearance.theme')}</span>
|
||||
<Dropdown
|
||||
value={theme}
|
||||
options={['Dark', 'Light', 'OLED Black', 'Warm']}
|
||||
@@ -852,15 +846,15 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Language</span>
|
||||
<span class="setting-label">{$t('settings.appearance.language')}</span>
|
||||
<Dropdown
|
||||
value={language}
|
||||
options={['Auto', 'English', 'Español', 'Français', 'Deutsch', 'Italiano', 'Português']}
|
||||
options={availableLanguages}
|
||||
onchange={handleLanguageChange}
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">UI Scale</span>
|
||||
<span class="setting-label">{$t('settings.appearance.uiScale')}</span>
|
||||
<Dropdown
|
||||
value={zoomLevel}
|
||||
options={zoomOptions}
|
||||
@@ -868,26 +862,22 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Compact Mode</span>
|
||||
<Toggle enabled={compactMode} onchange={(v) => (compactMode = v)} />
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">In-app Toasts</span>
|
||||
<span class="setting-label">{$t('settings.appearance.inAppToasts')}</span>
|
||||
<Toggle enabled={toastsEnabled} onchange={(v) => { toastsEnabled = v; setToastsEnabled(v); }} />
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">System Notifications</span>
|
||||
<span class="setting-label">{$t('settings.appearance.systemNotifications')}</span>
|
||||
<Toggle enabled={systemNotificationsEnabled} onchange={(v) => { systemNotificationsEnabled = v; setSystemNotificationsEnabled(v); }} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Library Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Library</h3>
|
||||
<h3 class="section-title">{$t('settings.library.title')}</h3>
|
||||
<div class="setting-row last">
|
||||
<div class="setting-with-description">
|
||||
<span class="setting-label">Fetch Qobuz Artist Images</span>
|
||||
<span class="setting-description">Show artist photos from Qobuz in local library</span>
|
||||
<span class="setting-label">{$t('settings.library.fetchArtistImages')}</span>
|
||||
<span class="setting-description">{$t('settings.library.fetchArtistImagesDesc')}</span>
|
||||
</div>
|
||||
<Toggle enabled={fetchQobuzArtistImages} onchange={(v) => {
|
||||
fetchQobuzArtistImages = v;
|
||||
@@ -898,34 +888,34 @@
|
||||
|
||||
<!-- Integrations Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Integrations</h3>
|
||||
<h3 class="section-title">{$t('settings.integrations.title')}</h3>
|
||||
|
||||
{#if lastfmConnected}
|
||||
<div class="setting-row">
|
||||
<div class="lastfm-connected">
|
||||
<span class="setting-label">Last.fm</span>
|
||||
<span class="lastfm-username">Connected as {lastfmUsername}</span>
|
||||
<span class="setting-label">{$t('settings.integrations.lastfm')}</span>
|
||||
<span class="lastfm-username">{$t('settings.integrations.connectedAs', { values: { username: lastfmUsername }})}</span>
|
||||
</div>
|
||||
<button
|
||||
class="connect-btn connected"
|
||||
onclick={handleLastfmDisconnect}
|
||||
>
|
||||
Disconnect
|
||||
{$t('settings.integrations.disconnect')}
|
||||
</button>
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">Scrobbling</span>
|
||||
<span class="setting-label">{$t('settings.integrations.scrobbling')}</span>
|
||||
<Toggle enabled={scrobbling} onchange={handleScrobblingChange} />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="setting-row" class:last={!showLastfmConfig && !lastfmAuthToken}>
|
||||
<span class="setting-label">Last.fm</span>
|
||||
<span class="setting-label">{$t('settings.integrations.lastfm')}</span>
|
||||
<button
|
||||
class="connect-btn"
|
||||
onclick={handleLastfmConnect}
|
||||
disabled={lastfmConnecting}
|
||||
>
|
||||
{lastfmConnecting ? 'Connecting...' : 'Connect'}
|
||||
{lastfmConnecting ? 'Connecting...' : $t('settings.integrations.connect')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -990,98 +980,90 @@
|
||||
|
||||
<!-- Storage Section (Memory Cache) -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Storage</h3>
|
||||
<h3 class="section-title">{$t('settings.storage.title')}</h3>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Cache Size</span>
|
||||
<span class="setting-label">{$t('settings.storage.cacheSize')}</span>
|
||||
<span class="setting-value">
|
||||
{#if cacheStats}
|
||||
{formatBytes(cacheStats.current_size_bytes)} / {formatBytes(cacheStats.max_size_bytes)}
|
||||
{:else}
|
||||
Loading...
|
||||
{$t('actions.loading')}
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Cached Tracks</span>
|
||||
<span class="setting-label">{$t('settings.storage.cachedTracks')}</span>
|
||||
<span class="setting-value">
|
||||
{#if cacheStats}
|
||||
{cacheStats.cached_tracks} tracks
|
||||
{cacheStats.cached_tracks} {$t('album.tracks')}
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">Clear Cache</span>
|
||||
<span class="setting-label">{$t('settings.storage.clearCache')}</span>
|
||||
<button
|
||||
class="clear-btn"
|
||||
onclick={handleClearCache}
|
||||
disabled={isClearing || !cacheStats || cacheStats.current_size_bytes === 0}
|
||||
>
|
||||
{isClearing ? 'Clearing...' : 'Clear'}
|
||||
{isClearing ? $t('settings.storage.clearing') : $t('actions.clear')}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Downloads Section (Offline Storage) -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Downloads</h3>
|
||||
<h3 class="section-title">{$t('settings.downloads.title')}</h3>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Downloaded Tracks</span>
|
||||
<span class="setting-label">{$t('settings.downloads.downloadedTracks')}</span>
|
||||
<span class="setting-value">
|
||||
{#if downloadStats}
|
||||
{downloadStats.readyTracks} tracks ({formatBytes(downloadStats.totalSizeBytes)})
|
||||
{downloadStats.readyTracks} {$t('album.tracks')} ({formatBytes(downloadStats.totalSizeBytes)})
|
||||
{:else}
|
||||
Loading...
|
||||
{$t('actions.loading')}
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Storage Limit</span>
|
||||
<Dropdown
|
||||
value={downloadCacheLimit}
|
||||
options={['500 MB', '1 GB', '2 GB', '5 GB', '10 GB', 'Unlimited']}
|
||||
onchange={handleDownloadLimitChange}
|
||||
/>
|
||||
</div>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Clear Downloads</span>
|
||||
<span class="setting-label">{$t('settings.downloads.clearDownloads')}</span>
|
||||
<button
|
||||
class="clear-btn"
|
||||
onclick={handleClearDownloads}
|
||||
disabled={isClearingDownloads || !downloadStats || downloadStats.readyTracks === 0}
|
||||
>
|
||||
{isClearingDownloads ? 'Clearing...' : 'Clear All'}
|
||||
{isClearingDownloads ? $t('settings.storage.clearing') : $t('actions.clearAll')}
|
||||
</button>
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">Open Folder</span>
|
||||
<span class="setting-label">{$t('settings.downloads.openFolder')}</span>
|
||||
<button
|
||||
class="folder-btn"
|
||||
onclick={handleOpenDownloadFolder}
|
||||
title="Open download cache folder"
|
||||
title={$t('settings.downloads.openFolder')}
|
||||
>
|
||||
<FolderOpen size={16} />
|
||||
<span>Open</span>
|
||||
<span>{$t('actions.open')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Lyrics Section -->
|
||||
<section class="section">
|
||||
<h3 class="section-title">Lyrics</h3>
|
||||
<h3 class="section-title">{$t('settings.lyrics.title')}</h3>
|
||||
<div class="setting-row">
|
||||
<span class="setting-label">Provider</span>
|
||||
<span class="setting-value">LRCLIB / lyrics.ovh</span>
|
||||
</div>
|
||||
<div class="setting-row last">
|
||||
<span class="setting-label">Clear Lyrics Cache</span>
|
||||
<span class="setting-label">{$t('settings.lyrics.clearLyrics')}</span>
|
||||
<button
|
||||
class="clear-btn"
|
||||
onclick={handleClearLyricsCache}
|
||||
disabled={isClearingLyrics}
|
||||
>
|
||||
{isClearingLyrics ? 'Clearing...' : 'Clear'}
|
||||
{isClearingLyrics ? $t('settings.storage.clearing') : $t('actions.clear')}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1097,7 +1079,7 @@
|
||||
{:else}
|
||||
<ChevronRight size={18} />
|
||||
{/if}
|
||||
<span>API Keys</span>
|
||||
<span>{$t('settings.integrations.apiKeys')}</span>
|
||||
{#if hasAnyUserCredentials()}
|
||||
<span class="keys-badge">Custom</span>
|
||||
{/if}
|
||||
|
||||
+212
-20
@@ -11,73 +11,179 @@
|
||||
"artists": "Artists",
|
||||
"tracks": "Tracks",
|
||||
"playlists": "Playlists",
|
||||
"favorites": "Favorites",
|
||||
"settings": "Settings",
|
||||
"newReleases": "New Releases",
|
||||
"pressAwards": "Press Awards",
|
||||
"radio": "Radio",
|
||||
"recentlyAdded": "Recently Added"
|
||||
"recentlyAdded": "Recently Added",
|
||||
"backTo": "Back to"
|
||||
},
|
||||
"home": {
|
||||
"title": "Home",
|
||||
"featuredForYou": "Featured for you",
|
||||
"recentlyPlayed": "Recently Played",
|
||||
"newReleases": "New Releases",
|
||||
"pressAwards": "Press Awards",
|
||||
"madeForYou": "Made for You",
|
||||
"topPicks": "Top Picks"
|
||||
"topPicks": "Top Picks",
|
||||
"yourPlaylists": "Your Playlists",
|
||||
"seeAll": "See All"
|
||||
},
|
||||
"search": {
|
||||
"title": "Search",
|
||||
"placeholder": "Search albums, artists, tracks...",
|
||||
"all": "All",
|
||||
"albums": "Albums",
|
||||
"tracks": "Tracks",
|
||||
"artists": "Artists",
|
||||
"noResults": "No results found",
|
||||
"searching": "Searching..."
|
||||
"searching": "Searching...",
|
||||
"recentSearches": "Recent Searches",
|
||||
"clearHistory": "Clear History"
|
||||
},
|
||||
"library": {
|
||||
"title": "Local Library",
|
||||
"albums": "Albums",
|
||||
"artists": "Artists",
|
||||
"tracks": "Tracks",
|
||||
"folders": "Folders",
|
||||
"noAlbums": "No albums in library",
|
||||
"noArtists": "No artists in library",
|
||||
"noTracks": "No tracks in library",
|
||||
"noFolders": "No folders added",
|
||||
"addFolder": "Add Folder",
|
||||
"removeFolder": "Remove",
|
||||
"scan": "Scan",
|
||||
"scanning": "Scanning...",
|
||||
"stopScan": "Stop",
|
||||
"scanComplete": "Scan complete",
|
||||
"scanCancelled": "Scan cancelled",
|
||||
"scanError": "Scan error",
|
||||
"searchPlaceholder": "Search...",
|
||||
"searchAlbums": "Search albums...",
|
||||
"searchArtists": "Search artists...",
|
||||
"searchTracks": "Search tracks, albums, artists...",
|
||||
"trackCount": "{count} tracks",
|
||||
"albumCount": "{count} albums",
|
||||
"artistCount": "{count} artists",
|
||||
"groupBy": "Group by",
|
||||
"sortBy": "Sort by",
|
||||
"viewAs": "View as",
|
||||
"grid": "Grid",
|
||||
"list": "List",
|
||||
"fetchingArtwork": "Fetching artwork..."
|
||||
},
|
||||
"album": {
|
||||
"tracks": "tracks",
|
||||
"track": "track",
|
||||
"by": "by",
|
||||
"released": "Released",
|
||||
"releaseDate": "Release Date",
|
||||
"label": "Label",
|
||||
"genre": "Genre"
|
||||
"genre": "Genre",
|
||||
"duration": "Duration",
|
||||
"quality": "Quality",
|
||||
"play": "Play",
|
||||
"shuffle": "Shuffle",
|
||||
"addToQueue": "Add to Queue",
|
||||
"addToPlaylist": "Add to Playlist",
|
||||
"download": "Download",
|
||||
"downloadAll": "Download All",
|
||||
"disc": "Disc"
|
||||
},
|
||||
"artist": {
|
||||
"albums": "Albums",
|
||||
"discography": "Discography",
|
||||
"eps": "EPs & Singles",
|
||||
"epsSingles": "EPs & Singles",
|
||||
"live": "Live Albums",
|
||||
"liveAlbums": "Live Albums",
|
||||
"compilations": "Compilations",
|
||||
"appearsOn": "Appears On",
|
||||
"popularTracks": "Popular Tracks",
|
||||
"similarArtists": "Similar Artists",
|
||||
"followers": "followers"
|
||||
"biography": "Biography",
|
||||
"readMore": "Read More",
|
||||
"readLess": "Read Less",
|
||||
"followers": "followers",
|
||||
"loadMore": "Load More",
|
||||
"noAlbums": "No albums",
|
||||
"noBiography": "No biography available"
|
||||
},
|
||||
"playlist": {
|
||||
"tracks": "tracks",
|
||||
"track": "track",
|
||||
"createNew": "Create New...",
|
||||
"createPlaylist": "Create Playlist",
|
||||
"deletePlaylist": "Delete Playlist",
|
||||
"renamePlaylist": "Rename Playlist",
|
||||
"allPlaylists": "All Playlists",
|
||||
"myPlaylists": "My Playlists"
|
||||
"myPlaylists": "My Playlists",
|
||||
"qobuzPlaylists": "Qobuz Playlists",
|
||||
"emptyPlaylist": "This playlist is empty",
|
||||
"addTracks": "Add Tracks",
|
||||
"removeTracks": "Remove",
|
||||
"playlistName": "Playlist Name",
|
||||
"description": "Description",
|
||||
"public": "Public",
|
||||
"private": "Private"
|
||||
},
|
||||
"favorites": {
|
||||
"title": "Favorites",
|
||||
"albums": "Albums",
|
||||
"tracks": "Tracks",
|
||||
"artists": "Artists",
|
||||
"noFavorites": "No favorites yet",
|
||||
"addedToFavorites": "Added to favorites",
|
||||
"removedFromFavorites": "Removed from favorites"
|
||||
},
|
||||
"player": {
|
||||
"nowPlaying": "Now Playing",
|
||||
"queue": "Queue",
|
||||
"upNext": "Up Next",
|
||||
"history": "History",
|
||||
"lyrics": "Lyrics",
|
||||
"noLyrics": "No lyrics available",
|
||||
"fetchingLyrics": "Fetching lyrics...",
|
||||
"shuffle": "Shuffle",
|
||||
"repeat": "Repeat",
|
||||
"repeatOne": "Repeat One",
|
||||
"repeatOff": "Repeat Off",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"play": "Play",
|
||||
"pause": "Pause",
|
||||
"volume": "Volume",
|
||||
"mute": "Mute"
|
||||
"mute": "Mute",
|
||||
"unmute": "Unmute",
|
||||
"clearQueue": "Clear Queue",
|
||||
"queueEmpty": "Queue is empty",
|
||||
"playNext": "Play Next",
|
||||
"addToQueue": "Add to Queue",
|
||||
"removeFromQueue": "Remove from Queue",
|
||||
"saveQueue": "Save as Playlist"
|
||||
},
|
||||
"quality": {
|
||||
"mp3": "MP3",
|
||||
"mp3": "MP3 320kbps",
|
||||
"cdQuality": "CD Quality",
|
||||
"cdQualityDesc": "16-bit / 44.1kHz FLAC",
|
||||
"hiRes": "Hi-Res",
|
||||
"ultraHiRes": "Ultra Hi-Res",
|
||||
"hiResDesc": "24-bit up to 96kHz FLAC",
|
||||
"ultraHiRes": "Hi-Res 24-bit",
|
||||
"ultraHiResDesc": "24-bit up to 192kHz FLAC",
|
||||
"flac": "FLAC",
|
||||
"bitDepth": "{depth}-bit",
|
||||
"sampleRate": "{rate} kHz",
|
||||
"lossless": "Lossless"
|
||||
"lossless": "Lossless",
|
||||
"max": "Max"
|
||||
},
|
||||
"actions": {
|
||||
"play": "Play",
|
||||
"playAll": "Play All",
|
||||
"playNow": "Play Now",
|
||||
"shuffle": "Shuffle",
|
||||
"shuffleAll": "Shuffle All",
|
||||
"addToQueue": "Add to Queue",
|
||||
"addToPlaylist": "Add to Playlist",
|
||||
"addToFavorites": "Add to Favorites",
|
||||
@@ -86,13 +192,26 @@
|
||||
"share": "Share",
|
||||
"viewAlbum": "View Album",
|
||||
"viewArtist": "View Artist",
|
||||
"goToArtist": "Go to Artist",
|
||||
"goToAlbum": "Go to Album",
|
||||
"more": "More",
|
||||
"back": "Back",
|
||||
"seeAll": "See All",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"delete": "Delete",
|
||||
"edit": "Edit"
|
||||
"edit": "Edit",
|
||||
"close": "Close",
|
||||
"open": "Open",
|
||||
"refresh": "Refresh",
|
||||
"retry": "Retry",
|
||||
"clear": "Clear",
|
||||
"clearAll": "Clear All",
|
||||
"confirm": "Confirm",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"ok": "OK",
|
||||
"loading": "Loading..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
@@ -106,8 +225,10 @@
|
||||
"audio": {
|
||||
"title": "Audio",
|
||||
"streamingQuality": "Streaming Quality",
|
||||
"preferHighest": "Prefer highest available",
|
||||
"preferHighest": "Prefer Highest Available",
|
||||
"preferHighestDesc": "Automatically select highest quality for your subscription",
|
||||
"outputDevice": "Output Device",
|
||||
"audioDevice": "Audio Device",
|
||||
"exclusiveMode": "Exclusive Mode",
|
||||
"exclusiveModeDesc": "Lock audio device for exclusive use",
|
||||
"dacPassthrough": "DAC Passthrough",
|
||||
@@ -131,22 +252,59 @@
|
||||
"warm": "Warm"
|
||||
},
|
||||
"accentColor": "Accent Color",
|
||||
"compactMode": "Compact Mode",
|
||||
"language": "Language"
|
||||
"language": "Language",
|
||||
"uiScale": "UI Scale",
|
||||
"inAppToasts": "In-app Toasts",
|
||||
"systemNotifications": "System Notifications"
|
||||
},
|
||||
"library": {
|
||||
"title": "Library",
|
||||
"fetchArtistImages": "Fetch Qobuz Artist Images",
|
||||
"fetchArtistImagesDesc": "Show artist photos from Qobuz in local library"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integrations",
|
||||
"lastfm": "Last.fm",
|
||||
"spotify": "Spotify",
|
||||
"tidal": "Tidal",
|
||||
"discogs": "Discogs",
|
||||
"connected": "Connected",
|
||||
"connectedAs": "Connected as {username}",
|
||||
"notConnected": "Not connected",
|
||||
"connect": "Connect",
|
||||
"disconnect": "Disconnect",
|
||||
"scrobbling": "Scrobbling"
|
||||
"scrobbling": "Scrobbling",
|
||||
"configureApi": "Configure API",
|
||||
"apiKeys": "API Keys",
|
||||
"clientId": "Client ID",
|
||||
"clientSecret": "Client Secret",
|
||||
"consumerKey": "Consumer Key",
|
||||
"consumerSecret": "Consumer Secret"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Storage",
|
||||
"cachedTracks": "Cached Tracks",
|
||||
"cacheSize": "Cache Size",
|
||||
"clearCache": "Clear Cache"
|
||||
"clearCache": "Clear Cache",
|
||||
"clearing": "Clearing..."
|
||||
},
|
||||
"downloads": {
|
||||
"title": "Downloads",
|
||||
"downloadedTracks": "Downloaded Tracks",
|
||||
"clearDownloads": "Clear All",
|
||||
"openFolder": "Open Folder"
|
||||
},
|
||||
"lyrics": {
|
||||
"title": "Lyrics",
|
||||
"lyricsCache": "Lyrics Cache",
|
||||
"clearLyrics": "Clear Lyrics"
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
"version": "Version",
|
||||
"sourceCode": "Source Code",
|
||||
"reportIssue": "Report Issue",
|
||||
"checkUpdates": "Check for Updates"
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
@@ -156,7 +314,25 @@
|
||||
"loginButton": "Sign In",
|
||||
"loggingIn": "Signing in...",
|
||||
"loginError": "Login failed. Please check your credentials.",
|
||||
"welcomeBack": "Welcome back"
|
||||
"welcomeBack": "Welcome back",
|
||||
"rememberMe": "Remember me"
|
||||
},
|
||||
"notifications": {
|
||||
"trackAdded": "Track added to queue",
|
||||
"tracksAdded": "{count} tracks added to queue",
|
||||
"albumAdded": "Album added to queue",
|
||||
"addedToPlaylist": "Added to playlist",
|
||||
"removedFromPlaylist": "Removed from playlist",
|
||||
"playlistCreated": "Playlist created",
|
||||
"playlistDeleted": "Playlist deleted",
|
||||
"downloadStarted": "Download started",
|
||||
"downloadComplete": "Download complete",
|
||||
"downloadFailed": "Download failed",
|
||||
"scanComplete": "Library scan complete",
|
||||
"scanCancelled": "Library scan cancelled",
|
||||
"scanFailed": "Library scan failed",
|
||||
"settingsSaved": "Settings saved",
|
||||
"copied": "Copied to clipboard"
|
||||
},
|
||||
"errors": {
|
||||
"generic": "Something went wrong",
|
||||
@@ -164,12 +340,20 @@
|
||||
"notFound": "Not found",
|
||||
"unauthorized": "Please log in to continue",
|
||||
"trackNotAvailable": "This track is not available for streaming",
|
||||
"qualityNotAvailable": "Requested quality is not available"
|
||||
"qualityNotAvailable": "Requested quality is not available",
|
||||
"loadFailed": "Failed to load",
|
||||
"playbackFailed": "Playback failed",
|
||||
"downloadFailed": "Download failed",
|
||||
"saveFailed": "Failed to save"
|
||||
},
|
||||
"time": {
|
||||
"hours": "h",
|
||||
"minutes": "min",
|
||||
"seconds": "s"
|
||||
"seconds": "s",
|
||||
"justNow": "Just now",
|
||||
"minutesAgo": "{count} min ago",
|
||||
"hoursAgo": "{count}h ago",
|
||||
"daysAgo": "{count}d ago"
|
||||
},
|
||||
"empty": {
|
||||
"noAlbums": "No albums yet",
|
||||
@@ -177,6 +361,14 @@
|
||||
"noTracks": "No tracks yet",
|
||||
"noPlaylists": "No playlists yet",
|
||||
"noFavorites": "No favorites yet",
|
||||
"queueEmpty": "Queue is empty"
|
||||
"queueEmpty": "Queue is empty",
|
||||
"noResults": "No results found",
|
||||
"noContent": "No content available"
|
||||
},
|
||||
"confirm": {
|
||||
"deletePlaylist": "Are you sure you want to delete this playlist?",
|
||||
"clearQueue": "Clear all tracks from queue?",
|
||||
"clearCache": "Clear all cached data?",
|
||||
"logout": "Are you sure you want to log out?"
|
||||
}
|
||||
}
|
||||
+259
-66
@@ -9,116 +9,238 @@
|
||||
"library": "Biblioteca",
|
||||
"albums": "Álbumes",
|
||||
"artists": "Artistas",
|
||||
"tracks": "Canciones",
|
||||
"playlists": "Playlists",
|
||||
"tracks": "Pistas",
|
||||
"playlists": "Listas",
|
||||
"favorites": "Favoritos",
|
||||
"settings": "Ajustes",
|
||||
"newReleases": "Novedades",
|
||||
"pressAwards": "Premios",
|
||||
"radio": "Radio",
|
||||
"recentlyAdded": "Añadido recientemente"
|
||||
"recentlyAdded": "Agregado Recientemente",
|
||||
"backTo": "Volver a"
|
||||
},
|
||||
"home": {
|
||||
"title": "Inicio",
|
||||
"featuredForYou": "Sugerencias destacadas para ti",
|
||||
"recentlyPlayed": "Escuchado recientemente",
|
||||
"newReleases": "Nuevos lanzamientos",
|
||||
"madeForYou": "Hecho para ti",
|
||||
"topPicks": "Selecciones destacadas"
|
||||
"featuredForYou": "Destacados para ti",
|
||||
"recentlyPlayed": "Escuchado Recientemente",
|
||||
"newReleases": "Novedades",
|
||||
"pressAwards": "Premios de Prensa",
|
||||
"madeForYou": "Hecho para Ti",
|
||||
"topPicks": "Selecciones Destacadas",
|
||||
"yourPlaylists": "Tus Listas",
|
||||
"seeAll": "Ver Todo"
|
||||
},
|
||||
"search": {
|
||||
"title": "Buscar",
|
||||
"placeholder": "Buscar álbumes, artistas, canciones...",
|
||||
"placeholder": "Buscar álbumes, artistas, pistas...",
|
||||
"all": "Todo",
|
||||
"noResults": "No se encontraron resultados",
|
||||
"searching": "Buscando..."
|
||||
"albums": "Álbumes",
|
||||
"tracks": "Pistas",
|
||||
"artists": "Artistas",
|
||||
"noResults": "Sin resultados",
|
||||
"searching": "Buscando...",
|
||||
"recentSearches": "Búsquedas Recientes",
|
||||
"clearHistory": "Limpiar Historial"
|
||||
},
|
||||
"library": {
|
||||
"title": "Biblioteca Local",
|
||||
"albums": "Álbumes",
|
||||
"artists": "Artistas",
|
||||
"tracks": "Pistas",
|
||||
"folders": "Carpetas",
|
||||
"noAlbums": "No hay álbumes en la biblioteca",
|
||||
"noArtists": "No hay artistas en la biblioteca",
|
||||
"noTracks": "No hay pistas en la biblioteca",
|
||||
"noFolders": "No hay carpetas agregadas",
|
||||
"addFolder": "Agregar Carpeta",
|
||||
"removeFolder": "Eliminar",
|
||||
"scan": "Escanear",
|
||||
"scanning": "Escaneando...",
|
||||
"stopScan": "Detener",
|
||||
"scanComplete": "Escaneo completo",
|
||||
"scanCancelled": "Escaneo cancelado",
|
||||
"scanError": "Error de escaneo",
|
||||
"searchPlaceholder": "Buscar...",
|
||||
"searchAlbums": "Buscar álbumes...",
|
||||
"searchArtists": "Buscar artistas...",
|
||||
"searchTracks": "Buscar pistas, álbumes, artistas...",
|
||||
"trackCount": "{count} pistas",
|
||||
"albumCount": "{count} álbumes",
|
||||
"artistCount": "{count} artistas",
|
||||
"groupBy": "Agrupar por",
|
||||
"sortBy": "Ordenar por",
|
||||
"viewAs": "Ver como",
|
||||
"grid": "Cuadrícula",
|
||||
"list": "Lista",
|
||||
"fetchingArtwork": "Obteniendo portada..."
|
||||
},
|
||||
"album": {
|
||||
"tracks": "canciones",
|
||||
"track": "canción",
|
||||
"tracks": "pistas",
|
||||
"track": "pista",
|
||||
"by": "de",
|
||||
"released": "Publicado",
|
||||
"released": "Lanzado",
|
||||
"releaseDate": "Fecha de Lanzamiento",
|
||||
"label": "Sello",
|
||||
"genre": "Género"
|
||||
"genre": "Género",
|
||||
"duration": "Duración",
|
||||
"quality": "Calidad",
|
||||
"play": "Reproducir",
|
||||
"shuffle": "Aleatorio",
|
||||
"addToQueue": "Agregar a la Cola",
|
||||
"addToPlaylist": "Agregar a Lista",
|
||||
"download": "Descargar",
|
||||
"downloadAll": "Descargar Todo",
|
||||
"disc": "Disco"
|
||||
},
|
||||
"artist": {
|
||||
"albums": "Álbumes",
|
||||
"popularTracks": "Canciones populares",
|
||||
"similarArtists": "Artistas similares",
|
||||
"followers": "seguidores"
|
||||
"discography": "Discografía",
|
||||
"eps": "EPs y Sencillos",
|
||||
"epsSingles": "EPs y Sencillos",
|
||||
"live": "Álbumes en Vivo",
|
||||
"liveAlbums": "Álbumes en Vivo",
|
||||
"compilations": "Compilaciones",
|
||||
"appearsOn": "Aparece En",
|
||||
"popularTracks": "Pistas Populares",
|
||||
"similarArtists": "Artistas Similares",
|
||||
"biography": "Biografía",
|
||||
"readMore": "Leer Más",
|
||||
"readLess": "Leer Menos",
|
||||
"followers": "seguidores",
|
||||
"loadMore": "Cargar Más",
|
||||
"noAlbums": "Sin álbumes",
|
||||
"noBiography": "No hay biografía disponible"
|
||||
},
|
||||
"playlist": {
|
||||
"tracks": "canciones",
|
||||
"createNew": "Crear nueva...",
|
||||
"allPlaylists": "Todas las playlists",
|
||||
"myPlaylists": "Mis playlists"
|
||||
"tracks": "pistas",
|
||||
"track": "pista",
|
||||
"createNew": "Crear Nueva...",
|
||||
"createPlaylist": "Crear Lista",
|
||||
"deletePlaylist": "Eliminar Lista",
|
||||
"renamePlaylist": "Renombrar Lista",
|
||||
"allPlaylists": "Todas las Listas",
|
||||
"myPlaylists": "Mis Listas",
|
||||
"qobuzPlaylists": "Listas de Qobuz",
|
||||
"emptyPlaylist": "Esta lista está vacía",
|
||||
"addTracks": "Agregar Pistas",
|
||||
"removeTracks": "Eliminar",
|
||||
"playlistName": "Nombre de la Lista",
|
||||
"description": "Descripción",
|
||||
"public": "Pública",
|
||||
"private": "Privada"
|
||||
},
|
||||
"favorites": {
|
||||
"title": "Favoritos",
|
||||
"albums": "Álbumes",
|
||||
"tracks": "Pistas",
|
||||
"artists": "Artistas",
|
||||
"noFavorites": "Aún no hay favoritos",
|
||||
"addedToFavorites": "Agregado a favoritos",
|
||||
"removedFromFavorites": "Eliminado de favoritos"
|
||||
},
|
||||
"player": {
|
||||
"nowPlaying": "Reproduciendo ahora",
|
||||
"nowPlaying": "Reproduciendo",
|
||||
"queue": "Cola",
|
||||
"lyrics": "Letra",
|
||||
"upNext": "Siguiente",
|
||||
"history": "Historial",
|
||||
"lyrics": "Letras",
|
||||
"noLyrics": "No hay letras disponibles",
|
||||
"fetchingLyrics": "Buscando letras...",
|
||||
"shuffle": "Aleatorio",
|
||||
"repeat": "Repetir",
|
||||
"repeatOne": "Repetir una",
|
||||
"repeatOne": "Repetir Una",
|
||||
"repeatOff": "No Repetir",
|
||||
"previous": "Anterior",
|
||||
"next": "Siguiente",
|
||||
"play": "Reproducir",
|
||||
"pause": "Pausar",
|
||||
"volume": "Volumen",
|
||||
"mute": "Silenciar"
|
||||
"mute": "Silenciar",
|
||||
"unmute": "Activar Sonido",
|
||||
"clearQueue": "Limpiar Cola",
|
||||
"queueEmpty": "La cola está vacía",
|
||||
"playNext": "Reproducir Siguiente",
|
||||
"addToQueue": "Agregar a la Cola",
|
||||
"removeFromQueue": "Quitar de la Cola",
|
||||
"saveQueue": "Guardar como Lista"
|
||||
},
|
||||
"quality": {
|
||||
"mp3": "MP3",
|
||||
"mp3": "MP3 320kbps",
|
||||
"cdQuality": "Calidad CD",
|
||||
"cdQualityDesc": "16-bit / 44.1kHz FLAC",
|
||||
"hiRes": "Hi-Res",
|
||||
"ultraHiRes": "Ultra Hi-Res",
|
||||
"hiResDesc": "24-bit hasta 96kHz FLAC",
|
||||
"ultraHiRes": "Hi-Res 24-bit",
|
||||
"ultraHiResDesc": "24-bit hasta 192kHz FLAC",
|
||||
"flac": "FLAC",
|
||||
"bitDepth": "{depth}-bit",
|
||||
"sampleRate": "{rate} kHz",
|
||||
"lossless": "Sin pérdida"
|
||||
"lossless": "Sin Pérdida",
|
||||
"max": "Máx"
|
||||
},
|
||||
"actions": {
|
||||
"play": "Reproducir",
|
||||
"playAll": "Reproducir todo",
|
||||
"playAll": "Reproducir Todo",
|
||||
"playNow": "Reproducir Ahora",
|
||||
"shuffle": "Aleatorio",
|
||||
"addToQueue": "Añadir a la cola",
|
||||
"addToPlaylist": "Añadir a playlist",
|
||||
"addToFavorites": "Añadir a favoritos",
|
||||
"removeFromFavorites": "Quitar de favoritos",
|
||||
"shuffleAll": "Aleatorio Todo",
|
||||
"addToQueue": "Agregar a la Cola",
|
||||
"addToPlaylist": "Agregar a Lista",
|
||||
"addToFavorites": "Agregar a Favoritos",
|
||||
"removeFromFavorites": "Quitar de Favoritos",
|
||||
"download": "Descargar",
|
||||
"share": "Compartir",
|
||||
"viewAlbum": "Ver álbum",
|
||||
"viewArtist": "Ver artista",
|
||||
"viewAlbum": "Ver Álbum",
|
||||
"viewArtist": "Ver Artista",
|
||||
"goToArtist": "Ir al Artista",
|
||||
"goToAlbum": "Ir al Álbum",
|
||||
"more": "Más",
|
||||
"back": "Atrás",
|
||||
"seeAll": "Ver todo",
|
||||
"seeAll": "Ver Todo",
|
||||
"cancel": "Cancelar",
|
||||
"save": "Guardar",
|
||||
"delete": "Eliminar",
|
||||
"edit": "Editar"
|
||||
"edit": "Editar",
|
||||
"close": "Cerrar",
|
||||
"open": "Abrir",
|
||||
"refresh": "Actualizar",
|
||||
"retry": "Reintentar",
|
||||
"clear": "Limpiar",
|
||||
"clearAll": "Limpiar Todo",
|
||||
"confirm": "Confirmar",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
"ok": "OK",
|
||||
"loading": "Cargando..."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configuración",
|
||||
"title": "Ajustes",
|
||||
"account": {
|
||||
"title": "Cuenta",
|
||||
"loggedInAs": "Conectado como",
|
||||
"subscription": "Suscripción",
|
||||
"logout": "Cerrar sesión",
|
||||
"login": "Iniciar sesión"
|
||||
"logout": "Cerrar Sesión",
|
||||
"login": "Iniciar Sesión"
|
||||
},
|
||||
"audio": {
|
||||
"title": "Audio",
|
||||
"streamingQuality": "Calidad de streaming",
|
||||
"preferHighest": "Preferir la más alta disponible",
|
||||
"outputDevice": "Dispositivo de salida",
|
||||
"exclusiveMode": "Modo exclusivo",
|
||||
"streamingQuality": "Calidad de Streaming",
|
||||
"preferHighest": "Preferir Máxima Calidad",
|
||||
"preferHighestDesc": "Seleccionar automáticamente la mejor calidad para tu suscripción",
|
||||
"outputDevice": "Dispositivo de Salida",
|
||||
"audioDevice": "Dispositivo de Audio",
|
||||
"exclusiveMode": "Modo Exclusivo",
|
||||
"exclusiveModeDesc": "Bloquear dispositivo de audio para uso exclusivo",
|
||||
"dacPassthrough": "Passthrough DAC",
|
||||
"dacPassthroughDesc": "Bypass del mixer del sistema para salida bit-perfect"
|
||||
"dacPassthroughDesc": "Bypass del mixer del sistema para salida bit-perfect",
|
||||
"currentSampleRate": "Tasa de Muestreo Actual"
|
||||
},
|
||||
"playback": {
|
||||
"title": "Reproducción",
|
||||
"gapless": "Reproducción sin pausas",
|
||||
"gapless": "Reproducción Sin Pausas",
|
||||
"crossfade": "Crossfade",
|
||||
"crossfadeSeconds": "{seconds}s",
|
||||
"normalizeVolume": "Normalizar volumen"
|
||||
"normalizeVolume": "Normalizar Volumen"
|
||||
},
|
||||
"appearance": {
|
||||
"title": "Apariencia",
|
||||
@@ -129,53 +251,124 @@
|
||||
"oled": "OLED Negro",
|
||||
"warm": "Cálido"
|
||||
},
|
||||
"accentColor": "Color de acento",
|
||||
"compactMode": "Modo compacto",
|
||||
"language": "Idioma"
|
||||
"accentColor": "Color de Acento",
|
||||
"language": "Idioma",
|
||||
"uiScale": "Escala de UI",
|
||||
"inAppToasts": "Notificaciones en App",
|
||||
"systemNotifications": "Notificaciones del Sistema"
|
||||
},
|
||||
"library": {
|
||||
"title": "Biblioteca",
|
||||
"fetchArtistImages": "Obtener Imágenes de Artistas de Qobuz",
|
||||
"fetchArtistImagesDesc": "Mostrar fotos de artistas de Qobuz en biblioteca local"
|
||||
},
|
||||
"integrations": {
|
||||
"title": "Integraciones",
|
||||
"lastfm": "Last.fm",
|
||||
"spotify": "Spotify",
|
||||
"tidal": "Tidal",
|
||||
"discogs": "Discogs",
|
||||
"connected": "Conectado",
|
||||
"connectedAs": "Conectado como {username}",
|
||||
"notConnected": "No conectado",
|
||||
"connect": "Conectar",
|
||||
"disconnect": "Desconectar",
|
||||
"scrobbling": "Scrobbling"
|
||||
"scrobbling": "Scrobbling",
|
||||
"configureApi": "Configurar API",
|
||||
"apiKeys": "Claves API",
|
||||
"clientId": "Client ID",
|
||||
"clientSecret": "Client Secret",
|
||||
"consumerKey": "Consumer Key",
|
||||
"consumerSecret": "Consumer Secret"
|
||||
},
|
||||
"storage": {
|
||||
"title": "Almacenamiento",
|
||||
"cacheSize": "Tamaño de caché",
|
||||
"clearCache": "Limpiar caché"
|
||||
"cachedTracks": "Pistas en Caché",
|
||||
"cacheSize": "Tamaño de Caché",
|
||||
"clearCache": "Limpiar Caché",
|
||||
"clearing": "Limpiando..."
|
||||
},
|
||||
"downloads": {
|
||||
"title": "Descargas",
|
||||
"downloadedTracks": "Pistas Descargadas",
|
||||
"clearDownloads": "Limpiar Todo",
|
||||
"openFolder": "Abrir Carpeta"
|
||||
},
|
||||
"lyrics": {
|
||||
"title": "Letras",
|
||||
"lyricsCache": "Caché de Letras",
|
||||
"clearLyrics": "Limpiar Letras"
|
||||
},
|
||||
"about": {
|
||||
"title": "Acerca de",
|
||||
"version": "Versión",
|
||||
"sourceCode": "Código Fuente",
|
||||
"reportIssue": "Reportar Problema",
|
||||
"checkUpdates": "Buscar Actualizaciones"
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"login": "Iniciar sesión",
|
||||
"email": "Correo electrónico",
|
||||
"login": "Iniciar Sesión",
|
||||
"email": "Correo Electrónico",
|
||||
"password": "Contraseña",
|
||||
"loginButton": "Entrar",
|
||||
"loggingIn": "Iniciando sesión...",
|
||||
"loginError": "Error al iniciar sesión. Verifica tus credenciales.",
|
||||
"welcomeBack": "Bienvenido de nuevo"
|
||||
"welcomeBack": "Bienvenido de nuevo",
|
||||
"rememberMe": "Recordarme"
|
||||
},
|
||||
"notifications": {
|
||||
"trackAdded": "Pista agregada a la cola",
|
||||
"tracksAdded": "{count} pistas agregadas a la cola",
|
||||
"albumAdded": "Álbum agregado a la cola",
|
||||
"addedToPlaylist": "Agregado a la lista",
|
||||
"removedFromPlaylist": "Eliminado de la lista",
|
||||
"playlistCreated": "Lista creada",
|
||||
"playlistDeleted": "Lista eliminada",
|
||||
"downloadStarted": "Descarga iniciada",
|
||||
"downloadComplete": "Descarga completa",
|
||||
"downloadFailed": "Descarga fallida",
|
||||
"scanComplete": "Escaneo de biblioteca completo",
|
||||
"scanCancelled": "Escaneo de biblioteca cancelado",
|
||||
"scanFailed": "Escaneo de biblioteca fallido",
|
||||
"settingsSaved": "Ajustes guardados",
|
||||
"copied": "Copiado al portapapeles"
|
||||
},
|
||||
"errors": {
|
||||
"generic": "Algo salió mal",
|
||||
"networkError": "Error de red. Verifica tu conexión.",
|
||||
"notFound": "No encontrado",
|
||||
"unauthorized": "Inicia sesión para continuar",
|
||||
"trackNotAvailable": "Esta canción no está disponible para streaming",
|
||||
"qualityNotAvailable": "La calidad solicitada no está disponible"
|
||||
"trackNotAvailable": "Esta pista no está disponible para streaming",
|
||||
"qualityNotAvailable": "La calidad solicitada no está disponible",
|
||||
"loadFailed": "Error al cargar",
|
||||
"playbackFailed": "Error de reproducción",
|
||||
"downloadFailed": "Error de descarga",
|
||||
"saveFailed": "Error al guardar"
|
||||
},
|
||||
"time": {
|
||||
"hours": "h",
|
||||
"minutes": "min",
|
||||
"seconds": "s"
|
||||
"seconds": "s",
|
||||
"justNow": "Ahora mismo",
|
||||
"minutesAgo": "hace {count} min",
|
||||
"hoursAgo": "hace {count}h",
|
||||
"daysAgo": "hace {count}d"
|
||||
},
|
||||
"empty": {
|
||||
"noAlbums": "Sin álbumes aún",
|
||||
"noArtists": "Sin artistas aún",
|
||||
"noTracks": "Sin canciones aún",
|
||||
"noPlaylists": "Sin playlists aún",
|
||||
"noFavorites": "Sin favoritos aún",
|
||||
"queueEmpty": "La cola está vacía"
|
||||
"noAlbums": "Aún no hay álbumes",
|
||||
"noArtists": "Aún no hay artistas",
|
||||
"noTracks": "Aún no hay pistas",
|
||||
"noPlaylists": "Aún no hay listas",
|
||||
"noFavorites": "Aún no hay favoritos",
|
||||
"queueEmpty": "La cola está vacía",
|
||||
"noResults": "Sin resultados",
|
||||
"noContent": "No hay contenido disponible"
|
||||
},
|
||||
"confirm": {
|
||||
"deletePlaylist": "¿Estás seguro de que quieres eliminar esta lista?",
|
||||
"clearQueue": "¿Limpiar todas las pistas de la cola?",
|
||||
"clearCache": "¿Limpiar todos los datos en caché?",
|
||||
"logout": "¿Estás seguro de que quieres cerrar sesión?"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user