mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-05-21 15:36:50 +02:00
feat: add translators section in about page and fix ARB locale format
This commit is contained in:
@@ -107,6 +107,7 @@ abstract class AppLocalizations {
|
||||
Locale('de'),
|
||||
Locale('en'),
|
||||
Locale('es'),
|
||||
Locale('es', 'ES'),
|
||||
Locale('fr'),
|
||||
Locale('hi'),
|
||||
Locale('id'),
|
||||
@@ -114,6 +115,7 @@ abstract class AppLocalizations {
|
||||
Locale('ko'),
|
||||
Locale('nl'),
|
||||
Locale('pt'),
|
||||
Locale('pt', 'PT'),
|
||||
Locale('ru'),
|
||||
Locale('zh'),
|
||||
Locale('zh', 'CN'),
|
||||
@@ -816,6 +818,12 @@ abstract class AppLocalizations {
|
||||
/// **'The talented artist who created our beautiful app logo!'**
|
||||
String get aboutLogoArtist;
|
||||
|
||||
/// Section for translators
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Translators'**
|
||||
String get aboutTranslators;
|
||||
|
||||
/// Section for special thanks
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
@@ -3699,6 +3707,22 @@ class _AppLocalizationsDelegate
|
||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||
// Lookup logic when language+country codes are specified.
|
||||
switch (locale.languageCode) {
|
||||
case 'es':
|
||||
{
|
||||
switch (locale.countryCode) {
|
||||
case 'ES':
|
||||
return AppLocalizationsEsEs();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'pt':
|
||||
{
|
||||
switch (locale.countryCode) {
|
||||
case 'PT':
|
||||
return AppLocalizationsPtPt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'zh':
|
||||
{
|
||||
switch (locale.countryCode) {
|
||||
|
||||
@@ -115,7 +115,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get settingsTitle => 'Einstellungen';
|
||||
|
||||
@override
|
||||
String get settingsDownload => 'Download';
|
||||
String get settingsDownload => 'Herunterladen';
|
||||
|
||||
@override
|
||||
String get settingsAppearance => 'Erscheinungsbild';
|
||||
@@ -130,7 +130,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get settingsAbout => 'Über';
|
||||
|
||||
@override
|
||||
String get downloadTitle => 'Download';
|
||||
String get downloadTitle => 'Herunterladen';
|
||||
|
||||
@override
|
||||
String get downloadLocation => 'Download-Speicherort';
|
||||
@@ -410,40 +410,46 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
'Der talentierte Künstler, der unser wunderschönes App-Logo entworfen hat!';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Besonderer Dank';
|
||||
|
||||
@override
|
||||
String get aboutLinks => 'Links';
|
||||
|
||||
@override
|
||||
String get aboutMobileSource => 'Mobile source code';
|
||||
String get aboutMobileSource => 'Mobiler Quellcode';
|
||||
|
||||
@override
|
||||
String get aboutPCSource => 'PC source code';
|
||||
String get aboutPCSource => 'PC Quellcode';
|
||||
|
||||
@override
|
||||
String get aboutReportIssue => 'Report an issue';
|
||||
String get aboutReportIssue => 'Problem melden';
|
||||
|
||||
@override
|
||||
String get aboutReportIssueSubtitle => 'Report any problems you encounter';
|
||||
String get aboutReportIssueSubtitle =>
|
||||
'Melde jedes Problem, die dir auftreten';
|
||||
|
||||
@override
|
||||
String get aboutFeatureRequest => 'Feature request';
|
||||
String get aboutFeatureRequest => 'Feature vorschlagen';
|
||||
|
||||
@override
|
||||
String get aboutFeatureRequestSubtitle => 'Suggest new features for the app';
|
||||
String get aboutFeatureRequestSubtitle =>
|
||||
'Schlage neue Funktionen für die App vor';
|
||||
|
||||
@override
|
||||
String get aboutSupport => 'Support';
|
||||
|
||||
@override
|
||||
String get aboutBuyMeCoffee => 'Buy me a coffee';
|
||||
String get aboutBuyMeCoffee => 'Spendiere mir einen Kaffee';
|
||||
|
||||
@override
|
||||
String get aboutBuyMeCoffeeSubtitle => 'Support development on Ko-fi';
|
||||
String get aboutBuyMeCoffeeSubtitle =>
|
||||
'Unterstütze die Entwicklung auf Ko-fi';
|
||||
|
||||
@override
|
||||
String get aboutApp => 'App';
|
||||
@@ -453,25 +459,25 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get aboutBinimumDesc =>
|
||||
'The creator of QQDL & HiFi API. Without this API, Tidal downloads wouldn\'t exist!';
|
||||
'Der Schöpfer der QQDL & HiFi API. Ohne diese API gäbe es keine Tidal-Downloads!';
|
||||
|
||||
@override
|
||||
String get aboutSachinsenalDesc =>
|
||||
'The original HiFi project creator. The foundation of Tidal integration!';
|
||||
'Der ursprüngliche Entwickler des HiFi-Projekts. Die Grundlage der Tidal-Integration!';
|
||||
|
||||
@override
|
||||
String get aboutDoubleDouble => 'DoubleDouble';
|
||||
|
||||
@override
|
||||
String get aboutDoubleDoubleDesc =>
|
||||
'Amazing API for Amazon Music downloads. Thank you for making it free!';
|
||||
'Wundervolle API für Amazon Music Downloads.\nVielen Dank, dass Sie sie kostenlos zur Verfügung stellen!';
|
||||
|
||||
@override
|
||||
String get aboutDabMusic => 'DAB Music';
|
||||
|
||||
@override
|
||||
String get aboutDabMusicDesc =>
|
||||
'The best Qobuz streaming API. Hi-Res downloads wouldn\'t be possible without this!';
|
||||
'Die beste Qobuz-Streaming-API. Hi-Res-Downloads wären ohne diese nicht möglich!';
|
||||
|
||||
@override
|
||||
String get aboutAppDescription =>
|
||||
|
||||
@@ -402,6 +402,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -402,6 +402,9 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
|
||||
|
||||
@@ -402,6 +402,9 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
|
||||
|
||||
@@ -406,6 +406,9 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'Seniman berbakat yang membuat logo aplikasi kita yang indah!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Terima Kasih Khusus';
|
||||
|
||||
|
||||
@@ -402,6 +402,9 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'スペシャルサンクス';
|
||||
|
||||
|
||||
@@ -402,6 +402,9 @@ class AppLocalizationsKo extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
|
||||
|
||||
@@ -402,6 +402,9 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -414,6 +414,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'Талантливый художник, который создал наш красивый логотип приложения!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Особая благодарность';
|
||||
|
||||
@@ -1533,7 +1536,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get trackFileInfo => 'Информация о файле';
|
||||
|
||||
@override
|
||||
String get trackLyrics => 'Тексты песен';
|
||||
String get trackLyrics => 'Текст песни';
|
||||
|
||||
@override
|
||||
String get trackFileNotFound => 'Файл не найден';
|
||||
@@ -1545,7 +1548,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get trackOpenInSpotify => 'Открыть в Spotify';
|
||||
|
||||
@override
|
||||
String get trackTrackName => 'Название трека';
|
||||
String get trackTrackName => 'Название';
|
||||
|
||||
@override
|
||||
String get trackArtist => 'Исполнитель';
|
||||
|
||||
@@ -402,6 +402,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get aboutLogoArtist =>
|
||||
'The talented artist who created our beautiful app logo!';
|
||||
|
||||
@override
|
||||
String get aboutTranslators => 'Translators';
|
||||
|
||||
@override
|
||||
String get aboutSpecialThanks => 'Special Thanks';
|
||||
|
||||
@@ -4056,7 +4059,7 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
|
||||
String get homeSupports => 'Supports: Track, Album, Playlist, Artist URLs';
|
||||
|
||||
@override
|
||||
String get homeRecent => 'Recent';
|
||||
String get homeRecent => '最新的';
|
||||
|
||||
@override
|
||||
String get historyTitle => 'History';
|
||||
|
||||
@@ -290,6 +290,8 @@
|
||||
"@aboutOriginalCreator": {"description": "Role description for original creator"},
|
||||
"aboutLogoArtist": "The talented artist who created our beautiful app logo!",
|
||||
"@aboutLogoArtist": {"description": "Role description for logo artist"},
|
||||
"aboutTranslators": "Translators",
|
||||
"@aboutTranslators": {"description": "Section for translators"},
|
||||
"aboutSpecialThanks": "Special Thanks",
|
||||
"@aboutSpecialThanks": {"description": "Section for special thanks"},
|
||||
"aboutLinks": "Links",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@locale": "es-ES",
|
||||
"@@locale": "es_ES",
|
||||
"@@last_modified": "2026-01-16",
|
||||
"appName": "SpotiFLAC",
|
||||
"@appName": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@locale": "pt-PT",
|
||||
"@@locale": "pt_PT",
|
||||
"@@last_modified": "2026-01-16",
|
||||
"appName": "SpotiFLAC",
|
||||
"@appName": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@locale": "zh-CN",
|
||||
"@@locale": "zh_CN",
|
||||
"@@last_modified": "2026-01-16",
|
||||
"appName": "SpotiFLAC",
|
||||
"@appName": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@locale": "zh-TW",
|
||||
"@@locale": "zh_TW",
|
||||
"@@last_modified": "2026-01-16",
|
||||
"appName": "SpotiFLAC",
|
||||
"@appName": {
|
||||
|
||||
@@ -86,6 +86,13 @@ class AboutPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: SettingsSectionHeader(title: context.l10n.aboutTranslators),
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: _TranslatorsSection(),
|
||||
),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: SettingsSectionHeader(title: context.l10n.aboutSpecialThanks),
|
||||
),
|
||||
@@ -395,7 +402,149 @@ class _ContributorItem extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Settings item with 40x40 icon area to align with contributor avatars
|
||||
/// Translator data model
|
||||
class _Translator {
|
||||
final String name;
|
||||
final String githubUsername;
|
||||
final String language;
|
||||
final String flag;
|
||||
|
||||
const _Translator({
|
||||
required this.name,
|
||||
required this.githubUsername,
|
||||
required this.language,
|
||||
required this.flag,
|
||||
});
|
||||
}
|
||||
|
||||
/// Translators section with compact chip-style layout
|
||||
class _TranslatorsSection extends StatelessWidget {
|
||||
const _TranslatorsSection();
|
||||
|
||||
static const List<_Translator> _translators = [
|
||||
_Translator(
|
||||
name: 'Pedro Marcondes',
|
||||
githubUsername: 'justapedro',
|
||||
language: 'Portuguese',
|
||||
flag: '🇵🇹',
|
||||
),
|
||||
_Translator(
|
||||
name: 'Credits 125',
|
||||
githubUsername: 'credits125',
|
||||
language: 'Spanish',
|
||||
flag: '🇪🇸',
|
||||
),
|
||||
_Translator(
|
||||
name: 'Владислав',
|
||||
githubUsername: 'OdiNoKiY_KoT',
|
||||
language: 'Russian',
|
||||
flag: '🇷🇺',
|
||||
),
|
||||
_Translator(
|
||||
name: 'Max',
|
||||
githubUsername: 'Amonoman',
|
||||
language: 'German',
|
||||
flag: '🇩🇪',
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
final cardColor = isDark
|
||||
? Color.alphaBlend(Colors.white.withValues(alpha: 0.08), colorScheme.surface)
|
||||
: colorScheme.surfaceContainerHighest;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: cardColor,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: _translators.map((translator) => _TranslatorChip(
|
||||
translator: translator,
|
||||
)).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Individual translator chip
|
||||
class _TranslatorChip extends StatelessWidget {
|
||||
final _Translator translator;
|
||||
|
||||
const _TranslatorChip({required this.translator});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Material(
|
||||
color: colorScheme.secondaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: InkWell(
|
||||
onTap: () => _launchGitHub(translator.githubUsername),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: 'https://github.com/${translator.githubUsername}.png',
|
||||
width: 20,
|
||||
height: 20,
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
color: colorScheme.surface,
|
||||
child: Icon(Icons.person, size: 12, color: colorScheme.onSurfaceVariant),
|
||||
),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
color: colorScheme.surface,
|
||||
child: Icon(Icons.person, size: 12, color: colorScheme.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
translator.name,
|
||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||
color: colorScheme.onSecondaryContainer,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
translator.flag,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _launchGitHub(String username) async {
|
||||
final uri = Uri.parse('https://github.com/$username');
|
||||
await launchUrl(uri, mode: LaunchMode.inAppBrowserView);
|
||||
}
|
||||
}
|
||||
|
||||
class _AboutSettingsItem extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String title;
|
||||
|
||||
Reference in New Issue
Block a user