l10n: localize settings, store, and metadata UI strings

Wire remaining hardcoded strings in about, download region picker, file
organization settings, extension repo snackbars, release type badges,
metadata queue actions, online cover labels, and update changelog fallback.
This commit is contained in:
zarzet
2026-06-30 03:40:45 +07:00
parent 5dc0980ced
commit d882fc292c
7 changed files with 75 additions and 52 deletions
+3 -1
View File
@@ -1967,7 +1967,9 @@ class _ArtistScreenState extends ConsumerState<ArtistScreen> {
borderRadius: BorderRadius.circular(4),
),
child: Text(
album.albumType == 'ep' ? 'EP' : 'Single',
album.albumType == 'ep'
? context.l10n.releaseTypeEp
: context.l10n.releaseTypeSingle,
style: const TextStyle(
color: Colors.white,
fontSize: 10,
+7 -4
View File
@@ -608,8 +608,8 @@ class _RepoTabState extends ConsumerState<RepoTab> {
SnackBar(
content: Text(
success
? '${ext.displayName} installed. Enable it in Settings > Extensions'
: 'Failed to install ${ext.displayName}',
? context.l10n.snackbarExtensionInstalledEnable(ext.displayName)
: context.l10n.snackbarFailedToInstallNamed(ext.displayName),
),
behavior: SnackBarBehavior.floating,
),
@@ -629,8 +629,11 @@ class _RepoTabState extends ConsumerState<RepoTab> {
SnackBar(
content: Text(
success
? '${ext.displayName} updated to v${ext.version}'
: 'Failed to update ${ext.displayName}',
? context.l10n.snackbarExtensionUpdatedVersion(
ext.displayName,
ext.version,
)
: context.l10n.snackbarFailedToUpdateNamed(ext.displayName),
),
behavior: SnackBarBehavior.floating,
),
+1 -3
View File
@@ -140,9 +140,7 @@ class AboutPage extends StatelessWidget {
_AboutSettingsItem(
icon: Icons.lyrics_outlined,
title: 'Paxsenix',
subtitle:
'Lyrics proxy for Musixmatch, Netease, Apple Music, '
'QQ Music, Spotify, Deezer, YouTube, Kugou, and Genius',
subtitle: context.l10n.aboutPaxsenixSubtitle,
onTap: () => _launchUrl('https://lyrics.paxsenix.org'),
showDivider: false,
),
@@ -281,7 +281,10 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
SettingsItem(
icon: Icons.public,
title: context.l10n.downloadSongLinkRegion,
subtitle: _getSongLinkRegionLabel(settings.songLinkRegion),
subtitle: _getSongLinkRegionLabel(
context,
settings.songLinkRegion,
),
onTap: () => _showSongLinkRegionPicker(
context,
ref,
@@ -309,26 +312,45 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
);
}
String _getSongLinkRegionLabel(String code) {
const names = <String, String>{
'US': 'United States',
'GB': 'United Kingdom',
'FR': 'France',
'DE': 'Germany',
'JP': 'Japan',
'KR': 'South Korea',
'IN': 'India',
'ID': 'Indonesia',
'BR': 'Brazil',
'MX': 'Mexico',
'AU': 'Australia',
'CA': 'Canada',
'XK': 'Kosovo',
};
String _regionCountryName(BuildContext context, String code) {
final l10n = context.l10n;
switch (code) {
case 'US':
return l10n.regionCountryUS;
case 'GB':
return l10n.regionCountryGB;
case 'FR':
return l10n.regionCountryFR;
case 'DE':
return l10n.regionCountryDE;
case 'JP':
return l10n.regionCountryJP;
case 'KR':
return l10n.regionCountryKR;
case 'IN':
return l10n.regionCountryIN;
case 'ID':
return l10n.regionCountryID;
case 'BR':
return l10n.regionCountryBR;
case 'MX':
return l10n.regionCountryMX;
case 'AU':
return l10n.regionCountryAU;
case 'CA':
return l10n.regionCountryCA;
case 'XK':
return l10n.regionCountryXK;
default:
return code;
}
}
String _getSongLinkRegionLabel(BuildContext context, String code) {
final normalized = code.trim().toUpperCase();
final effective = normalized.isEmpty ? 'US' : normalized;
final name = names[effective];
return name == null ? effective : '$effective - $name';
final name = _regionCountryName(context, effective);
return name == effective ? effective : '$effective - $name';
}
IconData _qualityIcon(String qualityId) {
@@ -766,21 +788,6 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
'ZM',
'ZW',
];
const names = <String, String>{
'US': 'United States',
'GB': 'United Kingdom',
'FR': 'France',
'DE': 'Germany',
'JP': 'Japan',
'KR': 'South Korea',
'IN': 'India',
'ID': 'Indonesia',
'BR': 'Brazil',
'MX': 'Mexico',
'AU': 'Australia',
'CA': 'Canada',
'XK': 'Kosovo',
};
final colorScheme = Theme.of(context).colorScheme;
final normalizedCurrent = current.trim().toUpperCase();
showModalBottomSheet<void>(
@@ -821,9 +828,12 @@ class _DownloadSettingsPageState extends ConsumerState<DownloadSettingsPage> {
itemBuilder: (context, index) {
final code = regions[index];
final isSelected = code == normalizedCurrent;
final countryName = _regionCountryName(context, code);
return ListTile(
title: Text(code),
subtitle: names[code] != null ? Text(names[code]!) : null,
subtitle: countryName != code
? Text(countryName)
: null,
trailing: isSelected
? Icon(Icons.check, color: colorScheme.primary)
: null,
@@ -424,11 +424,14 @@ class _FilesSettingsPageState extends ConsumerState<FilesSettingsPage> {
required bool usePrimaryArtistOnly,
required bool filterAlbumArtistContributors,
}) {
final l10n = context.l10n;
final statuses = <String>[
usePrimaryArtistOnly ? 'Primary only: On' : 'Primary only: Off',
usePrimaryArtistOnly
? l10n.downloadPrimaryArtistOnlyOn
: l10n.downloadPrimaryArtistOnlyOff,
filterAlbumArtistContributors
? 'Album Artist metadata: Primary only'
: 'Album Artist metadata: Full',
? l10n.downloadAlbumArtistMetadataPrimaryOnly
: l10n.downloadAlbumArtistMetadataFull,
];
return statuses.join(' | ');
}
+7 -3
View File
@@ -8,6 +8,7 @@ class _ResolvedAutoFillTrack {
}
class _EditMetadataSheet extends StatefulWidget {
static const _onlineCoverSentinel = '__online_cover__';
final ColorScheme colorScheme;
final Map<String, String> initialValues;
final String filePath;
@@ -941,7 +942,7 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
setState(() {
_selectedCoverPath = coverOutput;
_selectedCoverTempDir = tempDir.path;
_selectedCoverName = 'Online cover';
_selectedCoverName = _EditMetadataSheet._onlineCoverSentinel;
});
filledCount++;
}
@@ -1623,8 +1624,11 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
child: _buildCoverPreviewTile(
cs: cs,
path: _selectedCoverPath!,
label:
_selectedCoverName ?? context.l10n.trackCoverSelected,
label: _selectedCoverName ==
_EditMetadataSheet._onlineCoverSentinel
? context.l10n.trackCoverOnline
: (_selectedCoverName ??
context.l10n.trackCoverSelected),
),
),
],
+6 -3
View File
@@ -223,7 +223,10 @@ class _UpdateDialogState extends State<UpdateDialog> {
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Text(
_formatChangelog(widget.updateInfo.changelog),
_formatChangelog(
widget.updateInfo.changelog,
context.l10n.updateSeeReleaseNotes,
),
style: Theme.of(context).textTheme.bodySmall?.copyWith(height: 1.5),
),
),
@@ -299,7 +302,7 @@ class _UpdateDialogState extends State<UpdateDialog> {
}
/// Format changelog - clean up markdown and extract relevant content
String _formatChangelog(String changelog) {
String _formatChangelog(String changelog, String emptyFallback) {
var content = changelog;
final whatsNewMatch = _whatsNewPattern.firstMatch(content);
@@ -352,7 +355,7 @@ class _UpdateDialogState extends State<UpdateDialog> {
formatted = '${formatted.substring(0, 2000)}...';
}
return formatted.isEmpty ? 'See release notes for details.' : formatted;
return formatted.isEmpty ? emptyFallback : formatted;
}
}