feat(app): one Profile for every app, the person's own tab first, then each app's (ADR 0014)

The public profile was already one per person for every service of an
instance (the register, ADR 0016); its app side was Learn's alone. It
moves into halkyon_app: the model, the repository on the module's
endpoints, the form, the avatar drawn on the device and the sheet with
someone's profile. They take the Public prefix (PublicProfileRepository,
BasePublicProfileGateway), as Train's own ProfileRepository holds the
body's figures. AppDependencies gains profiles and files, the picker the
avatar is chosen with, which moves out of Learn too.

HalkyonProfile is every app's Profile screen: the person's own tab first,
the same in every app (the account and the ways they sign in, the app's
own cards, then the public profile), then the app's own tabs, folding into
the title. Learn adds its inbox and Statistics. Train adds Progress, Days
and, where nothing records, Plans, and so opens on the person's tab, no
longer on Progress. Todo, which has no Profile tab, opens it from a row at
the top of Browse, where Todoist keeps the account.

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-02 09:44:38 +01:00
commit b7b0b937fe
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -1764,4 +1764,247 @@ class HalkyonAppLocalizationsDe extends HalkyonAppLocalizations {
String whatsNewVersion(String version) {
return 'Version $version';
}
@override
String get profileIdentified =>
'Dein Fortschritt wird in deinem Konto gespeichert.';
@override
String get profileProblemAvatarInvalid =>
'Dieses Bild lässt sich nicht verwenden: Wähle ein PNG-, JPEG-, WebP- oder GIF-Bild.';
@override
String get profileProblemBioTooLong => 'Höchstens 500 Zeichen.';
@override
String get profileProblemDisplayNameTooLong => 'Höchstens 30 Zeichen.';
@override
String get profileProblemHandleInvalid =>
'Ein Handle besteht aus 1 bis 30 Buchstaben (a bis z), Ziffern oder Unterstrichen.';
@override
String get profileProblemHandleReserved =>
'Dieses Handle ist der Instanz vorbehalten.';
@override
String get profileProblemHandleTaken =>
'Dieses Handle hat schon jemand anderes.';
@override
String get profileProblemLinkInvalid =>
'Links beginnen mit https:// oder http://.';
@override
String get profileProblemPublished =>
'Du hast veröffentlicht: Dein Handle kann sich nicht mehr ändern und dein Profil nicht mehr gehen.';
@override
String get profileProblemTooManyHandleChecks =>
'Es wurden zu viele Handles ausprobiert. Versuche es in einer Stunde noch einmal.';
@override
String get profileProblemTooManyLinkChecks =>
'Die Links wurden zu oft geprüft. Versuche es in einer Stunde noch einmal.';
@override
String get profileProblemTooManyLinks => 'Höchstens 4 Links.';
@override
String get profileSheetNotFound =>
'Niemand auf dieser Instanz hat diesen Handle.';
@override
String get profileSheetTitle => 'Profil';
@override
String get profileSheetUnreachable =>
'Das Profil konnte nicht geladen werden. Prüfe deine Verbindung.';
@override
String get profileSignInWays => 'Anmeldewege';
@override
String get profileTabProfile => 'Profil';
@override
String get profileTitle => 'Profil';
@override
String get profileWayEmail => 'E-Mail-Adresse';
@override
String get profileWayLinked => 'Meldet dich an';
@override
String get publicProfileAddLink => 'Link hinzufügen';
@override
String publicProfileAddress(String address) {
return 'Andere finden dich als @$address';
}
@override
String publicProfileAddressPrivate(String address) {
return 'Privat, bis du dein Profil ausfüllst oder etwas veröffentlichst; dann finden dich andere als @$address.';
}
@override
String get publicProfileBio => 'Über dich';
@override
String get publicProfileCheckLinks => 'Links prüfen';
@override
String get publicProfileChoosePicture => 'Bild wählen';
@override
String get publicProfileDisplayName => 'Anzeigename';
@override
String get publicProfileDisplayNameHint => 'Der Name neben deinem Handle';
@override
String get publicProfileFailed =>
'Die Instanz ist nicht erreichbar. Versuche es erneut.';
@override
String get publicProfileHandle => 'Handle';
@override
String get publicProfileHandleChangeTitle => 'Ändere dein Handle';
@override
String get publicProfileHandleChecking => 'Wird geprüft …';
@override
String get publicProfileHandleChoose => 'Wähle ein Handle';
@override
String get publicProfileHandleChooseTitle => 'Wähle dein Handle';
@override
String get publicProfileHandleConfirmChange => 'Ändern';
@override
String get publicProfileHandleConfirmChoose => 'Wählen';
@override
String get publicProfileHandleDialogText =>
'Andere finden dich unter deinem Handle. Du kannst es ändern, bis du zum ersten Mal ein Lernset veröffentlichst.';
@override
String get publicProfileHandleFirst =>
'Wähle zuerst dein Handle: Damit wird dein Profil angelegt, und ab dann speichert es sich beim Schreiben.';
@override
String get publicProfileHandleFixed =>
'Fest, seit du veröffentlicht hast: Andere verweisen darauf.';
@override
String publicProfileHandleFree(String handle) {
return '@$handle ist frei';
}
@override
String get publicProfileHandleHint =>
'Buchstaben, Ziffern und Unterstriche, bis zu 30';
@override
String get publicProfileHandleYours => 'Das ist dein Handle';
@override
String get publicProfileIntro =>
'Wie andere dich sehen, sobald du veröffentlichst: das Handle, unter dem sie dich finden, dein Name, ein paar Worte und Links. Es speichert sich beim Schreiben, sobald du dein Handle gewählt hast.';
@override
String get publicProfileLinkHint => 'https://…';
@override
String get publicProfileLinkVerified => 'Verlinkt zurück auf dein Profil';
@override
String get publicProfileLinks => 'Links';
@override
String publicProfileLinksChecked(int count, int verified) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other:
'Geprüft: $verified von $count Links verlinken zurück auf dein Profil.',
one: 'Geprüft: $verified von 1 Link verlinkt zurück auf dein Profil.',
);
return '$_temp0';
}
@override
String get publicProfileLinksHint =>
'Deine Website oder andere Konten, bis zu 4.';
@override
String publicProfilePage(String url) {
return 'Deine Profilseite: $url';
}
@override
String get publicProfilePageCopied => 'Adresse kopiert.';
@override
String get publicProfilePageCopy => 'Adresse kopieren';
@override
String get publicProfilePicture => 'Bild';
@override
String get publicProfilePictureLater =>
'Wähle dein Handle, um ein Bild hinzuzufügen.';
@override
String get publicProfilePictureType => 'Bilder';
@override
String get publicProfileRemove => 'Profil entfernen';
@override
String get publicProfileRemoveLink => 'Link entfernen';
@override
String get publicProfileRemoveMessage =>
'Anzeigename, Text über dich, Links und Bild werden entfernt. Dein Handle bleibt deins und privat, bis du dein Profil wieder ausfüllst oder etwas veröffentlichst.';
@override
String get publicProfileRemovePicture => 'Bild entfernen';
@override
String get publicProfileRemoveTitle => 'Dein öffentliches Profil entfernen?';
@override
String get publicProfileRemoved => 'Profil entfernt.';
@override
String get publicProfileRetry => 'Erneut versuchen';
@override
String get publicProfileSavedNow => 'Gespeichert';
@override
String get publicProfileSaving => 'Wird gespeichert …';
@override
String get publicProfileTitle => 'Öffentliches Profil';
@override
String get publicProfileUnreachable =>
'Dein öffentliches Profil ist gerade nicht erreichbar.';
@override
String get publicProfileVerifyHint =>
'Ein Link bekommt ein Häkchen, sobald seine Seite mit rel=\"me\" auf deine Profilseite zurückverlinkt, wie Mastodon Links prüft.';
@override
String get profileAccount => 'Konto';
@override
String get profileSheetLinkVerified => 'Verlinkt zurück auf dieses Profil';
}