feat(train): Halkyon Train's shell, Todo's copied and renamed (ADR 0030, D12)
apps/train with halkyon_train_server, _client and _flutter, as Todo's:
halkyon_base configured by trainBase(), its own register alone and a
member of the instance's where the operator names one, the app on
halkyon_app's gates with Train's frame, account sheet and About, texts
in British English and German that speak of workouts, app.halkyon.train
on Android, iOS, Linux, macOS and Windows.
Where it differs from Todo: development ports of its own (8180 to 8190),
so it runs beside Learn's server; one initial migration with the schema
Todo's migrations end at (the same tables, compared line by line), not
Todo's seventeen; and Todo's icon as a placeholder until the icon tool
of ADR 0031 draws Train's bike. The workspace, the licences, the READMEs
and AGENTS.md name it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 10:26:49 +01:00
import ' dart:async ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:flutter/widgets.dart ' ;
import ' package:flutter_localizations/flutter_localizations.dart ' ;
import ' package:intl/intl.dart ' as intl ;
import ' app_localizations_de.dart ' ;
import ' app_localizations_en.dart ' ;
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, you’ ll need to edit this
/// file.
///
/// First, open your project’ s ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// project’ s Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations ( String locale )
: localeName = intl . Intl . canonicalizedLocale ( locale . toString ( ) ) ;
final String localeName ;
static AppLocalizations of ( BuildContext context ) {
return Localizations . of < AppLocalizations > ( context , AppLocalizations ) ! ;
}
static const LocalizationsDelegate < AppLocalizations > delegate =
_AppLocalizationsDelegate ( ) ;
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List < LocalizationsDelegate < dynamic > > localizationsDelegates =
< LocalizationsDelegate < dynamic > > [
delegate ,
GlobalMaterialLocalizations . delegate ,
GlobalCupertinoLocalizations . delegate ,
GlobalWidgetsLocalizations . delegate ,
] ;
/// A list of this localizations delegate's supported locales.
static const List < Locale > supportedLocales = < Locale > [
Locale ( ' de ' ) ,
Locale ( ' en ' ) ,
Locale ( ' en ' , ' GB ' ) ,
Locale ( ' en ' , ' US ' ) ,
] ;
/// The app's name: the window's title, and where halkyon_app's texts name the app.
///
/// In en, this message translates to:
/// **'Halkyon Train'**
String get appTitle ;
/// The app's word in its wordmark, under "Halkyon".
///
/// In en, this message translates to:
/// **'Train'**
String get launchProduct ;
/// No description provided for @instanceFirstStartSubtitle.
///
/// In en, this message translates to:
/// **'Choose the instance to keep your workouts on. Someone runs each one; you can add others later.'**
String get instanceFirstStartSubtitle ;
/// No description provided for @homeEmptyTitle.
///
/// In en, this message translates to:
feat(train): the workouts listed, and each one's page with its map (ADR 0030, D22-D24)
Home lists the person's workouts newest first under their months, each
with its activity's icon, its name (else the time of day's and the
activity's), when it started, its distance, moving time and pace or
speed; those this device can't open come last, locked. A workout's page
shows its track on the instance's map source (flutter_map with
vector_map_tiles, pinned at 9.0.0-beta.13), in pieces between its
pauses, start and end marked; its totals with the elevation gained;
its splits per kilometre on foot, per 5 km cycling; pace or speed and
elevation over the distance, drawn by the app's own painter; and what
the map's source sees. Its name and notes are edited there; deleting
asks first and can be undone for a moment from home (halkyon_app's
DelayedDeletions, TrainPerson.deletions).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 14:29:39 +01:00
/// **'No workouts yet'**
feat(train): Halkyon Train's shell, Todo's copied and renamed (ADR 0030, D12)
apps/train with halkyon_train_server, _client and _flutter, as Todo's:
halkyon_base configured by trainBase(), its own register alone and a
member of the instance's where the operator names one, the app on
halkyon_app's gates with Train's frame, account sheet and About, texts
in British English and German that speak of workouts, app.halkyon.train
on Android, iOS, Linux, macOS and Windows.
Where it differs from Todo: development ports of its own (8180 to 8190),
so it runs beside Learn's server; one initial migration with the schema
Todo's migrations end at (the same tables, compared line by line), not
Todo's seventeen; and Todo's icon as a placeholder until the icon tool
of ADR 0031 draws Train's bike. The workspace, the licences, the READMEs
and AGENTS.md name it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 10:26:49 +01:00
String get homeEmptyTitle ;
/// No description provided for @homeEmptyHint.
///
/// In en, this message translates to:
feat(train): the workouts listed, and each one's page with its map (ADR 0030, D22-D24)
Home lists the person's workouts newest first under their months, each
with its activity's icon, its name (else the time of day's and the
activity's), when it started, its distance, moving time and pace or
speed; those this device can't open come last, locked. A workout's page
shows its track on the instance's map source (flutter_map with
vector_map_tiles, pinned at 9.0.0-beta.13), in pieces between its
pauses, start and end marked; its totals with the elevation gained;
its splits per kilometre on foot, per 5 km cycling; pace or speed and
elevation over the distance, drawn by the app's own painter; and what
the map's source sees. Its name and notes are edited there; deleting
asks first and can be undone for a moment from home (halkyon_app's
DelayedDeletions, TrainPerson.deletions).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 14:29:39 +01:00
/// **'Workouts recorded on your phone show here.'**
feat(train): Halkyon Train's shell, Todo's copied and renamed (ADR 0030, D12)
apps/train with halkyon_train_server, _client and _flutter, as Todo's:
halkyon_base configured by trainBase(), its own register alone and a
member of the instance's where the operator names one, the app on
halkyon_app's gates with Train's frame, account sheet and About, texts
in British English and German that speak of workouts, app.halkyon.train
on Android, iOS, Linux, macOS and Windows.
Where it differs from Todo: development ports of its own (8180 to 8190),
so it runs beside Learn's server; one initial migration with the schema
Todo's migrations end at (the same tables, compared line by line), not
Todo's seventeen; and Todo's icon as a placeholder until the icon tool
of ADR 0031 draws Train's bike. The workspace, the licences, the READMEs
and AGENTS.md name it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 10:26:49 +01:00
String get homeEmptyHint ;
/// No description provided for @accountTitle.
///
/// In en, this message translates to:
/// **'Account'**
String get accountTitle ;
/// No description provided for @accountDeleteMessage.
///
/// In en, this message translates to:
/// **'Your account is deleted on the server and on all your devices. This can\'t be undone.'**
String get accountDeleteMessage ;
/// No description provided for @aboutTitle.
///
/// In en, this message translates to:
/// **'About'**
String get aboutTitle ;
feat(train): recording a workout on Android (ADR 0030, D13, D16, D19, D21)
RecorderService, a foreground service of the types location and health
started from the open app, takes fixes from LocationManager's GPS and
steps from the step detector, pauses by itself (AutoPause, tested on the
JVM) and appends each sample to the person's recording file, flushed
every five seconds. MainActivity asks for location, notifications and,
for auto-pause on foot, physical activity, never background location
(D19), and bridges the service to the app.
The app follows the file's lines with RecordingBloc and shows the moving
time, the distance, the pace or speed and GPS's state; the notification
shows the time and the distance with Pause or Resume. Stop is held down;
a stopped recording is saved as a workout and its series, or discarded
after asking, and one cut off or left unsaved is offered as the app
opens. Home has the Record button where the device records.
Three choices of the implementation's are recorded under D21 for review:
rowing waits for 5f, auto-pause on foot without steps goes by GPS speed
(below 2 km/h, on above 3 km/h), and Stop's hint shows above the button.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 13:24:56 +01:00
/// No description provided for @homeRecordHint.
///
/// In en, this message translates to:
feat(train): the workouts listed, and each one's page with its map (ADR 0030, D22-D24)
Home lists the person's workouts newest first under their months, each
with its activity's icon, its name (else the time of day's and the
activity's), when it started, its distance, moving time and pace or
speed; those this device can't open come last, locked. A workout's page
shows its track on the instance's map source (flutter_map with
vector_map_tiles, pinned at 9.0.0-beta.13), in pieces between its
pauses, start and end marked; its totals with the elevation gained;
its splits per kilometre on foot, per 5 km cycling; pace or speed and
elevation over the distance, drawn by the app's own painter; and what
the map's source sees. Its name and notes are edited there; deleting
asks first and can be undone for a moment from home (halkyon_app's
DelayedDeletions, TrainPerson.deletions).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 14:29:39 +01:00
/// **'Record one with the button below.'**
feat(train): recording a workout on Android (ADR 0030, D13, D16, D19, D21)
RecorderService, a foreground service of the types location and health
started from the open app, takes fixes from LocationManager's GPS and
steps from the step detector, pauses by itself (AutoPause, tested on the
JVM) and appends each sample to the person's recording file, flushed
every five seconds. MainActivity asks for location, notifications and,
for auto-pause on foot, physical activity, never background location
(D19), and bridges the service to the app.
The app follows the file's lines with RecordingBloc and shows the moving
time, the distance, the pace or speed and GPS's state; the notification
shows the time and the distance with Pause or Resume. Stop is held down;
a stopped recording is saved as a workout and its series, or discarded
after asking, and one cut off or left unsaved is offered as the app
opens. Home has the Record button where the device records.
Three choices of the implementation's are recorded under D21 for review:
rowing waits for 5f, auto-pause on foot without steps goes by GPS speed
(below 2 km/h, on above 3 km/h), and Stop's hint shows above the button.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 13:24:56 +01:00
String get homeRecordHint ;
/// No description provided for @recordAction.
///
/// In en, this message translates to:
/// **'Record'**
String get recordAction ;
/// No description provided for @recordBack.
///
/// In en, this message translates to:
/// **'Back to the recording'**
String get recordBack ;
/// No description provided for @recordSheetTitle.
///
/// In en, this message translates to:
/// **'Record a workout'**
String get recordSheetTitle ;
/// No description provided for @activityRunning.
///
/// In en, this message translates to:
/// **'Running'**
String get activityRunning ;
/// No description provided for @activityWalking.
///
/// In en, this message translates to:
/// **'Walking'**
String get activityWalking ;
/// No description provided for @activityHiking.
///
/// In en, this message translates to:
/// **'Hiking'**
String get activityHiking ;
/// No description provided for @activityCycling.
///
/// In en, this message translates to:
/// **'Cycling'**
String get activityCycling ;
/// No description provided for @activityIndoorRowing.
///
/// In en, this message translates to:
/// **'Rowing indoors'**
String get activityIndoorRowing ;
/// The switch for auto-pause, as the recording starts.
///
/// In en, this message translates to:
/// **'Pause by itself'**
String get recordAutoPause ;
/// No description provided for @recordAutoPauseHint.
///
/// In en, this message translates to:
/// **'When you stand still, and going on as you move again'**
String get recordAutoPauseHint ;
/// No description provided for @recordStart.
///
/// In en, this message translates to:
/// **'Start'**
String get recordStart ;
/// No description provided for @recordLocationRefused.
///
/// In en, this message translates to:
/// **'Train needs your location to record this. You can allow it in the system\'s settings.'**
String get recordLocationRefused ;
/// No description provided for @recordingWaitingForGps.
///
/// In en, this message translates to:
/// **'Waiting for GPS'**
String get recordingWaitingForGps ;
/// Before a fix precise enough: how far off the last one may be.
///
/// In en, this message translates to:
/// **'Waiting for GPS · ±{metres} m'**
String recordingWaitingForGpsAccuracy ( int metres ) ;
/// How far off the last fix may be.
///
/// In en, this message translates to:
/// **'GPS ±{metres} m'**
String recordingGpsAccuracy ( int metres ) ;
/// Under the time, lower case: the time moved, pauses left out.
///
/// In en, this message translates to:
/// **'moving time'**
String get recordingMovingTime ;
/// No description provided for @recordingDistance.
///
/// In en, this message translates to:
/// **'distance'**
String get recordingDistance ;
/// No description provided for @recordingPace.
///
/// In en, this message translates to:
/// **'pace'**
String get recordingPace ;
/// No description provided for @recordingSpeed.
///
/// In en, this message translates to:
/// **'speed'**
String get recordingSpeed ;
/// No description provided for @recordingDistanceValue.
///
/// In en, this message translates to:
/// **'{km} km'**
String recordingDistanceValue ( String km ) ;
/// Minutes and seconds a kilometre takes.
///
/// In en, this message translates to:
/// **'{pace} /km'**
String recordingPaceValue ( String pace ) ;
/// No description provided for @recordingSpeedValue.
///
/// In en, this message translates to:
/// **'{kmh} km/h'**
String recordingSpeedValue ( String kmh ) ;
/// Train paused the recording by itself (auto-pause).
///
/// In en, this message translates to:
/// **'Paused: not moving'**
String get recordingPausedAuto ;
/// No description provided for @recordingPausedByHand.
///
/// In en, this message translates to:
/// **'Paused'**
String get recordingPausedByHand ;
/// No description provided for @recordingPause.
///
/// In en, this message translates to:
/// **'Pause'**
String get recordingPause ;
/// No description provided for @recordingResume.
///
/// In en, this message translates to:
/// **'Resume'**
String get recordingResume ;
/// No description provided for @recordingStop.
///
/// In en, this message translates to:
/// **'Stop'**
String get recordingStop ;
/// No description provided for @recordingHoldToStop.
///
/// In en, this message translates to:
/// **'Hold Stop to end the workout'**
String get recordingHoldToStop ;
/// No description provided for @recordingStoppedTitle.
///
/// In en, this message translates to:
/// **'Save this workout?'**
String get recordingStoppedTitle ;
/// No description provided for @recordingSave.
///
/// In en, this message translates to:
/// **'Save'**
String get recordingSave ;
/// No description provided for @recordingDiscard.
///
/// In en, this message translates to:
/// **'Discard'**
String get recordingDiscard ;
/// No description provided for @recordingDiscardTitle.
///
/// In en, this message translates to:
/// **'Discard this workout?'**
String get recordingDiscardTitle ;
/// No description provided for @recordingDiscardMessage.
///
/// In en, this message translates to:
/// **'Its time and track are deleted from this device. This can\'t be undone.'**
String get recordingDiscardMessage ;
/// No description provided for @recordingSaveFailed.
///
/// In en, this message translates to:
/// **'It can\'t be saved on this device, which doesn\'t hold your account\'s keys. It stays here until it can be.'**
String get recordingSaveFailed ;
/// No description provided for @recordingCutOffTitle.
///
/// In en, this message translates to:
/// **'A recording was cut off'**
String get recordingCutOffTitle ;
/// A recording found unfinished as the app opened: when it started and its last sample.
///
/// In en, this message translates to:
/// **'A recording from {start} was cut off. Save it up to {end}, or discard it?'**
String recordingCutOffMessage ( String start , String end ) ;
/// The name of the recording's notification channel, in the system's settings.
///
/// In en, this message translates to:
/// **'Recording'**
String get recordingNotificationChannel ;
/// The notification's title while paused.
///
/// In en, this message translates to:
/// **'{activity} · paused'**
String recordingNotificationPaused ( String activity ) ;
feat(train): the workouts listed, and each one's page with its map (ADR 0030, D22-D24)
Home lists the person's workouts newest first under their months, each
with its activity's icon, its name (else the time of day's and the
activity's), when it started, its distance, moving time and pace or
speed; those this device can't open come last, locked. A workout's page
shows its track on the instance's map source (flutter_map with
vector_map_tiles, pinned at 9.0.0-beta.13), in pieces between its
pauses, start and end marked; its totals with the elevation gained;
its splits per kilometre on foot, per 5 km cycling; pace or speed and
elevation over the distance, drawn by the app's own painter; and what
the map's source sees. Its name and notes are edited there; deleting
asks first and can be undone for a moment from home (halkyon_app's
DelayedDeletions, TrainPerson.deletions).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 14:29:39 +01:00
/// A workout's name where the person gave none: the time of day it started (morning 5– 12, afternoon 12– 17, evening 17– 22, night) and its activity, as Strava names them.
///
/// In en, this message translates to:
/// **'{when, select, morning_running{Morning run} morning_walking{Morning walk} morning_hiking{Morning hike} morning_cycling{Morning ride} morning_indoorRowing{Morning row} afternoon_running{Afternoon run} afternoon_walking{Afternoon walk} afternoon_hiking{Afternoon hike} afternoon_cycling{Afternoon ride} afternoon_indoorRowing{Afternoon row} evening_running{Evening run} evening_walking{Evening walk} evening_hiking{Evening hike} evening_cycling{Evening ride} evening_indoorRowing{Evening row} night_running{Night run} night_walking{Night walk} night_hiking{Night hike} night_cycling{Night ride} night_indoorRowing{Night row} other{Workout}}'**
String workoutName ( String when ) ;
/// No description provided for @workoutLocked.
///
/// In en, this message translates to:
/// **'Locked workout'**
String get workoutLocked ;
/// Under a workout this device can't open (its key is missing here).
///
/// In en, this message translates to:
/// **'This device doesn\'t hold the key it\'s sealed with.'**
String get workoutLockedHint ;
/// No description provided for @workoutEdit.
///
/// In en, this message translates to:
/// **'Edit'**
String get workoutEdit ;
/// No description provided for @workoutEditTitle.
///
/// In en, this message translates to:
/// **'Edit workout'**
String get workoutEditTitle ;
/// No description provided for @workoutNameLabel.
///
/// In en, this message translates to:
/// **'Name'**
String get workoutNameLabel ;
/// No description provided for @workoutNotesLabel.
///
/// In en, this message translates to:
/// **'Notes'**
String get workoutNotesLabel ;
/// No description provided for @workoutSave.
///
/// In en, this message translates to:
/// **'Save'**
String get workoutSave ;
/// No description provided for @workoutDelete.
///
/// In en, this message translates to:
/// **'Delete'**
String get workoutDelete ;
/// No description provided for @workoutDeleteTitle.
///
/// In en, this message translates to:
/// **'Delete this workout?'**
String get workoutDeleteTitle ;
/// No description provided for @workoutDeleteMessage.
///
/// In en, this message translates to:
/// **'It\'s deleted on all your devices.'**
String get workoutDeleteMessage ;
/// No description provided for @workoutDeleted.
///
/// In en, this message translates to:
/// **'Workout deleted'**
String get workoutDeleted ;
/// No description provided for @workoutMovingTime.
///
/// In en, this message translates to:
/// **'moving time'**
String get workoutMovingTime ;
/// Lower case, under a figure: from start to end, pauses included.
///
/// In en, this message translates to:
/// **'whole time'**
String get workoutTotalTime ;
/// No description provided for @workoutDistance.
///
/// In en, this message translates to:
/// **'distance'**
String get workoutDistance ;
/// No description provided for @workoutPace.
///
/// In en, this message translates to:
/// **'pace'**
String get workoutPace ;
/// No description provided for @workoutSpeed.
///
/// In en, this message translates to:
/// **'speed'**
String get workoutSpeed ;
/// Lower case, under a figure: the elevation gained.
///
/// In en, this message translates to:
/// **'climbed'**
String get workoutClimb ;
/// No description provided for @workoutClimbValue.
///
/// In en, this message translates to:
/// **'{metres} m'**
String workoutClimbValue ( int metres ) ;
/// No description provided for @workoutSplits.
///
/// In en, this message translates to:
/// **'Splits'**
String get workoutSplits ;
/// A kilometre's split, its number.
///
/// In en, this message translates to:
/// **'km {number}'**
String workoutSplitKm ( int number ) ;
/// A cycling split of 5 km: where it starts and ends.
///
/// In en, this message translates to:
/// **'{from}– {to} km'**
String workoutSplitFiveKm ( int from , int to ) ;
/// No description provided for @workoutPaceChart.
///
/// In en, this message translates to:
/// **'Pace'**
String get workoutPaceChart ;
/// No description provided for @workoutSpeedChart.
///
/// In en, this message translates to:
/// **'Speed'**
String get workoutSpeedChart ;
/// No description provided for @workoutElevationChart.
///
/// In en, this message translates to:
/// **'Elevation'**
String get workoutElevationChart ;
/// Under a workout's map: what the map's source sees.
///
/// In en, this message translates to:
/// **'Map by {name}: it sees your device\'s address and the area shown, not your track.'**
String workoutMapSource ( String name ) ;
/// A link to the map source's page about what it keeps.
///
/// In en, this message translates to:
/// **'What {name} keeps'**
String workoutMapSourceAbout ( String name ) ;
/// No description provided for @workoutMapUnavailable.
///
/// In en, this message translates to:
/// **'The map can\'t be loaded now.'**
String get workoutMapUnavailable ;
/// No description provided for @workoutNotFound.
///
/// In en, this message translates to:
/// **'This workout is gone.'**
String get workoutNotFound ;
feat(train): Halkyon Train's shell, Todo's copied and renamed (ADR 0030, D12)
apps/train with halkyon_train_server, _client and _flutter, as Todo's:
halkyon_base configured by trainBase(), its own register alone and a
member of the instance's where the operator names one, the app on
halkyon_app's gates with Train's frame, account sheet and About, texts
in British English and German that speak of workouts, app.halkyon.train
on Android, iOS, Linux, macOS and Windows.
Where it differs from Todo: development ports of its own (8180 to 8190),
so it runs beside Learn's server; one initial migration with the schema
Todo's migrations end at (the same tables, compared line by line), not
Todo's seventeen; and Todo's icon as a placeholder until the icon tool
of ADR 0031 draws Train's bike. The workspace, the licences, the READMEs
and AGENTS.md name it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-28 10:26:49 +01:00
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate < AppLocalizations > {
const _AppLocalizationsDelegate ( ) ;
@ override
Future < AppLocalizations > load ( Locale locale ) {
return SynchronousFuture < AppLocalizations > ( lookupAppLocalizations ( locale ) ) ;
}
@ override
bool isSupported ( Locale locale ) = >
< String > [ ' de ' , ' en ' ] . contains ( locale . languageCode ) ;
@ override
bool shouldReload ( _AppLocalizationsDelegate old ) = > false ;
}
AppLocalizations lookupAppLocalizations ( Locale locale ) {
// Lookup logic when language+country codes are specified.
switch ( locale . languageCode ) {
case ' en ' :
{
switch ( locale . countryCode ) {
case ' GB ' :
return AppLocalizationsEnGb ( ) ;
case ' US ' :
return AppLocalizationsEnUs ( ) ;
}
break ;
}
}
// Lookup logic when only language code is specified.
switch ( locale . languageCode ) {
case ' de ' :
return AppLocalizationsDe ( ) ;
case ' en ' :
return AppLocalizationsEn ( ) ;
}
throw FlutterError (
' AppLocalizations.delegate failed to load unsupported locale " $ locale ". This is likely '
' an issue with the localizations generation tool. Please file an issue '
' on GitHub with a reproducible sample app and the gen-l10n configuration '
' that was used. ' ,
) ;
}