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:
parent
a0bb75f1ad
commit
b7b0b937fe
70 changed files with 1668 additions and 1293 deletions
|
|
@ -10,7 +10,7 @@ Halkyon's apps and the packages they share, in one repository and one pub worksp
|
||||||
- **`packages/`**: what the apps share, each with its README and licence, which the apps take by path (`path: ../../../packages/<package>`), so a change to a shared package and to the apps using it is one commit:
|
- **`packages/`**: what the apps share, each with its README and licence, which the apps take by path (`path: ../../../packages/<package>`), so a change to a shared package and to the apps using it is one commit:
|
||||||
- `halkyon_ui`: Halkyon's look, the theme around cobalt and copper, Noto Sans bundled, the window-size classes and the widgets every screen is built of (the floating bar and rail, `FoldingTabs`' tab row folding into the title), with texts of its own (English, German).
|
- `halkyon_ui`: Halkyon's look, the theme around cobalt and copper, Noto Sans bundled, the window-size classes and the widgets every screen is built of (the floating bar and rail, `FoldingTabs`' tab row folding into the title), with texts of its own (English, German).
|
||||||
- `halkyon_base_server`, `halkyon_base_client`: the Serverpod module every Halkyon server includes (ADR 0014): signing in (a password with TOTP and the resets of ADR 0017, SimpleLogin on `halkyon_oidc`, email codes proving an address; no anonymous accounts since ADR 0020, D25, nor GitHub since D36), an account's ways in and its deletion with a hook for each app's own data, the pruning, the instance's basics, people's handles and public profiles, who may sign up (`SIGN_UP`: open, approval, closed) with the accounts waiting for approval and the instance's operators who approve them (Halkyon Learn's ADR 0021, step 1), the operator's assistants forwarded on halkyon_llm with their grants, each person's budget, the efforts they allow and counted figures, and the instance's privacy page made from its settings (step 2), and the instance's register (ADR 0016): one account per person across an operator's services, held by one service (Learn's server on learn.halkyon.eu) and asked by the others, its members (`ACCOUNT_REGISTER_URL`), all sharing a secret (`INSTANCE_SECRET`); its README says how.
|
- `halkyon_base_server`, `halkyon_base_client`: the Serverpod module every Halkyon server includes (ADR 0014): signing in (a password with TOTP and the resets of ADR 0017, SimpleLogin on `halkyon_oidc`, email codes proving an address; no anonymous accounts since ADR 0020, D25, nor GitHub since D36), an account's ways in and its deletion with a hook for each app's own data, the pruning, the instance's basics, people's handles and public profiles, who may sign up (`SIGN_UP`: open, approval, closed) with the accounts waiting for approval and the instance's operators who approve them (Halkyon Learn's ADR 0021, step 1), the operator's assistants forwarded on halkyon_llm with their grants, each person's budget, the efforts they allow and counted figures, and the instance's privacy page made from its settings (step 2), and the instance's register (ADR 0016): one account per person across an operator's services, held by one service (Learn's server on learn.halkyon.eu) and asked by the others, its members (`ACCOUNT_REGISTER_URL`), all sharing a secret (`INSTANCE_SECRET`); its README says how.
|
||||||
- `halkyon_app`: every app's shell on the module's client (ADR 0014): the instances a device keeps accounts on and the first start, signing in and switching person, the gates building an app's dependencies per instance and per person, the sync service and where it stands, the account section of an app's settings (`AccountTiles`), the wait screen of an account waiting for approval and the operator's card, badge and screen (ADR 0021), the assistants of an app's settings (`AssistantsCard`: granted, by provider, agreed to, what is left of the person's budget, used, and the person's own keys) and the operator's grants from that screen (`AssistantGrantsScreen`: several assistants to several people at once, each with one budget, D57 to D63), with the repositories asking them through the module, at an effort the operator allows, or a person's own key directly (step 2) and what an app's warning before a private studyset goes names (`providerTermsOf`, `OwnAssistant.onThisMachine`, step 3), About with the instance's source link (`showAppAbout`), what's new after an update (`WhatsNew`, `WhatsNewOnUpdate`, `WhatsNewTile`, from the app's `assets/whats_new/`, Train's ADR 0030, D61), the language every app picks (`resolveAppLocale`) and countries' and subdivisions' names (Unicode CLDR's, bundled), with texts that name the app.
|
- `halkyon_app`: every app's shell on the module's client (ADR 0014): the instances a device keeps accounts on and the first start, signing in and switching person, the gates building an app's dependencies per instance and per person, the sync service and where it stands, the account section of an app's settings (`AccountTiles`), every app's Profile (`HalkyonProfile`, decided 2026-11-02: the person's own tab, the same in every app, with their account, the ways they sign in and their public profile, one for all apps, then the app's own tabs) and people's public profiles (`PublicProfileRepository`, `PublicProfileSection`, `showProfileOf`), the wait screen of an account waiting for approval and the operator's card, badge and screen (ADR 0021), the assistants of an app's settings (`AssistantsCard`: granted, by provider, agreed to, what is left of the person's budget, used, and the person's own keys) and the operator's grants from that screen (`AssistantGrantsScreen`: several assistants to several people at once, each with one budget, D57 to D63), with the repositories asking them through the module, at an effort the operator allows, or a person's own key directly (step 2) and what an app's warning before a private studyset goes names (`providerTermsOf`, `OwnAssistant.onThisMachine`, step 3), About with the instance's source link (`showAppAbout`), what's new after an update (`WhatsNew`, `WhatsNewOnUpdate`, `WhatsNewTile`, from the app's `assets/whats_new/`, Train's ADR 0030, D61), the language every app picks (`resolveAppLocale`) and countries' and subdivisions' names (Unicode CLDR's, bundled), with texts that name the app.
|
||||||
- `halkyon_core` (low-level primitives in pure Dart: ids, a logger, `SerialQueue`, `CoalescingRunner`) and `halkyon_interop` (contracts between apps, pure Dart).
|
- `halkyon_core` (low-level primitives in pure Dart: ids, a logger, `SerialQueue`, `CoalescingRunner`) and `halkyon_interop` (contracts between apps, pure Dart).
|
||||||
- `halkyon_keys` (pure Dart on libsodium, ADR 0017): an account's keys on the device, the password's Argon2id and SRP's x, the key pairs and their wrapping, the recovery phrase, data keys, content sealed and signed, row IDs keyed by the account (`keyedRowId`). SRP-6a's two halves are the module's (`halkyon_base_server`'s `base.dart`, `halkyon_base_client`'s `srp.dart`), as are TOTP and the recovery codes. `sodium`'s build hook compiles libsodium, so every machine that builds or tests needs a C compiler and `make`.
|
- `halkyon_keys` (pure Dart on libsodium, ADR 0017): an account's keys on the device, the password's Argon2id and SRP's x, the key pairs and their wrapping, the recovery phrase, data keys, content sealed and signed, row IDs keyed by the account (`keyedRowId`). SRP-6a's two halves are the module's (`halkyon_base_server`'s `base.dart`, `halkyon_base_client`'s `srp.dart`), as are TOTP and the recovery codes. `sodium`'s build hook compiles libsodium, so every machine that builds or tests needs a C compiler and `make`.
|
||||||
- `halkyon_llm` (pure Dart, Halkyon Learn's ADR 0021, D15 and D46): language models' APIs streamed over plain HTTP, no SDKs: Anthropic's Messages API, OpenAI's chat completions (each known host's fields, D45) and its Responses API, behind one interface (`LlmClient`), with `FakeLlmClient` for tests; tested on replies written from the providers' documentation and on those `tool/record_llm.dart` records with a key (D36). The module forwards the operator's assistants with it, and the apps call a person's own provider. BSD-3-Clause as `halkyon_oidc`, `publish_to: none`.
|
- `halkyon_llm` (pure Dart, Halkyon Learn's ADR 0021, D15 and D46): language models' APIs streamed over plain HTTP, no SDKs: Anthropic's Messages API, OpenAI's chat completions (each known host's fields, D45) and its Responses API, behind one interface (`LlmClient`), with `FakeLlmClient` for tests; tested on replies written from the providers' documentation and on those `tool/record_llm.dart` records with a key (D36). The module forwards the operator's assistants with it, and the apps call a person's own provider. BSD-3-Clause as `halkyon_oidc`, `publish_to: none`.
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -447,8 +447,6 @@
|
||||||
"exploreTitle": "Entdecken",
|
"exploreTitle": "Entdecken",
|
||||||
"exploreEmpty": "Lernsets, die andere teilen, erscheinen hier.",
|
"exploreEmpty": "Lernsets, die andere teilen, erscheinen hier.",
|
||||||
|
|
||||||
"profileTitle": "Profil",
|
|
||||||
"profileTabProfile": "Profil",
|
|
||||||
"profileTabStatistics": "Statistik",
|
"profileTabStatistics": "Statistik",
|
||||||
"statisticsDays": "Tage",
|
"statisticsDays": "Tage",
|
||||||
"statisticsWeeks": "Wochen",
|
"statisticsWeeks": "Wochen",
|
||||||
|
|
@ -467,75 +465,9 @@
|
||||||
"statisticsWeekOf": "Woche ab {date}",
|
"statisticsWeekOf": "Woche ab {date}",
|
||||||
"@statisticsWeekOf": {"placeholders": {"date": {"type": "String"}}},
|
"@statisticsWeekOf": {"placeholders": {"date": {"type": "String"}}},
|
||||||
"statisticsNothingYet": "Noch nichts gelernt. Deine Lernzeit und Bewertungen erscheinen hier, sobald du Karteikarten lernst.",
|
"statisticsNothingYet": "Noch nichts gelernt. Deine Lernzeit und Bewertungen erscheinen hier, sobald du Karteikarten lernst.",
|
||||||
"profileSettingsTooltip": "Einstellungen",
|
|
||||||
"profileIdentified": "Dein Fortschritt wird in deinem Konto gespeichert.",
|
|
||||||
"profileSignInWays": "Anmeldewege",
|
|
||||||
"profileWayEmail": "E-Mail-Adresse",
|
|
||||||
"profileWayLinked": "Meldet dich an",
|
|
||||||
"publicProfileTitle": "Öffentliches Profil",
|
|
||||||
"profileSheetTitle": "Profil",
|
"profileSheetTitle": "Profil",
|
||||||
"profileSheetNotFound": "Niemand auf dieser Instanz hat diesen Handle.",
|
"profileSheetNotFound": "Niemand auf dieser Instanz hat diesen Handle.",
|
||||||
"profileSheetLinkVerified": "Verlinkt zurück auf dieses Profil",
|
|
||||||
"profileSheetUnreachable": "Das Profil konnte nicht geladen werden. Prüfe deine Verbindung.",
|
"profileSheetUnreachable": "Das Profil konnte nicht geladen werden. Prüfe deine Verbindung.",
|
||||||
"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.",
|
|
||||||
"publicProfileDisplayName": "Anzeigename",
|
|
||||||
"publicProfileDisplayNameHint": "Der Name neben deinem Handle",
|
|
||||||
"publicProfileHandle": "Handle",
|
|
||||||
"publicProfileHandleHint": "Buchstaben, Ziffern und Unterstriche, bis zu 30",
|
|
||||||
"publicProfileAddress": "Andere finden dich als @{address}",
|
|
||||||
"@publicProfileAddress": {"placeholders": {"address": {"type": "String"}}},
|
|
||||||
"publicProfileAddressPrivate": "Privat, bis du dein Profil ausfüllst oder etwas veröffentlichst; dann finden dich andere als @{address}.",
|
|
||||||
"@publicProfileAddressPrivate": {"placeholders": {"address": {"type": "String"}}},
|
|
||||||
"publicProfileHandleFixed": "Fest, seit du veröffentlicht hast: Andere verweisen darauf.",
|
|
||||||
"publicProfileBio": "Über dich",
|
|
||||||
"publicProfileLinks": "Links",
|
|
||||||
"publicProfileLinksHint": "Deine Website oder andere Konten, bis zu 4.",
|
|
||||||
"publicProfileLinkHint": "https://…",
|
|
||||||
"publicProfileAddLink": "Link hinzufügen",
|
|
||||||
"publicProfilePage": "Deine Profilseite: {url}",
|
|
||||||
"publicProfilePageCopy": "Adresse kopieren",
|
|
||||||
"publicProfilePageCopied": "Adresse kopiert.",
|
|
||||||
"publicProfileVerifyHint": "Ein Link bekommt ein Häkchen, sobald seine Seite mit rel=\"me\" auf deine Profilseite zurückverlinkt, wie Mastodon Links prüft.",
|
|
||||||
"publicProfileCheckLinks": "Links prüfen",
|
|
||||||
"publicProfileLinkVerified": "Verlinkt zurück auf dein Profil",
|
|
||||||
"publicProfileLinksChecked": "{count, plural, =1{Geprüft: {verified} von 1 Link verlinkt zurück auf dein Profil.} other{Geprüft: {verified} von {count} Links verlinken zurück auf dein Profil.}}",
|
|
||||||
"publicProfileRemoveLink": "Link entfernen",
|
|
||||||
"publicProfileSaving": "Wird gespeichert …",
|
|
||||||
"publicProfileSavedNow": "Gespeichert",
|
|
||||||
"publicProfileHandleChoose": "Wähle ein Handle",
|
|
||||||
"publicProfileHandleFirst": "Wähle zuerst dein Handle: Damit wird dein Profil angelegt, und ab dann speichert es sich beim Schreiben.",
|
|
||||||
"publicProfileHandleChooseTitle": "Wähle dein Handle",
|
|
||||||
"publicProfileHandleChangeTitle": "Ändere dein Handle",
|
|
||||||
"publicProfileHandleDialogText": "Andere finden dich unter deinem Handle. Du kannst es ändern, bis du zum ersten Mal ein Lernset veröffentlichst.",
|
|
||||||
"publicProfileHandleChecking": "Wird geprüft …",
|
|
||||||
"publicProfileHandleFree": "@{handle} ist frei",
|
|
||||||
"@publicProfileHandleFree": {"placeholders": {"handle": {"type": "String"}}},
|
|
||||||
"publicProfileHandleYours": "Das ist dein Handle",
|
|
||||||
"publicProfileHandleConfirmChoose": "Wählen",
|
|
||||||
"publicProfileHandleConfirmChange": "Ändern",
|
|
||||||
"publicProfileRemove": "Profil entfernen",
|
|
||||||
"publicProfileRemoveTitle": "Dein öffentliches Profil entfernen?",
|
|
||||||
"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.",
|
|
||||||
"publicProfileRemoved": "Profil entfernt.",
|
|
||||||
"publicProfileFailed": "Die Instanz ist nicht erreichbar. Versuche es erneut.",
|
|
||||||
"publicProfileUnreachable": "Dein öffentliches Profil ist gerade nicht erreichbar.",
|
|
||||||
"publicProfileRetry": "Erneut versuchen",
|
|
||||||
"profileProblemHandleInvalid": "Ein Handle besteht aus 1 bis 30 Buchstaben (a bis z), Ziffern oder Unterstrichen.",
|
|
||||||
"profileProblemHandleReserved": "Dieses Handle ist der Instanz vorbehalten.",
|
|
||||||
"profileProblemHandleTaken": "Dieses Handle hat schon jemand anderes.",
|
|
||||||
"profileProblemPublished": "Du hast veröffentlicht: Dein Handle kann sich nicht mehr ändern und dein Profil nicht mehr gehen.",
|
|
||||||
"profileProblemDisplayNameTooLong": "Höchstens 30 Zeichen.",
|
|
||||||
"profileProblemBioTooLong": "Höchstens 500 Zeichen.",
|
|
||||||
"profileProblemTooManyLinks": "Höchstens 4 Links.",
|
|
||||||
"profileProblemLinkInvalid": "Links beginnen mit https:// oder http://.",
|
|
||||||
"profileProblemAvatarInvalid": "Dieses Bild lässt sich nicht verwenden: Wähle ein PNG-, JPEG-, WebP- oder GIF-Bild.",
|
|
||||||
"profileProblemTooManyLinkChecks": "Die Links wurden zu oft geprüft. Versuche es in einer Stunde noch einmal.",
|
|
||||||
"profileProblemTooManyHandleChecks": "Es wurden zu viele Handles ausprobiert. Versuche es in einer Stunde noch einmal.",
|
|
||||||
"publicProfilePicture": "Bild",
|
|
||||||
"publicProfileChoosePicture": "Bild wählen",
|
|
||||||
"publicProfileRemovePicture": "Bild entfernen",
|
|
||||||
"publicProfilePictureType": "Bilder",
|
|
||||||
"publicProfilePictureLater": "Wähle dein Handle, um ein Bild hinzuzufügen.",
|
|
||||||
|
|
||||||
"settingsTitle": "Einstellungen",
|
"settingsTitle": "Einstellungen",
|
||||||
"settingsAccount": "Konto",
|
"settingsAccount": "Konto",
|
||||||
|
|
|
||||||
|
|
@ -504,8 +504,6 @@
|
||||||
"exploreTitle": "Explore",
|
"exploreTitle": "Explore",
|
||||||
"exploreEmpty": "Studysets that others share will appear here.",
|
"exploreEmpty": "Studysets that others share will appear here.",
|
||||||
|
|
||||||
"profileTitle": "Profile",
|
|
||||||
"profileTabProfile": "Profile",
|
|
||||||
"profileTabStatistics": "Statistics",
|
"profileTabStatistics": "Statistics",
|
||||||
"statisticsDays": "Days",
|
"statisticsDays": "Days",
|
||||||
"statisticsWeeks": "Weeks",
|
"statisticsWeeks": "Weeks",
|
||||||
|
|
@ -532,81 +530,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"statisticsNothingYet": "Nothing studied yet. Your study time and ratings show here once you study flashcards.",
|
"statisticsNothingYet": "Nothing studied yet. Your study time and ratings show here once you study flashcards.",
|
||||||
"profileSettingsTooltip": "Settings",
|
|
||||||
"profileIdentified": "Your progress is kept with your account.",
|
|
||||||
"profileSignInWays": "Ways to sign in",
|
|
||||||
"profileWayEmail": "Email address",
|
|
||||||
"profileWayLinked": "Signs you in",
|
|
||||||
"publicProfileTitle": "Public profile",
|
|
||||||
"profileSheetTitle": "Profile",
|
"profileSheetTitle": "Profile",
|
||||||
"profileSheetNotFound": "Nobody on this instance has this handle.",
|
"profileSheetNotFound": "Nobody on this instance has this handle.",
|
||||||
"profileSheetLinkVerified": "Links back to this profile",
|
|
||||||
"profileSheetUnreachable": "The profile couldn’t be loaded. Check your connection.",
|
"profileSheetUnreachable": "The profile couldn’t be loaded. Check your connection.",
|
||||||
"publicProfileIntro": "How others see you once you publish: the handle they find you by, your name, a few words and links. It saves as you write, once you have chosen your handle.",
|
|
||||||
"publicProfileDisplayName": "Display name",
|
|
||||||
"publicProfileDisplayNameHint": "The name shown beside your handle",
|
|
||||||
"publicProfileHandle": "Handle",
|
|
||||||
"publicProfileHandleHint": "Letters, digits and underscores, up to 30",
|
|
||||||
"publicProfileAddress": "Others find you as @{address}",
|
|
||||||
"@publicProfileAddress": {"placeholders": {"address": {"type": "String"}}},
|
|
||||||
"publicProfileAddressPrivate": "Private until you fill in your profile or publish something; then others find you as @{address}.",
|
|
||||||
"@publicProfileAddressPrivate": {"placeholders": {"address": {"type": "String"}}},
|
|
||||||
"publicProfileHandleFixed": "Fixed since you published: others refer to it.",
|
|
||||||
"publicProfileBio": "Bio",
|
|
||||||
"publicProfileLinks": "Links",
|
|
||||||
"publicProfileLinksHint": "Your site or other accounts, up to 4.",
|
|
||||||
"publicProfileLinkHint": "https://…",
|
|
||||||
"publicProfileAddLink": "Add link",
|
|
||||||
"publicProfilePage": "Your profile page: {url}",
|
|
||||||
"@publicProfilePage": {"placeholders": {"url": {"type": "String"}}},
|
|
||||||
"publicProfilePageCopy": "Copy the address",
|
|
||||||
"publicProfilePageCopied": "Address copied.",
|
|
||||||
"publicProfileVerifyHint": "A link gets a checkmark once its page links back to your profile page with rel=\"me\", as Mastodon checks links.",
|
|
||||||
"publicProfileCheckLinks": "Check links",
|
|
||||||
"publicProfileLinkVerified": "Links back to your profile",
|
|
||||||
"publicProfileLinksChecked": "{count, plural, =1{Checked: {verified} of 1 link links back to your profile.} other{Checked: {verified} of {count} links link back to your profile.}}",
|
|
||||||
"@publicProfileLinksChecked": {"placeholders": {"count": {"type": "int"}, "verified": {"type": "int"}}},
|
|
||||||
"publicProfileRemoveLink": "Remove link",
|
|
||||||
"publicProfileSaving": "Saving…",
|
|
||||||
"publicProfileSavedNow": "Saved",
|
|
||||||
"publicProfileHandleChoose": "Choose a handle",
|
|
||||||
"publicProfileHandleFirst": "Choose your handle first: your profile is made with it, and saves as you write from then on.",
|
|
||||||
"publicProfileHandleChooseTitle": "Choose your handle",
|
|
||||||
"publicProfileHandleChangeTitle": "Change your handle",
|
|
||||||
"publicProfileHandleDialogText": "Others find you by your handle. You can change it until you first publish a studyset.",
|
|
||||||
"publicProfileHandleChecking": "Checking…",
|
|
||||||
"publicProfileHandleFree": "@{handle} is free",
|
|
||||||
"@publicProfileHandleFree": {
|
|
||||||
"placeholders": {
|
|
||||||
"handle": {"type": "String"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"publicProfileHandleYours": "This is your handle",
|
|
||||||
"publicProfileHandleConfirmChoose": "Choose",
|
|
||||||
"publicProfileHandleConfirmChange": "Change",
|
|
||||||
"publicProfileRemove": "Remove profile",
|
|
||||||
"publicProfileRemoveTitle": "Remove your public profile?",
|
|
||||||
"publicProfileRemoveMessage": "Your display name, bio, links and picture are removed. Your handle stays yours and private until you fill in your profile again or publish something.",
|
|
||||||
"publicProfileRemoved": "Profile removed.",
|
|
||||||
"publicProfileFailed": "Couldn't reach the instance. Try again.",
|
|
||||||
"publicProfileUnreachable": "Your public profile can't be reached right now.",
|
|
||||||
"publicProfileRetry": "Retry",
|
|
||||||
"profileProblemHandleInvalid": "A handle is 1 to 30 letters (a to z), digits or underscores.",
|
|
||||||
"profileProblemHandleReserved": "This handle is kept for the instance.",
|
|
||||||
"profileProblemHandleTaken": "Someone else has this handle.",
|
|
||||||
"profileProblemPublished": "You have published: your handle can't change, nor your profile go.",
|
|
||||||
"profileProblemDisplayNameTooLong": "At most 30 characters.",
|
|
||||||
"profileProblemBioTooLong": "At most 500 characters.",
|
|
||||||
"profileProblemTooManyLinks": "At most 4 links.",
|
|
||||||
"profileProblemLinkInvalid": "Links start with https:// or http://.",
|
|
||||||
"profileProblemAvatarInvalid": "This picture can't be used: choose a PNG, JPEG, WebP or GIF image.",
|
|
||||||
"profileProblemTooManyLinkChecks": "The links were checked too often. Try again in an hour.",
|
|
||||||
"profileProblemTooManyHandleChecks": "Too many handles were tried. Try again in an hour.",
|
|
||||||
"publicProfilePicture": "Picture",
|
|
||||||
"publicProfileChoosePicture": "Choose picture",
|
|
||||||
"publicProfileRemovePicture": "Remove picture",
|
|
||||||
"publicProfilePictureType": "Images",
|
|
||||||
"publicProfilePictureLater": "Choose your handle to add a picture.",
|
|
||||||
|
|
||||||
"settingsTitle": "Settings",
|
"settingsTitle": "Settings",
|
||||||
"settingsAccount": "Account",
|
"settingsAccount": "Account",
|
||||||
|
|
|
||||||
|
|
@ -2704,18 +2704,6 @@ abstract class AppLocalizations {
|
||||||
/// **'Studysets that others share will appear here.'**
|
/// **'Studysets that others share will appear here.'**
|
||||||
String get exploreEmpty;
|
String get exploreEmpty;
|
||||||
|
|
||||||
/// No description provided for @profileTitle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Profile'**
|
|
||||||
String get profileTitle;
|
|
||||||
|
|
||||||
/// No description provided for @profileTabProfile.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Profile'**
|
|
||||||
String get profileTabProfile;
|
|
||||||
|
|
||||||
/// No description provided for @profileTabStatistics.
|
/// No description provided for @profileTabStatistics.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|
@ -2812,42 +2800,6 @@ abstract class AppLocalizations {
|
||||||
/// **'Nothing studied yet. Your study time and ratings show here once you study flashcards.'**
|
/// **'Nothing studied yet. Your study time and ratings show here once you study flashcards.'**
|
||||||
String get statisticsNothingYet;
|
String get statisticsNothingYet;
|
||||||
|
|
||||||
/// No description provided for @profileSettingsTooltip.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Settings'**
|
|
||||||
String get profileSettingsTooltip;
|
|
||||||
|
|
||||||
/// No description provided for @profileIdentified.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Your progress is kept with your account.'**
|
|
||||||
String get profileIdentified;
|
|
||||||
|
|
||||||
/// No description provided for @profileSignInWays.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Ways to sign in'**
|
|
||||||
String get profileSignInWays;
|
|
||||||
|
|
||||||
/// No description provided for @profileWayEmail.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Email address'**
|
|
||||||
String get profileWayEmail;
|
|
||||||
|
|
||||||
/// No description provided for @profileWayLinked.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Signs you in'**
|
|
||||||
String get profileWayLinked;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileTitle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Public profile'**
|
|
||||||
String get publicProfileTitle;
|
|
||||||
|
|
||||||
/// No description provided for @profileSheetTitle.
|
/// No description provided for @profileSheetTitle.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|
@ -2860,354 +2812,12 @@ abstract class AppLocalizations {
|
||||||
/// **'Nobody on this instance has this handle.'**
|
/// **'Nobody on this instance has this handle.'**
|
||||||
String get profileSheetNotFound;
|
String get profileSheetNotFound;
|
||||||
|
|
||||||
/// No description provided for @profileSheetLinkVerified.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Links back to this profile'**
|
|
||||||
String get profileSheetLinkVerified;
|
|
||||||
|
|
||||||
/// No description provided for @profileSheetUnreachable.
|
/// No description provided for @profileSheetUnreachable.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'The profile couldn’t be loaded. Check your connection.'**
|
/// **'The profile couldn’t be loaded. Check your connection.'**
|
||||||
String get profileSheetUnreachable;
|
String get profileSheetUnreachable;
|
||||||
|
|
||||||
/// No description provided for @publicProfileIntro.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'How others see you once you publish: the handle they find you by, your name, a few words and links. It saves as you write, once you have chosen your handle.'**
|
|
||||||
String get publicProfileIntro;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileDisplayName.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Display name'**
|
|
||||||
String get publicProfileDisplayName;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileDisplayNameHint.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'The name shown beside your handle'**
|
|
||||||
String get publicProfileDisplayNameHint;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Handle'**
|
|
||||||
String get publicProfileHandle;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleHint.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Letters, digits and underscores, up to 30'**
|
|
||||||
String get publicProfileHandleHint;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileAddress.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Others find you as @{address}'**
|
|
||||||
String publicProfileAddress(String address);
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileAddressPrivate.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Private until you fill in your profile or publish something; then others find you as @{address}.'**
|
|
||||||
String publicProfileAddressPrivate(String address);
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleFixed.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Fixed since you published: others refer to it.'**
|
|
||||||
String get publicProfileHandleFixed;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileBio.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Bio'**
|
|
||||||
String get publicProfileBio;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileLinks.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Links'**
|
|
||||||
String get publicProfileLinks;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileLinksHint.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Your site or other accounts, up to 4.'**
|
|
||||||
String get publicProfileLinksHint;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileLinkHint.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'https://…'**
|
|
||||||
String get publicProfileLinkHint;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileAddLink.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Add link'**
|
|
||||||
String get publicProfileAddLink;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfilePage.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Your profile page: {url}'**
|
|
||||||
String publicProfilePage(String url);
|
|
||||||
|
|
||||||
/// No description provided for @publicProfilePageCopy.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Copy the address'**
|
|
||||||
String get publicProfilePageCopy;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfilePageCopied.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Address copied.'**
|
|
||||||
String get publicProfilePageCopied;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileVerifyHint.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'A link gets a checkmark once its page links back to your profile page with rel=\"me\", as Mastodon checks links.'**
|
|
||||||
String get publicProfileVerifyHint;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileCheckLinks.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Check links'**
|
|
||||||
String get publicProfileCheckLinks;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileLinkVerified.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Links back to your profile'**
|
|
||||||
String get publicProfileLinkVerified;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileLinksChecked.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'{count, plural, =1{Checked: {verified} of 1 link links back to your profile.} other{Checked: {verified} of {count} links link back to your profile.}}'**
|
|
||||||
String publicProfileLinksChecked(int count, int verified);
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRemoveLink.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Remove link'**
|
|
||||||
String get publicProfileRemoveLink;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileSaving.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Saving…'**
|
|
||||||
String get publicProfileSaving;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileSavedNow.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Saved'**
|
|
||||||
String get publicProfileSavedNow;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleChoose.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Choose a handle'**
|
|
||||||
String get publicProfileHandleChoose;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleFirst.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Choose your handle first: your profile is made with it, and saves as you write from then on.'**
|
|
||||||
String get publicProfileHandleFirst;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleChooseTitle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Choose your handle'**
|
|
||||||
String get publicProfileHandleChooseTitle;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleChangeTitle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Change your handle'**
|
|
||||||
String get publicProfileHandleChangeTitle;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleDialogText.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Others find you by your handle. You can change it until you first publish a studyset.'**
|
|
||||||
String get publicProfileHandleDialogText;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleChecking.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Checking…'**
|
|
||||||
String get publicProfileHandleChecking;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleFree.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'@{handle} is free'**
|
|
||||||
String publicProfileHandleFree(String handle);
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleYours.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'This is your handle'**
|
|
||||||
String get publicProfileHandleYours;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleConfirmChoose.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Choose'**
|
|
||||||
String get publicProfileHandleConfirmChoose;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileHandleConfirmChange.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Change'**
|
|
||||||
String get publicProfileHandleConfirmChange;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRemove.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Remove profile'**
|
|
||||||
String get publicProfileRemove;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRemoveTitle.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Remove your public profile?'**
|
|
||||||
String get publicProfileRemoveTitle;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRemoveMessage.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Your display name, bio, links and picture are removed. Your handle stays yours and private until you fill in your profile again or publish something.'**
|
|
||||||
String get publicProfileRemoveMessage;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRemoved.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Profile removed.'**
|
|
||||||
String get publicProfileRemoved;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileFailed.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Couldn\'t reach the instance. Try again.'**
|
|
||||||
String get publicProfileFailed;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileUnreachable.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Your public profile can\'t be reached right now.'**
|
|
||||||
String get publicProfileUnreachable;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRetry.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Retry'**
|
|
||||||
String get publicProfileRetry;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemHandleInvalid.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'A handle is 1 to 30 letters (a to z), digits or underscores.'**
|
|
||||||
String get profileProblemHandleInvalid;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemHandleReserved.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'This handle is kept for the instance.'**
|
|
||||||
String get profileProblemHandleReserved;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemHandleTaken.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Someone else has this handle.'**
|
|
||||||
String get profileProblemHandleTaken;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemPublished.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'You have published: your handle can\'t change, nor your profile go.'**
|
|
||||||
String get profileProblemPublished;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemDisplayNameTooLong.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'At most 30 characters.'**
|
|
||||||
String get profileProblemDisplayNameTooLong;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemBioTooLong.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'At most 500 characters.'**
|
|
||||||
String get profileProblemBioTooLong;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemTooManyLinks.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'At most 4 links.'**
|
|
||||||
String get profileProblemTooManyLinks;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemLinkInvalid.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Links start with https:// or http://.'**
|
|
||||||
String get profileProblemLinkInvalid;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemAvatarInvalid.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'This picture can\'t be used: choose a PNG, JPEG, WebP or GIF image.'**
|
|
||||||
String get profileProblemAvatarInvalid;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemTooManyLinkChecks.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'The links were checked too often. Try again in an hour.'**
|
|
||||||
String get profileProblemTooManyLinkChecks;
|
|
||||||
|
|
||||||
/// No description provided for @profileProblemTooManyHandleChecks.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Too many handles were tried. Try again in an hour.'**
|
|
||||||
String get profileProblemTooManyHandleChecks;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfilePicture.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Picture'**
|
|
||||||
String get publicProfilePicture;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileChoosePicture.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Choose picture'**
|
|
||||||
String get publicProfileChoosePicture;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfileRemovePicture.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Remove picture'**
|
|
||||||
String get publicProfileRemovePicture;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfilePictureType.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Images'**
|
|
||||||
String get publicProfilePictureType;
|
|
||||||
|
|
||||||
/// No description provided for @publicProfilePictureLater.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Choose your handle to add a picture.'**
|
|
||||||
String get publicProfilePictureLater;
|
|
||||||
|
|
||||||
/// No description provided for @settingsTitle.
|
/// No description provided for @settingsTitle.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|
|
||||||
|
|
@ -1639,12 +1639,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get exploreEmpty => 'Lernsets, die andere teilen, erscheinen hier.';
|
String get exploreEmpty => 'Lernsets, die andere teilen, erscheinen hier.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileTitle => 'Profil';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileTabProfile => 'Profil';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileTabStatistics => 'Statistik';
|
String get profileTabStatistics => 'Statistik';
|
||||||
|
|
||||||
|
|
@ -1708,25 +1702,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
String get statisticsNothingYet =>
|
String get statisticsNothingYet =>
|
||||||
'Noch nichts gelernt. Deine Lernzeit und Bewertungen erscheinen hier, sobald du Karteikarten lernst.';
|
'Noch nichts gelernt. Deine Lernzeit und Bewertungen erscheinen hier, sobald du Karteikarten lernst.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileSettingsTooltip => 'Einstellungen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileIdentified =>
|
|
||||||
'Dein Fortschritt wird in deinem Konto gespeichert.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileSignInWays => 'Anmeldewege';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileWayEmail => 'E-Mail-Adresse';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileWayLinked => 'Meldet dich an';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileTitle => 'Öffentliches Profil';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileSheetTitle => 'Profil';
|
String get profileSheetTitle => 'Profil';
|
||||||
|
|
||||||
|
|
@ -1734,217 +1709,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
String get profileSheetNotFound =>
|
String get profileSheetNotFound =>
|
||||||
'Niemand auf dieser Instanz hat diesen Handle.';
|
'Niemand auf dieser Instanz hat diesen Handle.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileSheetLinkVerified => 'Verlinkt zurück auf dieses Profil';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileSheetUnreachable =>
|
String get profileSheetUnreachable =>
|
||||||
'Das Profil konnte nicht geladen werden. Prüfe deine Verbindung.';
|
'Das Profil konnte nicht geladen werden. Prüfe deine Verbindung.';
|
||||||
|
|
||||||
@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 publicProfileDisplayName => 'Anzeigename';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileDisplayNameHint => 'Der Name neben deinem Handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandle => 'Handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleHint =>
|
|
||||||
'Buchstaben, Ziffern und Unterstriche, bis zu 30';
|
|
||||||
|
|
||||||
@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 publicProfileHandleFixed =>
|
|
||||||
'Fest, seit du veröffentlicht hast: Andere verweisen darauf.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileBio => 'Über dich';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinks => 'Links';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinksHint =>
|
|
||||||
'Deine Website oder andere Konten, bis zu 4.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinkHint => 'https://…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileAddLink => 'Link hinzufügen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfilePage(String url) {
|
|
||||||
return 'Deine Profilseite: $url';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePageCopy => 'Adresse kopieren';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePageCopied => 'Adresse kopiert.';
|
|
||||||
|
|
||||||
@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 publicProfileCheckLinks => 'Links prüfen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinkVerified => 'Verlinkt zurück auf dein Profil';
|
|
||||||
|
|
||||||
@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 publicProfileRemoveLink => 'Link entfernen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileSaving => 'Wird gespeichert …';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileSavedNow => 'Gespeichert';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleChoose => 'Wähle ein Handle';
|
|
||||||
|
|
||||||
@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 publicProfileHandleChooseTitle => 'Wähle dein Handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleChangeTitle => 'Ändere dein Handle';
|
|
||||||
|
|
||||||
@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 publicProfileHandleChecking => 'Wird geprüft …';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfileHandleFree(String handle) {
|
|
||||||
return '@$handle ist frei';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleYours => 'Das ist dein Handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleConfirmChoose => 'Wählen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleConfirmChange => 'Ändern';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemove => 'Profil entfernen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemoveTitle => 'Dein öffentliches Profil 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 publicProfileRemoved => 'Profil entfernt.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileFailed =>
|
|
||||||
'Die Instanz ist nicht erreichbar. Versuche es erneut.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileUnreachable =>
|
|
||||||
'Dein öffentliches Profil ist gerade nicht erreichbar.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRetry => 'Erneut versuchen';
|
|
||||||
|
|
||||||
@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 profileProblemPublished =>
|
|
||||||
'Du hast veröffentlicht: Dein Handle kann sich nicht mehr ändern und dein Profil nicht mehr gehen.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemDisplayNameTooLong => 'Höchstens 30 Zeichen.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemBioTooLong => 'Höchstens 500 Zeichen.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemTooManyLinks => 'Höchstens 4 Links.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemLinkInvalid =>
|
|
||||||
'Links beginnen mit https:// oder http://.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemAvatarInvalid =>
|
|
||||||
'Dieses Bild lässt sich nicht verwenden: Wähle ein PNG-, JPEG-, WebP- oder GIF-Bild.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemTooManyLinkChecks =>
|
|
||||||
'Die Links wurden zu oft geprüft. Versuche es in einer Stunde noch einmal.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemTooManyHandleChecks =>
|
|
||||||
'Es wurden zu viele Handles ausprobiert. Versuche es in einer Stunde noch einmal.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePicture => 'Bild';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileChoosePicture => 'Bild wählen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemovePicture => 'Bild entfernen';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePictureType => 'Bilder';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePictureLater =>
|
|
||||||
'Wähle dein Handle, um ein Bild hinzuzufügen.';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get settingsTitle => 'Einstellungen';
|
String get settingsTitle => 'Einstellungen';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1624,12 +1624,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get exploreEmpty => 'Studysets that others share will appear here.';
|
String get exploreEmpty => 'Studysets that others share will appear here.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileTitle => 'Profile';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileTabProfile => 'Profile';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileTabStatistics => 'Statistics';
|
String get profileTabStatistics => 'Statistics';
|
||||||
|
|
||||||
|
|
@ -1693,238 +1687,16 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
String get statisticsNothingYet =>
|
String get statisticsNothingYet =>
|
||||||
'Nothing studied yet. Your study time and ratings show here once you study flashcards.';
|
'Nothing studied yet. Your study time and ratings show here once you study flashcards.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileSettingsTooltip => 'Settings';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileIdentified => 'Your progress is kept with your account.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileSignInWays => 'Ways to sign in';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileWayEmail => 'Email address';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileWayLinked => 'Signs you in';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileTitle => 'Public profile';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileSheetTitle => 'Profile';
|
String get profileSheetTitle => 'Profile';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileSheetNotFound => 'Nobody on this instance has this handle.';
|
String get profileSheetNotFound => 'Nobody on this instance has this handle.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileSheetLinkVerified => 'Links back to this profile';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get profileSheetUnreachable =>
|
String get profileSheetUnreachable =>
|
||||||
'The profile couldn’t be loaded. Check your connection.';
|
'The profile couldn’t be loaded. Check your connection.';
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileIntro =>
|
|
||||||
'How others see you once you publish: the handle they find you by, your name, a few words and links. It saves as you write, once you have chosen your handle.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileDisplayName => 'Display name';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileDisplayNameHint =>
|
|
||||||
'The name shown beside your handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandle => 'Handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleHint =>
|
|
||||||
'Letters, digits and underscores, up to 30';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfileAddress(String address) {
|
|
||||||
return 'Others find you as @$address';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfileAddressPrivate(String address) {
|
|
||||||
return 'Private until you fill in your profile or publish something; then others find you as @$address.';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleFixed =>
|
|
||||||
'Fixed since you published: others refer to it.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileBio => 'Bio';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinks => 'Links';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinksHint => 'Your site or other accounts, up to 4.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinkHint => 'https://…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileAddLink => 'Add link';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfilePage(String url) {
|
|
||||||
return 'Your profile page: $url';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePageCopy => 'Copy the address';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePageCopied => 'Address copied.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileVerifyHint =>
|
|
||||||
'A link gets a checkmark once its page links back to your profile page with rel=\"me\", as Mastodon checks links.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileCheckLinks => 'Check links';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileLinkVerified => 'Links back to your profile';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfileLinksChecked(int count, int verified) {
|
|
||||||
String _temp0 = intl.Intl.pluralLogic(
|
|
||||||
count,
|
|
||||||
locale: localeName,
|
|
||||||
other: 'Checked: $verified of $count links link back to your profile.',
|
|
||||||
one: 'Checked: $verified of 1 link links back to your profile.',
|
|
||||||
);
|
|
||||||
return '$_temp0';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemoveLink => 'Remove link';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileSaving => 'Saving…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileSavedNow => 'Saved';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleChoose => 'Choose a handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleFirst =>
|
|
||||||
'Choose your handle first: your profile is made with it, and saves as you write from then on.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleChooseTitle => 'Choose your handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleChangeTitle => 'Change your handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleDialogText =>
|
|
||||||
'Others find you by your handle. You can change it until you first publish a studyset.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleChecking => 'Checking…';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String publicProfileHandleFree(String handle) {
|
|
||||||
return '@$handle is free';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleYours => 'This is your handle';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleConfirmChoose => 'Choose';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileHandleConfirmChange => 'Change';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemove => 'Remove profile';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemoveTitle => 'Remove your public profile?';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemoveMessage =>
|
|
||||||
'Your display name, bio, links and picture are removed. Your handle stays yours and private until you fill in your profile again or publish something.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemoved => 'Profile removed.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileFailed => 'Couldn\'t reach the instance. Try again.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileUnreachable =>
|
|
||||||
'Your public profile can\'t be reached right now.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRetry => 'Retry';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemHandleInvalid =>
|
|
||||||
'A handle is 1 to 30 letters (a to z), digits or underscores.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemHandleReserved =>
|
|
||||||
'This handle is kept for the instance.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemHandleTaken => 'Someone else has this handle.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemPublished =>
|
|
||||||
'You have published: your handle can\'t change, nor your profile go.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemDisplayNameTooLong => 'At most 30 characters.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemBioTooLong => 'At most 500 characters.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemTooManyLinks => 'At most 4 links.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemLinkInvalid =>
|
|
||||||
'Links start with https:// or http://.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemAvatarInvalid =>
|
|
||||||
'This picture can\'t be used: choose a PNG, JPEG, WebP or GIF image.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemTooManyLinkChecks =>
|
|
||||||
'The links were checked too often. Try again in an hour.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get profileProblemTooManyHandleChecks =>
|
|
||||||
'Too many handles were tried. Try again in an hour.';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePicture => 'Picture';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileChoosePicture => 'Choose picture';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfileRemovePicture => 'Remove picture';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePictureType => 'Images';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get publicProfilePictureLater =>
|
|
||||||
'Choose your handle to add a picture.';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get settingsTitle => 'Settings';
|
String get settingsTitle => 'Settings';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import 'package:halkyon_learn_flutter/src/core/asset/data/sync_asset_gateway.dar
|
||||||
import 'package:halkyon_learn_flutter/src/core/dependencies/person_dependencies.dart';
|
import 'package:halkyon_learn_flutter/src/core/dependencies/person_dependencies.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/device_settings/data/device_settings_store.dart';
|
import 'package:halkyon_learn_flutter/src/core/device_settings/data/device_settings_store.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/device_settings/model/device_settings.dart';
|
import 'package:halkyon_learn_flutter/src/core/device_settings/model/device_settings.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/files/file_picker.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/core/grammar/grammar_checks.dart';
|
import 'package:halkyon_learn_flutter/src/core/grammar/grammar_checks.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/grammar/grammar_gateway.dart';
|
import 'package:halkyon_learn_flutter/src/core/grammar/grammar_gateway.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/privacy/data/content_keys.dart';
|
import 'package:halkyon_learn_flutter/src/core/privacy/data/content_keys.dart';
|
||||||
|
|
@ -73,8 +72,6 @@ import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/sync_pdf_sourc
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_platform.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_platform.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_platforms.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_platforms.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_run_store.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_run_store.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/data/profile_repository.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/data/serverpod_profile_gateway.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/data/published_store.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/data/published_store.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/data/serverpod_publish_gateway.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/data/serverpod_publish_gateway.dart';
|
||||||
|
|
@ -158,7 +155,11 @@ class Dependencies({
|
||||||
required final SoundPlayer sounds,
|
required final SoundPlayer sounds,
|
||||||
|
|
||||||
/// Lets the person pick files to import.
|
/// Lets the person pick files to import.
|
||||||
required final FilePicker files,
|
@override required final FilePicker files,
|
||||||
|
|
||||||
|
/// People's public profiles on the instance, the person's own among them:
|
||||||
|
/// one for every Halkyon app (decided 2026-11-02).
|
||||||
|
@override required final PublicProfileRepository profiles,
|
||||||
|
|
||||||
/// Lets the person keep files the app made, such as exports.
|
/// Lets the person keep files the app made, such as exports.
|
||||||
@override required final FileSaver fileSaver,
|
@override required final FileSaver fileSaver,
|
||||||
|
|
@ -305,6 +306,9 @@ class Dependencies({
|
||||||
instanceOperators: instanceOperators,
|
instanceOperators: instanceOperators,
|
||||||
assistants: assistants,
|
assistants: assistants,
|
||||||
assistantOperators: assistantOperators,
|
assistantOperators: assistantOperators,
|
||||||
|
profiles: PublicProfileRepository(
|
||||||
|
BasePublicProfileGateway(client.modules.base),
|
||||||
|
),
|
||||||
sourceCodeUrl: () async => (await client.instance.info()).sourceCodeUrl,
|
sourceCodeUrl: () async => (await client.instance.info()).sourceCodeUrl,
|
||||||
dictionaries: DictionaryRepository(
|
dictionaries: DictionaryRepository(
|
||||||
ServerpodDictionaryGateway(client),
|
ServerpodDictionaryGateway(client),
|
||||||
|
|
@ -627,7 +631,6 @@ Future<PersonDependencies> _openPersonData(
|
||||||
privateOffer: FilePrivateOfferStore(
|
privateOffer: FilePrivateOfferStore(
|
||||||
File(p.join(folder.path, 'private_offer')),
|
File(p.join(folder.path, 'private_offer')),
|
||||||
),
|
),
|
||||||
profile: ProfileRepository(ServerpodProfileGateway(client)),
|
|
||||||
publishing: publishing,
|
publishing: publishing,
|
||||||
explore: ExploreRepository(
|
explore: ExploreRepository(
|
||||||
ServerpodExploreGateway(client),
|
ServerpodExploreGateway(client),
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import 'package:halkyon_learn_flutter/src/feature/note/data/note_repository.dart
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_deletions.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_deletions.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_source_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_source_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_run_store.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pomodoro/data/pomodoro_run_store.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/data/profile_repository.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/settings/data/settings_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/settings/data/settings_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/study/data/review_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/study/data/review_repository.dart';
|
||||||
|
|
@ -107,9 +106,6 @@ class PersonDependencies({
|
||||||
/// answered on this device (ADR 0019, D4).
|
/// answered on this device (ADR 0019, D4).
|
||||||
required final PrivateOfferStore privateOffer,
|
required final PrivateOfferStore privateOffer,
|
||||||
|
|
||||||
/// The person's public profile, on the instance.
|
|
||||||
required final ProfileRepository profile,
|
|
||||||
|
|
||||||
/// Publishing the person's studysets, on the instance.
|
/// Publishing the person's studysets, on the instance.
|
||||||
required final PublishRepository publishing,
|
required final PublishRepository publishing,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:halkyon_learn_flutter/src/core/files/file_picker.dart';
|
import 'package:halkyon_app/halkyon_app.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/model/assistant_topic.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/model/assistant_topic.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_engine.dart';
|
import 'package:halkyon_learn_flutter/src/feature/pdf_source/data/pdf_engine.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,128 +1,42 @@
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:halkyon_app/halkyon_app.dart';
|
import 'package:halkyon_app/halkyon_app.dart' as app;
|
||||||
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/dependencies/dependencies.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/discussion/widget/discussion_inbox.dart';
|
import 'package:halkyon_learn_flutter/src/feature/discussion/widget/discussion_inbox.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/feedback/widget/inbox_section.dart';
|
import 'package:halkyon_learn_flutter/src/feature/feedback/widget/inbox_section.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/widget/public_profile_section.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/statistics/widget/statistics_view.dart';
|
import 'package:halkyon_learn_flutter/src/feature/statistics/widget/statistics_view.dart';
|
||||||
import 'package:halkyon_ui/halkyon_ui.dart';
|
import 'package:halkyon_ui/halkyon_ui.dart';
|
||||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||||
import 'package:material_ui/material_ui.dart';
|
import 'package:material_ui/material_ui.dart';
|
||||||
|
|
||||||
/// The profile tab, in two tabs as Vaia has it (decided 2026-10-12): the
|
/// The profile tab: every Halkyon app's Profile (halkyon_app's
|
||||||
/// profile (the ways the person signs in, SimpleLogin, ADR 0020, and their
|
/// [app.HalkyonProfile], decided 2026-11-02), the person's own tab first
|
||||||
/// password and authenticators, ADR 0017) and the person's statistics.
|
/// (their account and how they sign in, Learn's inbox of discussions and
|
||||||
/// Settings are behind the gear. The tab row folds into the title as the
|
/// feedback, and their public profile), then their statistics, in two
|
||||||
/// content scrolls ([FoldingTabs], as Strava's).
|
/// tabs as Vaia has it (decided 2026-10-12). Settings are behind the gear.
|
||||||
class const ProfileScreen({super.key}) extends StatelessWidget {
|
class const ProfileScreen({super.key}) extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = AppLocalizations.of(context);
|
final l10n = AppLocalizations.of(context);
|
||||||
return BlocProvider(
|
return app.HalkyonProfile(
|
||||||
create: (context) =>
|
color: Brand.primary,
|
||||||
SignInWaysCubit(Dependencies.of(context).auth)..load(),
|
background: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||||
child: TopGradient(
|
actions: [
|
||||||
color: Brand.primary,
|
IconButton(
|
||||||
background: Theme.of(context).colorScheme.surfaceContainerLow,
|
icon: const app.WaitingAccountsBadge(
|
||||||
child: FoldingTabs(
|
child: app.SyncTroubleBadge(child: Icon(LucideIcons.settings)),
|
||||||
title: l10n.profileTitle,
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
icon: const WaitingAccountsBadge(
|
|
||||||
child: SyncTroubleBadge(child: Icon(LucideIcons.settings)),
|
|
||||||
),
|
|
||||||
tooltip: l10n.profileSettingsTooltip,
|
|
||||||
onPressed: () => context.push(RoutePaths.settings),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
tabs: [
|
|
||||||
FoldingTab(label: l10n.profileTabProfile, body: const _Account()),
|
|
||||||
FoldingTab(
|
|
||||||
label: l10n.profileTabStatistics,
|
|
||||||
body: const StatisticsView(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class const _Account() extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final l10n = AppLocalizations.of(context);
|
|
||||||
// On the screen itself, in the middle, as wide as readable text.
|
|
||||||
return Center(
|
|
||||||
child: ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(maxWidth: readableContentMaxWidth),
|
|
||||||
// A card for each part, as Settings groups its own.
|
|
||||||
child: ListView(
|
|
||||||
// Room at the end for the navigation bar floating over the foot.
|
|
||||||
padding: EdgeInsets.fromLTRB(
|
|
||||||
12,
|
|
||||||
12,
|
|
||||||
12,
|
|
||||||
12 + MediaQuery.paddingOf(context).bottom,
|
|
||||||
),
|
),
|
||||||
children: [
|
tooltip: l10n.settingsTitle,
|
||||||
SectionCard(
|
onPressed: () => context.push(RoutePaths.settings),
|
||||||
child: Column(
|
),
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
const SizedBox(width: 8),
|
||||||
children: [
|
],
|
||||||
Text(
|
sections: const [InboxSection(discussions: DiscussionInbox())],
|
||||||
l10n.settingsAccount,
|
tabs: [
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
FoldingTab(
|
||||||
),
|
label: l10n.profileTabStatistics,
|
||||||
const SizedBox(height: 4),
|
body: const StatisticsView(),
|
||||||
Text(l10n.profileIdentified),
|
|
||||||
const _SignInWays(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
const SectionCard(
|
|
||||||
child: InboxSection(discussions: DiscussionInbox()),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12),
|
|
||||||
const SectionCard(child: PublicProfileSection()),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// How the person signs in: an email address, and SimpleLogin (ADR 0020,
|
|
||||||
/// D21), with the password and authenticators beneath.
|
|
||||||
class const _SignInWays() extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final l10n = AppLocalizations.of(context);
|
|
||||||
final theme = Theme.of(context);
|
|
||||||
final ways = context.watch<SignInWaysCubit>().state;
|
|
||||||
Widget way(String label, String linkedAs) => ListTile(
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
title: Text(label),
|
|
||||||
subtitle: Text(linkedAs, maxLines: 1, overflow: TextOverflow.ellipsis),
|
|
||||||
trailing: Icon(LucideIcons.circleCheck, color: theme.colorScheme.primary),
|
|
||||||
);
|
|
||||||
return Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Text(l10n.profileSignInWays, style: theme.textTheme.titleSmall),
|
|
||||||
if (ways.ways.email)
|
|
||||||
way(l10n.profileWayEmail, ways.emailAddress ?? l10n.profileWayLinked),
|
|
||||||
// SimpleLogin (ADR 0020, D21): once added, one more way in here.
|
|
||||||
const SimpleLoginSection(gapAbove: 16),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
// The password and authenticators, and setting them up (ADR 0017),
|
|
||||||
// which brings the address.
|
|
||||||
const AccountSecuritySection(),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:halkyon_app/halkyon_app.dart';
|
||||||
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_view.dart';
|
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_view.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/l10n/content_languages.dart';
|
import 'package:halkyon_learn_flutter/src/core/l10n/content_languages.dart';
|
||||||
|
|
@ -8,7 +9,6 @@ import 'package:halkyon_learn_flutter/src/feature/explore/bloc/explore_bloc.dart
|
||||||
import 'package:halkyon_learn_flutter/src/feature/explore/model/explore_studyset.dart';
|
import 'package:halkyon_learn_flutter/src/feature/explore/model/explore_studyset.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/explore/widget/explore_screen.dart';
|
import 'package:halkyon_learn_flutter/src/feature/explore/widget/explore_screen.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/feedback/widget/feedback_threads.dart';
|
import 'package:halkyon_learn_flutter/src/feature/feedback/widget/feedback_threads.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/widget/profile_sheet.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/license_footer.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/license_footer.dart';
|
||||||
import 'package:halkyon_ui/halkyon_ui.dart';
|
import 'package:halkyon_ui/halkyon_ui.dart';
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@ import 'dart:developer';
|
||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:halkyon_app/halkyon_app.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/learning_path/data/learning_path_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/learning_path/data/learning_path_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/note/data/note_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/note/data/note_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/data/profile_repository.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/model/public_profile.dart';
|
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/data/publish_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/model/publication.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/model/publication.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/model/unsettled_item.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/model/unsettled_item.dart';
|
||||||
|
|
@ -23,7 +22,7 @@ import 'package:halkyon_learn_flutter/src/feature/publish/model/unsettled_item.d
|
||||||
/// are left to the person, as [PublishStateReady.unsettled].
|
/// are left to the person, as [PublishStateReady.unsettled].
|
||||||
class PublishBloc(
|
class PublishBloc(
|
||||||
final PublishRepository _publishing,
|
final PublishRepository _publishing,
|
||||||
final ProfileRepository _profiles,
|
final PublicProfileRepository _profiles,
|
||||||
final CardRepository _cards,
|
final CardRepository _cards,
|
||||||
final NoteRepository _notes,
|
final NoteRepository _notes,
|
||||||
final LearningPathRepository _paths, {
|
final LearningPathRepository _paths, {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:halkyon_app/halkyon_app.dart';
|
import 'package:halkyon_app/halkyon_app.dart';
|
||||||
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
|
||||||
|
import 'package:halkyon_learn_flutter/src/core/dependencies/dependencies.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/dependencies/person_dependencies.dart';
|
import 'package:halkyon_learn_flutter/src/core/dependencies/person_dependencies.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/bloc/publish_bloc.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/bloc/publish_bloc.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/publish/widget/publish_sheet.dart';
|
import 'package:halkyon_learn_flutter/src/feature/publish/widget/publish_sheet.dart';
|
||||||
|
|
@ -107,7 +108,7 @@ PublishBloc _publishBloc(BuildContext context, String studysetId) {
|
||||||
final sync = context.read<SyncStatusBloc>();
|
final sync = context.read<SyncStatusBloc>();
|
||||||
return PublishBloc(
|
return PublishBloc(
|
||||||
person.publishing,
|
person.publishing,
|
||||||
person.profile,
|
Dependencies.of(context).profiles,
|
||||||
person.cards,
|
person.cards,
|
||||||
person.notes,
|
person.notes,
|
||||||
person.paths,
|
person.paths,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:halkyon_learn_flutter/src/feature/profile/widget/profile_sheet.dart';
|
import 'package:halkyon_app/halkyon_app.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/model/license_link.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/model/license_link.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
||||||
import 'package:material_ui/material_ui.dart';
|
import 'package:material_ui/material_ui.dart';
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:halkyon_app/testing.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_document.dart';
|
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_document.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_editor.dart';
|
import 'package:halkyon_learn_flutter/src/core/editor/rich_content_editor.dart';
|
||||||
|
|
@ -14,7 +15,6 @@ import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_conten
|
||||||
import 'package:material_ui/material_ui.dart';
|
import 'package:material_ui/material_ui.dart';
|
||||||
|
|
||||||
import '../../support/fake_asset_gateway.dart';
|
import '../../support/fake_asset_gateway.dart';
|
||||||
import '../../support/fake_file_picker.dart';
|
|
||||||
import '../../support/fake_note_gateway.dart';
|
import '../../support/fake_note_gateway.dart';
|
||||||
import '../../support/fake_studyset_gateway.dart';
|
import '../../support/fake_studyset_gateway.dart';
|
||||||
import '../../support/memory_asset_file_cache.dart';
|
import '../../support/memory_asset_file_cache.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:halkyon_app/testing.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
||||||
|
|
@ -14,7 +15,6 @@ import 'package:material_ui/material_ui.dart';
|
||||||
|
|
||||||
import '../../../support/fake_asset_server_gateway.dart';
|
import '../../../support/fake_asset_server_gateway.dart';
|
||||||
import '../../../support/fake_card_gateway.dart';
|
import '../../../support/fake_card_gateway.dart';
|
||||||
import '../../../support/fake_file_picker.dart';
|
|
||||||
import '../../../support/fake_note_gateway.dart';
|
import '../../../support/fake_note_gateway.dart';
|
||||||
import '../../../support/fake_studyset_gateway.dart';
|
import '../../../support/fake_studyset_gateway.dart';
|
||||||
import '../../../support/pump_app.dart';
|
import '../../../support/pump_app.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:halkyon_app/testing.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/data/studyset_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/data/studyset_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/studyset_screen.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/studyset_screen.dart';
|
||||||
|
|
@ -6,7 +7,6 @@ import 'package:material_ui/material_ui.dart';
|
||||||
|
|
||||||
import '../../support/fake_card_gateway.dart';
|
import '../../support/fake_card_gateway.dart';
|
||||||
import '../../support/fake_dictionary_gateway.dart';
|
import '../../support/fake_dictionary_gateway.dart';
|
||||||
import '../../support/fake_file_picker.dart';
|
|
||||||
import '../../support/fake_studyset_gateway.dart';
|
import '../../support/fake_studyset_gateway.dart';
|
||||||
import '../../support/pump_app.dart';
|
import '../../support/pump_app.dart';
|
||||||
import '../../support/test_dependencies.dart';
|
import '../../support/test_dependencies.dart';
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import '../../support/fake_asset_sealing.dart';
|
||||||
import '../../support/fake_asset_server_gateway.dart';
|
import '../../support/fake_asset_server_gateway.dart';
|
||||||
import '../../support/fake_card_gateway.dart';
|
import '../../support/fake_card_gateway.dart';
|
||||||
import '../../support/fake_conversation_gateway.dart';
|
import '../../support/fake_conversation_gateway.dart';
|
||||||
import '../../support/fake_file_picker.dart';
|
|
||||||
import '../../support/fake_grammar_gateway.dart';
|
import '../../support/fake_grammar_gateway.dart';
|
||||||
import '../../support/fake_settings_gateway.dart';
|
import '../../support/fake_settings_gateway.dart';
|
||||||
import '../../support/fake_studyset_gateway.dart';
|
import '../../support/fake_studyset_gateway.dart';
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:halkyon_app/testing.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_payload.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_payload.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
||||||
|
|
@ -10,7 +11,6 @@ import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_conten
|
||||||
import 'package:material_ui/material_ui.dart';
|
import 'package:material_ui/material_ui.dart';
|
||||||
|
|
||||||
import '../../../support/fake_card_gateway.dart';
|
import '../../../support/fake_card_gateway.dart';
|
||||||
import '../../../support/fake_file_picker.dart';
|
|
||||||
import '../../../support/fake_studyset_gateway.dart';
|
import '../../../support/fake_studyset_gateway.dart';
|
||||||
import '../../../support/pump_app.dart';
|
import '../../../support/pump_app.dart';
|
||||||
import '../../../support/test_dependencies.dart';
|
import '../../../support/test_dependencies.dart';
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue