perf(startup): paint a splash immediately, run init off the first frame
main() awaited all of configureDependencies() (open the encrypted DB, derive the social key, seed/scan the species catalog) before the first runApp, so nothing painted until init finished — startup jank visible as skipped frames. Now main() runs runApp immediately with a Bootstrap widget that shows a native-splash-matching green splash while the heavy work runs, then swaps in TaneApp. On failure it shows a localized error with a retry (configureDependencies is idempotent, so retry is safe). Adds a bootstrap i18n group (en/es/pt/ast) and a widget test for the splash/error frame.
This commit is contained in:
parent
33d8b2a4d7
commit
71413f3801
12 changed files with 289 additions and 53 deletions
|
|
@ -2,6 +2,10 @@
|
|||
"app": {
|
||||
"title": "Tanemaki"
|
||||
},
|
||||
"bootstrap": {
|
||||
"failed": "Tanemaki nun pudo aniciar",
|
||||
"retry": "Reintentar"
|
||||
},
|
||||
"common": {
|
||||
"save": "Guardar",
|
||||
"cancel": "Encaboxar",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
"app": {
|
||||
"title": "Tanemaki"
|
||||
},
|
||||
"bootstrap": {
|
||||
"failed": "Tanemaki couldn't start",
|
||||
"retry": "Try again"
|
||||
},
|
||||
"common": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
"app": {
|
||||
"title": "Tanemaki"
|
||||
},
|
||||
"bootstrap": {
|
||||
"failed": "Tanemaki no pudo arrancar",
|
||||
"retry": "Reintentar"
|
||||
},
|
||||
"common": {
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
"app": {
|
||||
"title": "Tanemaki"
|
||||
},
|
||||
"bootstrap": {
|
||||
"failed": "O Tanemaki não conseguiu iniciar",
|
||||
"retry": "Tentar de novo"
|
||||
},
|
||||
"common": {
|
||||
"save": "Guardar",
|
||||
"cancel": "Cancelar",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 4
|
||||
/// Strings: 1464 (366 per locale)
|
||||
/// Strings: 1472 (368 per locale)
|
||||
///
|
||||
/// Built on 2026-07-10 at 13:52 UTC
|
||||
/// Built on 2026-07-10 at 15:00 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class TranslationsAst extends Translations with BaseTranslations<AppLocale, Tran
|
|||
|
||||
// Translations
|
||||
@override late final _Translations$app$ast app = _Translations$app$ast._(_root);
|
||||
@override late final _Translations$bootstrap$ast bootstrap = _Translations$bootstrap$ast._(_root);
|
||||
@override late final _Translations$common$ast common = _Translations$common$ast._(_root);
|
||||
@override late final _Translations$home$ast home = _Translations$home$ast._(_root);
|
||||
@override late final _Translations$photo$ast photo = _Translations$photo$ast._(_root);
|
||||
|
|
@ -85,6 +86,17 @@ class _Translations$app$ast extends Translations$app$en {
|
|||
@override String get title => 'Tanemaki';
|
||||
}
|
||||
|
||||
// Path: bootstrap
|
||||
class _Translations$bootstrap$ast extends Translations$bootstrap$en {
|
||||
_Translations$bootstrap$ast._(TranslationsAst root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsAst _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get failed => 'Tanemaki nun pudo aniciar';
|
||||
@override String get retry => 'Reintentar';
|
||||
}
|
||||
|
||||
// Path: common
|
||||
class _Translations$common$ast extends Translations$common$en {
|
||||
_Translations$common$ast._(TranslationsAst root) : this._root = root, super.internal(root);
|
||||
|
|
@ -645,6 +657,11 @@ class _Translations$market$ast extends Translations$market$en {
|
|||
@override String get useLocation => 'Usar el mio allugamientu averáu';
|
||||
@override String get locationFailed => 'Nun se pudo consiguir el to allugamientu — comprueba que l\'allugamientu ta activáu y el permisu concedíu';
|
||||
@override String get queued => 'Guardáu — compartirémosles cuando tengas conexón';
|
||||
@override String get shareFailed => 'Nun se pudo coneutar colos sirvidores — les tos granes nun se compartieron. Vuelvi a intentalo nun momentu.';
|
||||
@override String get rangeLabel => 'Hasta ónde guetar';
|
||||
@override String get rangeNear => 'Bien cerca';
|
||||
@override String get rangeArea => 'Pela mio zona';
|
||||
@override String get rangeRegion => 'La mio rexón';
|
||||
}
|
||||
|
||||
// Path: profile
|
||||
|
|
@ -1052,6 +1069,8 @@ extension on TranslationsAst {
|
|||
dynamic _flatMapFunction(String path) {
|
||||
return switch (path) {
|
||||
'app.title' => 'Tanemaki',
|
||||
'bootstrap.failed' => 'Tanemaki nun pudo aniciar',
|
||||
'bootstrap.retry' => 'Reintentar',
|
||||
'common.save' => 'Guardar',
|
||||
'common.cancel' => 'Encaboxar',
|
||||
'common.delete' => 'Desaniciar',
|
||||
|
|
@ -1384,6 +1403,11 @@ extension on TranslationsAst {
|
|||
'market.useLocation' => 'Usar el mio allugamientu averáu',
|
||||
'market.locationFailed' => 'Nun se pudo consiguir el to allugamientu — comprueba que l\'allugamientu ta activáu y el permisu concedíu',
|
||||
'market.queued' => 'Guardáu — compartirémosles cuando tengas conexón',
|
||||
'market.shareFailed' => 'Nun se pudo coneutar colos sirvidores — les tos granes nun se compartieron. Vuelvi a intentalo nun momentu.',
|
||||
'market.rangeLabel' => 'Hasta ónde guetar',
|
||||
'market.rangeNear' => 'Bien cerca',
|
||||
'market.rangeArea' => 'Pela mio zona',
|
||||
'market.rangeRegion' => 'La mio rexón',
|
||||
'profile.title' => 'El to perfil',
|
||||
'profile.name' => 'Nome',
|
||||
'profile.nameHint' => 'Cómo te ven los demás',
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class Translations with BaseTranslations<AppLocale, Translations> {
|
|||
|
||||
// Translations
|
||||
late final Translations$app$en app = Translations$app$en.internal(_root);
|
||||
late final Translations$bootstrap$en bootstrap = Translations$bootstrap$en.internal(_root);
|
||||
late final Translations$common$en common = Translations$common$en.internal(_root);
|
||||
late final Translations$home$en home = Translations$home$en.internal(_root);
|
||||
late final Translations$photo$en photo = Translations$photo$en.internal(_root);
|
||||
|
|
@ -88,6 +89,21 @@ class Translations$app$en {
|
|||
String get title => 'Tanemaki';
|
||||
}
|
||||
|
||||
// Path: bootstrap
|
||||
class Translations$bootstrap$en {
|
||||
Translations$bootstrap$en.internal(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
|
||||
/// en: 'Tanemaki couldn't start'
|
||||
String get failed => 'Tanemaki couldn\'t start';
|
||||
|
||||
/// en: 'Try again'
|
||||
String get retry => 'Try again';
|
||||
}
|
||||
|
||||
// Path: common
|
||||
class Translations$common$en {
|
||||
Translations$common$en.internal(this._root);
|
||||
|
|
@ -1776,6 +1792,8 @@ extension on Translations {
|
|||
dynamic _flatMapFunction(String path) {
|
||||
return switch (path) {
|
||||
'app.title' => 'Tanemaki',
|
||||
'bootstrap.failed' => 'Tanemaki couldn\'t start',
|
||||
'bootstrap.retry' => 'Try again',
|
||||
'common.save' => 'Save',
|
||||
'common.cancel' => 'Cancel',
|
||||
'common.delete' => 'Delete',
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class TranslationsEs extends Translations with BaseTranslations<AppLocale, Trans
|
|||
|
||||
// Translations
|
||||
@override late final _Translations$app$es app = _Translations$app$es._(_root);
|
||||
@override late final _Translations$bootstrap$es bootstrap = _Translations$bootstrap$es._(_root);
|
||||
@override late final _Translations$common$es common = _Translations$common$es._(_root);
|
||||
@override late final _Translations$home$es home = _Translations$home$es._(_root);
|
||||
@override late final _Translations$photo$es photo = _Translations$photo$es._(_root);
|
||||
|
|
@ -85,6 +86,17 @@ class _Translations$app$es extends Translations$app$en {
|
|||
@override String get title => 'Tanemaki';
|
||||
}
|
||||
|
||||
// Path: bootstrap
|
||||
class _Translations$bootstrap$es extends Translations$bootstrap$en {
|
||||
_Translations$bootstrap$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get failed => 'Tanemaki no pudo arrancar';
|
||||
@override String get retry => 'Reintentar';
|
||||
}
|
||||
|
||||
// Path: common
|
||||
class _Translations$common$es extends Translations$common$en {
|
||||
_Translations$common$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
|
@ -1059,6 +1071,8 @@ extension on TranslationsEs {
|
|||
dynamic _flatMapFunction(String path) {
|
||||
return switch (path) {
|
||||
'app.title' => 'Tanemaki',
|
||||
'bootstrap.failed' => 'Tanemaki no pudo arrancar',
|
||||
'bootstrap.retry' => 'Reintentar',
|
||||
'common.save' => 'Guardar',
|
||||
'common.cancel' => 'Cancelar',
|
||||
'common.delete' => 'Eliminar',
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class TranslationsPt extends Translations with BaseTranslations<AppLocale, Trans
|
|||
|
||||
// Translations
|
||||
@override late final _Translations$app$pt app = _Translations$app$pt._(_root);
|
||||
@override late final _Translations$bootstrap$pt bootstrap = _Translations$bootstrap$pt._(_root);
|
||||
@override late final _Translations$common$pt common = _Translations$common$pt._(_root);
|
||||
@override late final _Translations$home$pt home = _Translations$home$pt._(_root);
|
||||
@override late final _Translations$photo$pt photo = _Translations$photo$pt._(_root);
|
||||
|
|
@ -85,6 +86,17 @@ class _Translations$app$pt extends Translations$app$en {
|
|||
@override String get title => 'Tanemaki';
|
||||
}
|
||||
|
||||
// Path: bootstrap
|
||||
class _Translations$bootstrap$pt extends Translations$bootstrap$en {
|
||||
_Translations$bootstrap$pt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsPt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get failed => 'O Tanemaki não conseguiu iniciar';
|
||||
@override String get retry => 'Tentar de novo';
|
||||
}
|
||||
|
||||
// Path: common
|
||||
class _Translations$common$pt extends Translations$common$en {
|
||||
_Translations$common$pt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
|
@ -1056,6 +1068,8 @@ extension on TranslationsPt {
|
|||
dynamic _flatMapFunction(String path) {
|
||||
return switch (path) {
|
||||
'app.title' => 'Tanemaki',
|
||||
'bootstrap.failed' => 'O Tanemaki não conseguiu iniciar',
|
||||
'bootstrap.retry' => 'Tentar de novo',
|
||||
'common.save' => 'Guardar',
|
||||
'common.cancel' => 'Cancelar',
|
||||
'common.delete' => 'Eliminar',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue