build(editor): halkyon_editor joins the workspace (ADR 0033, D37)

The package for the general parts of Learn's editor, its strings first;
the code moves next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-06 21:11:47 +01:00
commit 6e93ef82b5
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
7 changed files with 1474 additions and 0 deletions

View file

@ -0,0 +1,35 @@
{
"@@locale": "de",
"formatAlignLeft": "Linksbündig",
"formatAlignCenter": "Zentriert",
"formatAlignRight": "Rechtsbündig",
"formatBold": "Fett",
"formatItalic": "Kursiv",
"formatUnderline": "Unterstrichen",
"formatSuperscript": "Hochgestellt",
"formatSubscript": "Tiefgestellt",
"formatLink": "Link",
"linkTitle": "Link",
"linkText": "Text",
"linkAddress": "Adresse",
"linkAddressHint": "https://…",
"linkSave": "Speichern",
"linkRemove": "Link entfernen",
"commonCancel": "Abbrechen",
"editorInsert": "Einfügen",
"blockGroupText": "Text",
"blockGroupBlocks": "Blöcke",
"blockGroupMedia": "Medien",
"blockHeading": "Überschrift {level}",
"blockBulletedList": "Aufzählung",
"blockNumberedList": "Nummerierte Liste",
"blockChecklist": "Checkliste",
"blockQuote": "Zitat",
"blockListItem": "Listenpunkt",
"blockChecklistItem": "Aufgabe",
"editorSlashHint": "Tippe / für einen Block oder schreib einfach los",
"blockDivider": "Trennlinie",
"blockTable": "Tabelle",
"blockRemove": "Entfernen",
"blockUnknown": "Dieser Teil braucht eine neuere Version der App."
}

View file

@ -0,0 +1,42 @@
{
"@@locale": "en",
"formatAlignLeft": "Align left",
"formatAlignCenter": "Centre",
"formatAlignRight": "Align right",
"formatBold": "Bold",
"formatItalic": "Italic",
"formatUnderline": "Underline",
"formatSuperscript": "Superscript",
"formatSubscript": "Subscript",
"formatLink": "Link",
"linkTitle": "Link",
"linkText": "Text",
"linkAddress": "Address",
"linkAddressHint": "https://…",
"linkSave": "Save",
"linkRemove": "Remove link",
"commonCancel": "Cancel",
"editorInsert": "Insert",
"blockGroupText": "Text",
"blockGroupBlocks": "Blocks",
"blockGroupMedia": "Media",
"blockHeading": "Heading {level}",
"@blockHeading": {
"placeholders": {
"level": {
"type": "int"
}
}
},
"blockBulletedList": "Bulleted list",
"blockNumberedList": "Numbered list",
"blockChecklist": "Checklist",
"blockQuote": "Quote",
"blockListItem": "List item",
"blockChecklistItem": "To-do",
"editorSlashHint": "Type / to insert a block, or just start typing",
"blockDivider": "Divider",
"blockTable": "Table",
"blockRemove": "Remove",
"blockUnknown": "This part needs a newer version of the app."
}

View file

@ -0,0 +1,3 @@
{
"@@locale": "en_GB"
}

View file

@ -0,0 +1,4 @@
{
"@@locale": "en_US",
"formatAlignCenter": "Center"
}

View file

@ -0,0 +1,347 @@
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 'halkyon_editor_localizations_de.dart';
import 'halkyon_editor_localizations_en.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of HalkyonEditorLocalizations
/// returned by `HalkyonEditorLocalizations.of(context)`.
///
/// Applications need to include `HalkyonEditorLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/halkyon_editor_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: HalkyonEditorLocalizations.localizationsDelegates,
/// supportedLocales: HalkyonEditorLocalizations.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 HalkyonEditorLocalizations.supportedLocales
/// property.
abstract class HalkyonEditorLocalizations {
HalkyonEditorLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static HalkyonEditorLocalizations of(BuildContext context) {
return Localizations.of<HalkyonEditorLocalizations>(
context,
HalkyonEditorLocalizations,
)!;
}
static const LocalizationsDelegate<HalkyonEditorLocalizations> delegate =
_HalkyonEditorLocalizationsDelegate();
/// 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'),
];
/// No description provided for @formatAlignLeft.
///
/// In en, this message translates to:
/// **'Align left'**
String get formatAlignLeft;
/// No description provided for @formatAlignCenter.
///
/// In en, this message translates to:
/// **'Centre'**
String get formatAlignCenter;
/// No description provided for @formatAlignRight.
///
/// In en, this message translates to:
/// **'Align right'**
String get formatAlignRight;
/// No description provided for @formatBold.
///
/// In en, this message translates to:
/// **'Bold'**
String get formatBold;
/// No description provided for @formatItalic.
///
/// In en, this message translates to:
/// **'Italic'**
String get formatItalic;
/// No description provided for @formatUnderline.
///
/// In en, this message translates to:
/// **'Underline'**
String get formatUnderline;
/// No description provided for @formatSuperscript.
///
/// In en, this message translates to:
/// **'Superscript'**
String get formatSuperscript;
/// No description provided for @formatSubscript.
///
/// In en, this message translates to:
/// **'Subscript'**
String get formatSubscript;
/// No description provided for @formatLink.
///
/// In en, this message translates to:
/// **'Link'**
String get formatLink;
/// No description provided for @linkTitle.
///
/// In en, this message translates to:
/// **'Link'**
String get linkTitle;
/// No description provided for @linkText.
///
/// In en, this message translates to:
/// **'Text'**
String get linkText;
/// No description provided for @linkAddress.
///
/// In en, this message translates to:
/// **'Address'**
String get linkAddress;
/// No description provided for @linkAddressHint.
///
/// In en, this message translates to:
/// **'https://…'**
String get linkAddressHint;
/// No description provided for @linkSave.
///
/// In en, this message translates to:
/// **'Save'**
String get linkSave;
/// No description provided for @linkRemove.
///
/// In en, this message translates to:
/// **'Remove link'**
String get linkRemove;
/// No description provided for @commonCancel.
///
/// In en, this message translates to:
/// **'Cancel'**
String get commonCancel;
/// No description provided for @editorInsert.
///
/// In en, this message translates to:
/// **'Insert'**
String get editorInsert;
/// No description provided for @blockGroupText.
///
/// In en, this message translates to:
/// **'Text'**
String get blockGroupText;
/// No description provided for @blockGroupBlocks.
///
/// In en, this message translates to:
/// **'Blocks'**
String get blockGroupBlocks;
/// No description provided for @blockGroupMedia.
///
/// In en, this message translates to:
/// **'Media'**
String get blockGroupMedia;
/// No description provided for @blockHeading.
///
/// In en, this message translates to:
/// **'Heading {level}'**
String blockHeading(int level);
/// No description provided for @blockBulletedList.
///
/// In en, this message translates to:
/// **'Bulleted list'**
String get blockBulletedList;
/// No description provided for @blockNumberedList.
///
/// In en, this message translates to:
/// **'Numbered list'**
String get blockNumberedList;
/// No description provided for @blockChecklist.
///
/// In en, this message translates to:
/// **'Checklist'**
String get blockChecklist;
/// No description provided for @blockQuote.
///
/// In en, this message translates to:
/// **'Quote'**
String get blockQuote;
/// No description provided for @blockListItem.
///
/// In en, this message translates to:
/// **'List item'**
String get blockListItem;
/// No description provided for @blockChecklistItem.
///
/// In en, this message translates to:
/// **'To-do'**
String get blockChecklistItem;
/// No description provided for @editorSlashHint.
///
/// In en, this message translates to:
/// **'Type / to insert a block, or just start typing'**
String get editorSlashHint;
/// No description provided for @blockDivider.
///
/// In en, this message translates to:
/// **'Divider'**
String get blockDivider;
/// No description provided for @blockTable.
///
/// In en, this message translates to:
/// **'Table'**
String get blockTable;
/// No description provided for @blockRemove.
///
/// In en, this message translates to:
/// **'Remove'**
String get blockRemove;
/// No description provided for @blockUnknown.
///
/// In en, this message translates to:
/// **'This part needs a newer version of the app.'**
String get blockUnknown;
}
class _HalkyonEditorLocalizationsDelegate
extends LocalizationsDelegate<HalkyonEditorLocalizations> {
const _HalkyonEditorLocalizationsDelegate();
@override
Future<HalkyonEditorLocalizations> load(Locale locale) {
return SynchronousFuture<HalkyonEditorLocalizations>(
lookupHalkyonEditorLocalizations(locale),
);
}
@override
bool isSupported(Locale locale) =>
<String>['de', 'en'].contains(locale.languageCode);
@override
bool shouldReload(_HalkyonEditorLocalizationsDelegate old) => false;
}
HalkyonEditorLocalizations lookupHalkyonEditorLocalizations(Locale locale) {
// Lookup logic when language+country codes are specified.
switch (locale.languageCode) {
case 'en':
{
switch (locale.countryCode) {
case 'GB':
return HalkyonEditorLocalizationsEnGb();
case 'US':
return HalkyonEditorLocalizationsEnUs();
}
break;
}
}
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'de':
return HalkyonEditorLocalizationsDe();
case 'en':
return HalkyonEditorLocalizationsEn();
}
throw FlutterError(
'HalkyonEditorLocalizations.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.',
);
}

View file

@ -0,0 +1,110 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'halkyon_editor_localizations.dart';
// ignore_for_file: type=lint
/// The translations for German (`de`).
class HalkyonEditorLocalizationsDe extends HalkyonEditorLocalizations {
HalkyonEditorLocalizationsDe([String locale = 'de']) : super(locale);
@override
String get formatAlignLeft => 'Linksbündig';
@override
String get formatAlignCenter => 'Zentriert';
@override
String get formatAlignRight => 'Rechtsbündig';
@override
String get formatBold => 'Fett';
@override
String get formatItalic => 'Kursiv';
@override
String get formatUnderline => 'Unterstrichen';
@override
String get formatSuperscript => 'Hochgestellt';
@override
String get formatSubscript => 'Tiefgestellt';
@override
String get formatLink => 'Link';
@override
String get linkTitle => 'Link';
@override
String get linkText => 'Text';
@override
String get linkAddress => 'Adresse';
@override
String get linkAddressHint => 'https://…';
@override
String get linkSave => 'Speichern';
@override
String get linkRemove => 'Link entfernen';
@override
String get commonCancel => 'Abbrechen';
@override
String get editorInsert => 'Einfügen';
@override
String get blockGroupText => 'Text';
@override
String get blockGroupBlocks => 'Blöcke';
@override
String get blockGroupMedia => 'Medien';
@override
String blockHeading(int level) {
return 'Überschrift $level';
}
@override
String get blockBulletedList => 'Aufzählung';
@override
String get blockNumberedList => 'Nummerierte Liste';
@override
String get blockChecklist => 'Checkliste';
@override
String get blockQuote => 'Zitat';
@override
String get blockListItem => 'Listenpunkt';
@override
String get blockChecklistItem => 'Aufgabe';
@override
String get editorSlashHint =>
'Tippe / für einen Block oder schreib einfach los';
@override
String get blockDivider => 'Trennlinie';
@override
String get blockTable => 'Tabelle';
@override
String get blockRemove => 'Entfernen';
@override
String get blockUnknown => 'Dieser Teil braucht eine neuere Version der App.';
}

View file

@ -0,0 +1,123 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'halkyon_editor_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class HalkyonEditorLocalizationsEn extends HalkyonEditorLocalizations {
HalkyonEditorLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get formatAlignLeft => 'Align left';
@override
String get formatAlignCenter => 'Centre';
@override
String get formatAlignRight => 'Align right';
@override
String get formatBold => 'Bold';
@override
String get formatItalic => 'Italic';
@override
String get formatUnderline => 'Underline';
@override
String get formatSuperscript => 'Superscript';
@override
String get formatSubscript => 'Subscript';
@override
String get formatLink => 'Link';
@override
String get linkTitle => 'Link';
@override
String get linkText => 'Text';
@override
String get linkAddress => 'Address';
@override
String get linkAddressHint => 'https://…';
@override
String get linkSave => 'Save';
@override
String get linkRemove => 'Remove link';
@override
String get commonCancel => 'Cancel';
@override
String get editorInsert => 'Insert';
@override
String get blockGroupText => 'Text';
@override
String get blockGroupBlocks => 'Blocks';
@override
String get blockGroupMedia => 'Media';
@override
String blockHeading(int level) {
return 'Heading $level';
}
@override
String get blockBulletedList => 'Bulleted list';
@override
String get blockNumberedList => 'Numbered list';
@override
String get blockChecklist => 'Checklist';
@override
String get blockQuote => 'Quote';
@override
String get blockListItem => 'List item';
@override
String get blockChecklistItem => 'To-do';
@override
String get editorSlashHint =>
'Type / to insert a block, or just start typing';
@override
String get blockDivider => 'Divider';
@override
String get blockTable => 'Table';
@override
String get blockRemove => 'Remove';
@override
String get blockUnknown => 'This part needs a newer version of the app.';
}
/// The translations for English, as used in the United Kingdom (`en_GB`).
class HalkyonEditorLocalizationsEnGb extends HalkyonEditorLocalizationsEn {
HalkyonEditorLocalizationsEnGb() : super('en_GB');
}
/// The translations for English, as used in the United States (`en_US`).
class HalkyonEditorLocalizationsEnUs extends HalkyonEditorLocalizationsEn {
HalkyonEditorLocalizationsEnUs() : super('en_US');
@override
String get formatAlignCenter => 'Center';
}