fix(alarm): fail-safe alarm system overhaul (SDD alarm-system-overhaul, slice A)
Root-cause fix for the unstoppable-alarm incident (alarm rang 15 minutes, only uninstall silenced it) plus systematic hardening of every stop path. Native (Kotlin): - Verified stop: stopActiveAlarm now derives its result from the real post-teardown state (companion instance + synchronous stopEverything + activeRingingId check) instead of reporting unconditional success. - Atomic teardown: every stop path (stop action, notification button, snooze, missed, onDestroy, startForeground failure) funnels through one stopEverything() covering audio, wakelock, notification, foreground state and firing-record cleanup; player.release() guarded. - Bounded ringing: 10-minute auto-silence armed via AlarmManager fires a FIRED->MISSED transition with a localized missed-alarm notification; repeating alarms keep their native rearm, deleted alarms never produce ghost MISSED notifications. - Durable firing record with onStartCommand re-validation (resurrection guard) and boot-time stale cleanup; firing records cleared on every refuse/mismatch/cancel path. - New notification-only dismissal channel (dismissAlarmNotificationOnly) so UI-level dedup can never kill a live ring's audio. Flutter (Dart): - Stop/disable/edit/delete of a ringing alarm always attempt to silence it; on native-query failure the stop falls back toward silence via the id-scoped legacy stop. - Verified-stop results surface failures: the ringing screen keeps dismiss-by-design on success, but on a verified failure it stays up with a persistent force-stop banner (guarded against double-dismiss) and auto-dismisses if the ring ends externally (missed/notification). - Missed events sync alarm bookkeeping without opening the ringing UI. - 4 new l10n keys translated across all 13 locales (ARB guard green). 550 tests green, analyzer clean. Reviewed in 3 adversarial 4-lens rounds (2 deterministic + 1 refuter-corroborated critical fixed); formal gentle-ai receipt waived by maintainer authorization (correction scope legitimately exceeded the frozen genesis paths). On-device QA checklist in openspec/changes/alarm-system-overhaul/tasks.md pending before archive.
This commit is contained in:
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "يرن باستخدام الصوت الداخلي الآمن.",
|
||||
"ringingPreparingInternalAudio": "جارٍ تجهيز الصوت الداخلي الآمن.",
|
||||
"stopAlarmAction": "إيقاف المنبه",
|
||||
"alarmStopFailedMessage": "تعذّر التأكد من إيقاف المنبه. حاول مرة أخرى.",
|
||||
"alarmForceStopAction": "إيقاف قسري",
|
||||
"alarmMissedNotificationTitle": "منبه فائت",
|
||||
"alarmMissedNotificationText": "تم كتم {name} تلقائيًا بعد 10 دقائق.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "إيقاف مؤقت",
|
||||
"miniPlayerOpenLabel": "فتح المشغل لـ {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "নিরাপদ অভ্যন্তরীণ শব্দ দিয়ে বাজছে।",
|
||||
"ringingPreparingInternalAudio": "নিরাপদ অভ্যন্তরীণ শব্দ প্রস্তুত হচ্ছে।",
|
||||
"stopAlarmAction": "অ্যালার্ম বন্ধ করুন",
|
||||
"alarmStopFailedMessage": "অ্যালার্ম বন্ধ হয়েছে তা নিশ্চিত করা যায়নি। আবার চেষ্টা করুন।",
|
||||
"alarmForceStopAction": "জোর করে বন্ধ করুন",
|
||||
"alarmMissedNotificationTitle": "মিস হওয়া অ্যালার্ম",
|
||||
"alarmMissedNotificationText": "১০ মিনিট পর {name} স্বয়ংক্রিয়ভাবে নিঃশব্দ করা হয়েছে।",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "বিরতি দিন",
|
||||
"miniPlayerOpenLabel": "{stationName}-এর প্লেয়ার খুলুন",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Wiedergabe mit internem Sicherheitston.",
|
||||
"ringingPreparingInternalAudio": "Interner Sicherheitston wird vorbereitet.",
|
||||
"stopAlarmAction": "Alarm stoppen",
|
||||
"alarmStopFailedMessage": "Wir konnten nicht bestätigen, dass der Alarm gestoppt wurde. Versuche es erneut.",
|
||||
"alarmForceStopAction": "Erzwungen stoppen",
|
||||
"alarmMissedNotificationTitle": "Verpasster Alarm",
|
||||
"alarmMissedNotificationText": "{name} wurde nach 10 Minuten automatisch stummgeschaltet.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Pausieren",
|
||||
"miniPlayerOpenLabel": "Wiedergabe für {stationName} öffnen",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Playing with internal safe audio.",
|
||||
"ringingPreparingInternalAudio": "Preparing internal safe audio.",
|
||||
"stopAlarmAction": "Stop alarm",
|
||||
"alarmStopFailedMessage": "We couldn't confirm the alarm stopped. Try again.",
|
||||
"alarmForceStopAction": "Force stop",
|
||||
"alarmMissedNotificationTitle": "Missed alarm",
|
||||
"alarmMissedNotificationText": "{name} was silenced automatically after 10 minutes.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Pause",
|
||||
"miniPlayerOpenLabel": "Open player for {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,11 @@
|
||||
"ringingInternalAudioActive": "Sonando con audio seguro interno.",
|
||||
"ringingPreparingInternalAudio": "Preparando audio seguro interno.",
|
||||
"stopAlarmAction": "Detener alarma",
|
||||
"alarmStopFailedMessage": "No pudimos confirmar que la alarma se detuvo. Inténtalo de nuevo.",
|
||||
"alarmForceStopAction": "Forzar detención",
|
||||
"alarmMissedNotificationTitle": "Alarma perdida",
|
||||
"alarmMissedNotificationText": "{name} se silenció automáticamente después de 10 minutos.",
|
||||
"@alarmMissedNotificationText": {"placeholders": {"name": {}}},
|
||||
"pauseAction": "Pausar",
|
||||
"miniPlayerOpenLabel": "Abrir reproductor de {stationName}",
|
||||
"@miniPlayerOpenLabel": {"placeholders": {"stationName": {}}},
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Son sécurisé interne en cours.",
|
||||
"ringingPreparingInternalAudio": "Préparation du son sécurisé interne.",
|
||||
"stopAlarmAction": "Arrêter l’alarme",
|
||||
"alarmStopFailedMessage": "Nous n’avons pas pu confirmer l’arrêt de l’alarme. Réessayez.",
|
||||
"alarmForceStopAction": "Forcer l’arrêt",
|
||||
"alarmMissedNotificationTitle": "Alarme manquée",
|
||||
"alarmMissedNotificationText": "{name} a été mise en sourdine automatiquement après 10 minutes.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Pause",
|
||||
"miniPlayerOpenLabel": "Ouvrir le lecteur de {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "सुरक्षित आंतरिक ध्वनि के साथ बज रहा है।",
|
||||
"ringingPreparingInternalAudio": "सुरक्षित आंतरिक ध्वनि तैयार हो रही है।",
|
||||
"stopAlarmAction": "अलार्म रोकें",
|
||||
"alarmStopFailedMessage": "हम पुष्टि नहीं कर सके कि अलार्म बंद हुआ। फिर से कोशिश करें।",
|
||||
"alarmForceStopAction": "जबरन बंद करें",
|
||||
"alarmMissedNotificationTitle": "छूटा हुआ अलार्म",
|
||||
"alarmMissedNotificationText": "10 मिनट बाद {name} अपने आप म्यूट कर दिया गया।",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "विराम दें",
|
||||
"miniPlayerOpenLabel": "{stationName} का प्लेयर खोलें",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Berbunyi dengan audio internal aman.",
|
||||
"ringingPreparingInternalAudio": "Menyiapkan audio internal aman.",
|
||||
"stopAlarmAction": "Hentikan alarm",
|
||||
"alarmStopFailedMessage": "Kami tidak dapat memastikan alarm berhenti. Coba lagi.",
|
||||
"alarmForceStopAction": "Paksa berhenti",
|
||||
"alarmMissedNotificationTitle": "Alarm terlewat",
|
||||
"alarmMissedNotificationText": "{name} dibisukan secara otomatis setelah 10 menit.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Jeda",
|
||||
"miniPlayerOpenLabel": "Buka pemutar untuk {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Suono sicuro interno in riproduzione.",
|
||||
"ringingPreparingInternalAudio": "Preparazione del suono sicuro interno.",
|
||||
"stopAlarmAction": "Ferma sveglia",
|
||||
"alarmStopFailedMessage": "Non siamo riusciti a confermare l’arresto della sveglia. Riprova.",
|
||||
"alarmForceStopAction": "Forza arresto",
|
||||
"alarmMissedNotificationTitle": "Sveglia mancata",
|
||||
"alarmMissedNotificationText": "{name} è stata disattivata automaticamente dopo 10 minuti.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Pausa",
|
||||
"miniPlayerOpenLabel": "Apri il lettore per {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "安全な内部音で鳴っています。",
|
||||
"ringingPreparingInternalAudio": "安全な内部音を準備中です。",
|
||||
"stopAlarmAction": "アラームを停止",
|
||||
"alarmStopFailedMessage": "アラームが停止したことを確認できませんでした。もう一度お試しください。",
|
||||
"alarmForceStopAction": "強制停止",
|
||||
"alarmMissedNotificationTitle": "アラームの聞き逃し",
|
||||
"alarmMissedNotificationText": "{name}は10分後に自動的に消音されました。",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "一時停止",
|
||||
"miniPlayerOpenLabel": "{stationName}のプレーヤーを開く",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Tocando com som seguro interno.",
|
||||
"ringingPreparingInternalAudio": "Preparando som seguro interno.",
|
||||
"stopAlarmAction": "Parar alarme",
|
||||
"alarmStopFailedMessage": "Não conseguimos confirmar que o alarme parou. Tente novamente.",
|
||||
"alarmForceStopAction": "Forçar parada",
|
||||
"alarmMissedNotificationTitle": "Alarme perdido",
|
||||
"alarmMissedNotificationText": "{name} foi silenciado automaticamente após 10 minutos.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Pausar",
|
||||
"miniPlayerOpenLabel": "Abrir reprodutor de {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "Звонит с безопасным внутренним звуком.",
|
||||
"ringingPreparingInternalAudio": "Подготовка безопасного внутреннего звука.",
|
||||
"stopAlarmAction": "Остановить будильник",
|
||||
"alarmStopFailedMessage": "Не удалось подтвердить, что будильник остановлен. Попробуйте снова.",
|
||||
"alarmForceStopAction": "Принудительно остановить",
|
||||
"alarmMissedNotificationTitle": "Пропущенный будильник",
|
||||
"alarmMissedNotificationText": "{name} был автоматически отключён через 10 минут.",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "Пауза",
|
||||
"miniPlayerOpenLabel": "Открыть плеер для {stationName}",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -466,6 +466,15 @@
|
||||
"ringingInternalAudioActive": "正在使用内部安全音频响铃。",
|
||||
"ringingPreparingInternalAudio": "正在准备内部安全音频。",
|
||||
"stopAlarmAction": "停止闹钟",
|
||||
"alarmStopFailedMessage": "无法确认闹钟已停止,请重试。",
|
||||
"alarmForceStopAction": "强制停止",
|
||||
"alarmMissedNotificationTitle": "错过的闹钟",
|
||||
"alarmMissedNotificationText": "{name}已在10分钟后自动静音。",
|
||||
"@alarmMissedNotificationText": {
|
||||
"placeholders": {
|
||||
"name": {}
|
||||
}
|
||||
},
|
||||
"pauseAction": "暂停",
|
||||
"miniPlayerOpenLabel": "打开 {stationName} 的播放器",
|
||||
"@miniPlayerOpenLabel": {
|
||||
|
||||
@@ -1694,6 +1694,30 @@ abstract class AppLocalizations {
|
||||
/// **'Detener alarma'**
|
||||
String get stopAlarmAction;
|
||||
|
||||
/// No description provided for @alarmStopFailedMessage.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'No pudimos confirmar que la alarma se detuvo. Inténtalo de nuevo.'**
|
||||
String get alarmStopFailedMessage;
|
||||
|
||||
/// No description provided for @alarmForceStopAction.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Forzar detención'**
|
||||
String get alarmForceStopAction;
|
||||
|
||||
/// No description provided for @alarmMissedNotificationTitle.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Alarma perdida'**
|
||||
String get alarmMissedNotificationTitle;
|
||||
|
||||
/// No description provided for @alarmMissedNotificationText.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'{name} se silenció automáticamente después de 10 minutos.'**
|
||||
String alarmMissedNotificationText(Object name);
|
||||
|
||||
/// No description provided for @pauseAction.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
|
||||
@@ -899,6 +899,21 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'إيقاف المنبه';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'تعذّر التأكد من إيقاف المنبه. حاول مرة أخرى.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'إيقاف قسري';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'منبه فائت';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return 'تم كتم $name تلقائيًا بعد 10 دقائق.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'إيقاف مؤقت';
|
||||
|
||||
|
||||
@@ -908,6 +908,21 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'অ্যালার্ম বন্ধ করুন';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'অ্যালার্ম বন্ধ হয়েছে তা নিশ্চিত করা যায়নি। আবার চেষ্টা করুন।';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'জোর করে বন্ধ করুন';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'মিস হওয়া অ্যালার্ম';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '১০ মিনিট পর $name স্বয়ংক্রিয়ভাবে নিঃশব্দ করা হয়েছে।';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'বিরতি দিন';
|
||||
|
||||
|
||||
@@ -910,6 +910,21 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Alarm stoppen';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'Wir konnten nicht bestätigen, dass der Alarm gestoppt wurde. Versuche es erneut.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Erzwungen stoppen';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Verpasster Alarm';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name wurde nach 10 Minuten automatisch stummgeschaltet.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Pausieren';
|
||||
|
||||
|
||||
@@ -903,6 +903,21 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Stop alarm';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'We couldn\'t confirm the alarm stopped. Try again.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Force stop';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Missed alarm';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name was silenced automatically after 10 minutes.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Pause';
|
||||
|
||||
|
||||
@@ -907,6 +907,21 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Detener alarma';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'No pudimos confirmar que la alarma se detuvo. Inténtalo de nuevo.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Forzar detención';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Alarma perdida';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name se silenció automáticamente después de 10 minutos.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Pausar';
|
||||
|
||||
|
||||
@@ -913,6 +913,21 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Arrêter l’alarme';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'Nous n’avons pas pu confirmer l’arrêt de l’alarme. Réessayez.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Forcer l’arrêt';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Alarme manquée';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name a été mise en sourdine automatiquement après 10 minutes.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Pause';
|
||||
|
||||
|
||||
@@ -904,6 +904,21 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'अलार्म रोकें';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'हम पुष्टि नहीं कर सके कि अलार्म बंद हुआ। फिर से कोशिश करें।';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'जबरन बंद करें';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'छूटा हुआ अलार्म';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '10 मिनट बाद $name अपने आप म्यूट कर दिया गया।';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'विराम दें';
|
||||
|
||||
|
||||
@@ -908,6 +908,21 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Hentikan alarm';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'Kami tidak dapat memastikan alarm berhenti. Coba lagi.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Paksa berhenti';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Alarm terlewat';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name dibisukan secara otomatis setelah 10 menit.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Jeda';
|
||||
|
||||
|
||||
@@ -910,6 +910,21 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Ferma sveglia';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'Non siamo riusciti a confermare l’arresto della sveglia. Riprova.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Forza arresto';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Sveglia mancata';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name è stata disattivata automaticamente dopo 10 minuti.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Pausa';
|
||||
|
||||
|
||||
@@ -875,6 +875,20 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'アラームを停止';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage => 'アラームが停止したことを確認できませんでした。もう一度お試しください。';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => '強制停止';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'アラームの聞き逃し';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$nameは10分後に自動的に消音されました。';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => '一時停止';
|
||||
|
||||
|
||||
@@ -905,6 +905,21 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Parar alarme';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'Não conseguimos confirmar que o alarme parou. Tente novamente.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Forçar parada';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Alarme perdido';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name foi silenciado automaticamente após 10 minutos.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Pausar';
|
||||
|
||||
|
||||
@@ -909,6 +909,21 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => 'Остановить будильник';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage =>
|
||||
'Не удалось подтвердить, что будильник остановлен. Попробуйте снова.';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => 'Принудительно остановить';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => 'Пропущенный будильник';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name был автоматически отключён через 10 минут.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => 'Пауза';
|
||||
|
||||
|
||||
@@ -871,6 +871,20 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
@override
|
||||
String get stopAlarmAction => '停止闹钟';
|
||||
|
||||
@override
|
||||
String get alarmStopFailedMessage => '无法确认闹钟已停止,请重试。';
|
||||
|
||||
@override
|
||||
String get alarmForceStopAction => '强制停止';
|
||||
|
||||
@override
|
||||
String get alarmMissedNotificationTitle => '错过的闹钟';
|
||||
|
||||
@override
|
||||
String alarmMissedNotificationText(Object name) {
|
||||
return '$name已在10分钟后自动静音。';
|
||||
}
|
||||
|
||||
@override
|
||||
String get pauseAction => '暂停';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user