feat(ui): design token discipline, accessibility and i18n pass
- Replace all hardcoded Color literals outside lib/tema with theme tokens (new static brand palette in PluriWaveTokens); media notification uses the brand color instead of the Material default purple - Favorite button on station cards grows to a 48dp target and becomes an independent semantics node for screen readers (Semantics container fix) - All flutter_animate call sites route through the PluriAnimate reduced-motion gate (zero direct .animate() left) - Locale-aware short dates via intl DateFormat (new lib/l10n/formato_fechas.dart) replacing the hardcoded DD/MM/YYYY; proper plural messages for the favorites counter; example stream URL as a localized key - all 13 locales - Rounded shimmer placeholders matching card radii; shimmer loading state in search instead of a bare spinner; rounded icon variants unified in settings; bottom-sheet conventions on the custom station form - Fix latent debug crash: vacation editor read AppLocalizations in initState - 11 new tests (121 total green), flutter analyze clean
This commit is contained in:
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "الخميس",
|
||||
"weekdayShortFriday": "الجمعة",
|
||||
"weekdayShortSaturday": "السبت",
|
||||
"weekdayShortSunday": "الأحد"
|
||||
"weekdayShortSunday": "الأحد",
|
||||
"stationCount": "{count, plural, one{محطة واحدة} two{محطتان} few{{count} محطات} other{{count} محطة}}",
|
||||
"alarmIconLabel": "منبه موسيقي",
|
||||
"vacationIconLabel": "وضع الإجازة",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "বৃহস্পতি",
|
||||
"weekdayShortFriday": "শুক্র",
|
||||
"weekdayShortSaturday": "শনি",
|
||||
"weekdayShortSunday": "রবি"
|
||||
"weekdayShortSunday": "রবি",
|
||||
"stationCount": "{count, plural, =1{১টি স্টেশন} other{{count}টি স্টেশন}}",
|
||||
"alarmIconLabel": "মিউজিক অ্যালার্ম",
|
||||
"vacationIconLabel": "ছুটির মোড",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Do",
|
||||
"weekdayShortFriday": "Fr",
|
||||
"weekdayShortSaturday": "Sa",
|
||||
"weekdayShortSunday": "So"
|
||||
"weekdayShortSunday": "So",
|
||||
"stationCount": "{count, plural, =1{1 Sender} other{{count} Sender}}",
|
||||
"alarmIconLabel": "Musikwecker",
|
||||
"vacationIconLabel": "Urlaubsmodus",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Thu",
|
||||
"weekdayShortFriday": "Fri",
|
||||
"weekdayShortSaturday": "Sat",
|
||||
"weekdayShortSunday": "Sun"
|
||||
"weekdayShortSunday": "Sun",
|
||||
"stationCount": "{count, plural, =1{1 station} other{{count} stations}}",
|
||||
"alarmIconLabel": "Musical alarm",
|
||||
"vacationIconLabel": "Vacation mode",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+12
-2
@@ -568,6 +568,16 @@
|
||||
"weekdayShortThursday": "Jue",
|
||||
"weekdayShortFriday": "Vie",
|
||||
"weekdayShortSaturday": "Sáb",
|
||||
"weekdayShortSunday": "Dom"
|
||||
|
||||
"weekdayShortSunday": "Dom",
|
||||
"stationCount": "{count, plural, =1{1 emisora} other{{count} emisoras}}",
|
||||
"alarmIconLabel": "Alarma musical",
|
||||
"vacationIconLabel": "Modo vacaciones",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio",
|
||||
"@stationCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Jeu",
|
||||
"weekdayShortFriday": "Ven",
|
||||
"weekdayShortSaturday": "Sam",
|
||||
"weekdayShortSunday": "Dim"
|
||||
"weekdayShortSunday": "Dim",
|
||||
"stationCount": "{count, plural, =1{1 station} other{{count} stations}}",
|
||||
"alarmIconLabel": "Alarme musicale",
|
||||
"vacationIconLabel": "Mode vacances",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "गुरु",
|
||||
"weekdayShortFriday": "शुक्र",
|
||||
"weekdayShortSaturday": "शनि",
|
||||
"weekdayShortSunday": "रवि"
|
||||
"weekdayShortSunday": "रवि",
|
||||
"stationCount": "{count, plural, =1{1 स्टेशन} other{{count} स्टेशन}}",
|
||||
"alarmIconLabel": "संगीत अलार्म",
|
||||
"vacationIconLabel": "अवकाश मोड",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Kam",
|
||||
"weekdayShortFriday": "Jum",
|
||||
"weekdayShortSaturday": "Sab",
|
||||
"weekdayShortSunday": "Min"
|
||||
"weekdayShortSunday": "Min",
|
||||
"stationCount": "{count, plural, other{{count} stasiun}}",
|
||||
"alarmIconLabel": "Alarm musik",
|
||||
"vacationIconLabel": "Mode liburan",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Gio",
|
||||
"weekdayShortFriday": "Ven",
|
||||
"weekdayShortSaturday": "Sab",
|
||||
"weekdayShortSunday": "Dom"
|
||||
"weekdayShortSunday": "Dom",
|
||||
"stationCount": "{count, plural, =1{1 stazione} other{{count} stazioni}}",
|
||||
"alarmIconLabel": "Sveglia musicale",
|
||||
"vacationIconLabel": "Modalità vacanza",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "木",
|
||||
"weekdayShortFriday": "金",
|
||||
"weekdayShortSaturday": "土",
|
||||
"weekdayShortSunday": "日"
|
||||
"weekdayShortSunday": "日",
|
||||
"stationCount": "{count, plural, other{{count}局}}",
|
||||
"alarmIconLabel": "ミュージックアラーム",
|
||||
"vacationIconLabel": "休暇モード",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Qui",
|
||||
"weekdayShortFriday": "Sex",
|
||||
"weekdayShortSaturday": "Sáb",
|
||||
"weekdayShortSunday": "Dom"
|
||||
"weekdayShortSunday": "Dom",
|
||||
"stationCount": "{count, plural, =1{1 estação} other{{count} estações}}",
|
||||
"alarmIconLabel": "Alarme musical",
|
||||
"vacationIconLabel": "Modo férias",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "Чт",
|
||||
"weekdayShortFriday": "Пт",
|
||||
"weekdayShortSaturday": "Сб",
|
||||
"weekdayShortSunday": "Вс"
|
||||
"weekdayShortSunday": "Вс",
|
||||
"stationCount": "{count, plural, one{{count} станция} few{{count} станции} other{{count} станций}}",
|
||||
"alarmIconLabel": "Музыкальный будильник",
|
||||
"vacationIconLabel": "Режим отпуска",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
+5
-1
@@ -612,5 +612,9 @@
|
||||
"weekdayShortThursday": "周四",
|
||||
"weekdayShortFriday": "周五",
|
||||
"weekdayShortSaturday": "周六",
|
||||
"weekdayShortSunday": "周日"
|
||||
"weekdayShortSunday": "周日",
|
||||
"stationCount": "{count, plural, other{{count} 个电台}}",
|
||||
"alarmIconLabel": "音乐闹钟",
|
||||
"vacationIconLabel": "假期模式",
|
||||
"streamUrlHint": "https://stream.example.com:8000/radio"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
/// Locale-aware short date (S5-R4).
|
||||
///
|
||||
/// Replaces the old hardcoded `DD/MM/YYYY` pattern, which was wrong for
|
||||
/// locales like en-US (M/D/Y) or ja (Y/M/D). [localeTag] accepts both
|
||||
/// BCP-47 ('en-US') and ICU ('en_US') forms — intl canonicalizes them.
|
||||
///
|
||||
/// Date symbols for the active locale are loaded by
|
||||
/// GlobalMaterialLocalizations, so any widget below MaterialApp can call
|
||||
/// this safely.
|
||||
String fechaCortaLocalizada(String localeTag, DateTime fecha) =>
|
||||
DateFormat.yMd(localeTag).format(fecha);
|
||||
@@ -2245,6 +2245,30 @@ abstract class AppLocalizations {
|
||||
/// In es, this message translates to:
|
||||
/// **'Dom'**
|
||||
String get weekdayShortSunday;
|
||||
|
||||
/// No description provided for @stationCount.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'{count, plural, =1{1 emisora} other{{count} emisoras}}'**
|
||||
String stationCount(int count);
|
||||
|
||||
/// No description provided for @alarmIconLabel.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Alarma musical'**
|
||||
String get alarmIconLabel;
|
||||
|
||||
/// No description provided for @vacationIconLabel.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Modo vacaciones'**
|
||||
String get vacationIconLabel;
|
||||
|
||||
/// No description provided for @streamUrlHint.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'https://stream.example.com:8000/radio'**
|
||||
String get streamUrlHint;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -1203,4 +1203,26 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'الأحد';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count محطة',
|
||||
few: '$count محطات',
|
||||
two: 'محطتان',
|
||||
one: 'محطة واحدة',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'منبه موسيقي';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'وضع الإجازة';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1212,4 +1212,24 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'রবি';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$countটি স্টেশন',
|
||||
one: '১টি স্টেশন',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'মিউজিক অ্যালার্ম';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'ছুটির মোড';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1222,4 +1222,24 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'So';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count Sender',
|
||||
one: '1 Sender',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Musikwecker';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Urlaubsmodus';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1208,4 +1208,24 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Sun';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count stations',
|
||||
one: '1 station',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Musical alarm';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Vacation mode';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1217,4 +1217,24 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Dom';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count emisoras',
|
||||
one: '1 emisora',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Alarma musical';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Modo vacaciones';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1227,4 +1227,24 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Dim';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count stations',
|
||||
one: '1 station',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Alarme musicale';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Mode vacances';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1211,4 +1211,24 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'रवि';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count स्टेशन',
|
||||
one: '1 स्टेशन',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'संगीत अलार्म';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'अवकाश मोड';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1217,4 +1217,23 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Min';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count stasiun',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Alarm musik';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Mode liburan';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1222,4 +1222,24 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Dom';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count stazioni',
|
||||
one: '1 stazione',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Sveglia musicale';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Modalità vacanza';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1173,4 +1173,23 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => '日';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count局',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'ミュージックアラーム';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => '休暇モード';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1214,4 +1214,24 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Dom';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count estações',
|
||||
one: '1 estação',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Alarme musical';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Modo férias';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1217,4 +1217,25 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => 'Вс';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count станций',
|
||||
few: '$count станции',
|
||||
one: '$count станция',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => 'Музыкальный будильник';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => 'Режим отпуска';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
@@ -1168,4 +1168,23 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get weekdayShortSunday => '周日';
|
||||
|
||||
@override
|
||||
String stationCount(int count) {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count 个电台',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get alarmIconLabel => '音乐闹钟';
|
||||
|
||||
@override
|
||||
String get vacationIconLabel => '假期模式';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user