kasy-cli 1.12.1 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/bin/kasy.js +21 -0
  2. package/lib/commands/splash.js +220 -0
  3. package/lib/scaffold/CHANGELOG.json +9 -0
  4. package/lib/scaffold/backends/api/patch/lib/main.dart +29 -10
  5. package/lib/scaffold/backends/supabase/patch/lib/main.dart +29 -10
  6. package/lib/scaffold/features/README.md +15 -139
  7. package/lib/scaffold/shared/generator-utils.js +16 -15
  8. package/lib/utils/i18n.js +78 -0
  9. package/package.json +2 -2
  10. package/templates/firebase/android/app/src/main/res/drawable-hdpi/android12splash.png +0 -0
  11. package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
  12. package/templates/firebase/android/app/src/main/res/drawable-mdpi/android12splash.png +0 -0
  13. package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
  14. package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
  15. package/templates/firebase/android/app/src/main/res/drawable-night/launch_background.xml +9 -0
  16. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/android12splash.png +0 -0
  17. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/splash.png +0 -0
  18. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/android12splash.png +0 -0
  19. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/splash.png +0 -0
  20. package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
  21. package/templates/firebase/android/app/src/main/res/drawable-night-v21/launch_background.xml +9 -0
  22. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/android12splash.png +0 -0
  23. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/splash.png +0 -0
  24. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png +0 -0
  25. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/splash.png +0 -0
  26. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png +0 -0
  27. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/splash.png +0 -0
  28. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/android12splash.png +0 -0
  29. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
  30. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/android12splash.png +0 -0
  31. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
  32. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/android12splash.png +0 -0
  33. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
  34. package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +2 -1
  35. package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -0
  36. package/templates/firebase/assets/images/splash_logo_dark.png +0 -0
  37. package/templates/firebase/assets/images/splash_logo_light.png +0 -0
  38. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json +9 -8
  39. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
  40. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +33 -0
  41. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
  42. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
  43. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
  44. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png +0 -0
  45. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png +0 -0
  46. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png +0 -0
  47. package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +1 -1
  48. package/templates/firebase/lib/core/theme/providers/theme_provider.dart +48 -24
  49. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +4 -0
  50. package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +1 -0
  51. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +13 -0
  52. package/templates/firebase/lib/features/settings/settings_page.dart +158 -18
  53. package/templates/firebase/lib/i18n/en.i18n.json +6 -2
  54. package/templates/firebase/lib/i18n/es.i18n.json +6 -2
  55. package/templates/firebase/lib/i18n/pt.i18n.json +6 -2
  56. package/templates/firebase/lib/main.dart +29 -10
  57. package/templates/firebase/pubspec.yaml +4 -5
  58. package/templates/firebase/test/core/data/repositories/user_repository_test.dart +1 -1
  59. package/templates/firebase/web/index.html +47 -39
  60. package/templates/firebase/web/splash/img/dark-1x.png +0 -0
  61. package/templates/firebase/web/splash/img/dark-2x.png +0 -0
  62. package/templates/firebase/web/splash/img/dark-3x.png +0 -0
  63. package/templates/firebase/web/splash/img/dark-4x.png +0 -0
  64. package/templates/firebase/web/splash/img/light-1x.png +0 -0
  65. package/templates/firebase/web/splash/img/light-2x.png +0 -0
  66. package/templates/firebase/web/splash/img/light-3x.png +0 -0
  67. package/templates/firebase/web/splash/img/light-4x.png +0 -0
  68. package/lib/scaffold/features/analytics/lib/core/data/api/analytics_api.dart +0 -124
  69. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.es.md +0 -35
  70. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.md +0 -35
  71. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.pt.md +0 -35
  72. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.es.md +0 -12
  73. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.md +0 -12
  74. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.pt.md +0 -12
  75. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.es.md +0 -17
  76. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  77. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.pt.md +0 -17
  78. package/lib/scaffold/features/ci/.github/dependabot.yml +0 -16
  79. package/lib/scaffold/features/ci/.github/workflows/app.yml +0 -20
  80. package/lib/scaffold/features/ci/.gitlab/templates/deploy.yaml +0 -14
  81. package/lib/scaffold/features/ci/.gitlab/templates/dropbox.yaml +0 -19
  82. package/lib/scaffold/features/ci/.gitlab/templates/flutter.yaml +0 -163
  83. package/lib/scaffold/features/ci/.gitlab/templates/mailgun.yaml +0 -28
  84. package/lib/scaffold/features/ci/.gitlab-ci.yml +0 -37
  85. package/lib/scaffold/features/ci/codemagic.yaml +0 -157
  86. package/lib/scaffold/features/facebook/lib/core/data/api/tracking_api.dart +0 -111
  87. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_request_entity.dart +0 -27
  88. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_vote_entity.dart +0 -27
  89. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_request_api.dart +0 -50
  90. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_vote_api.dart +0 -79
  91. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feature_requests.dart +0 -48
  92. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feedback_state.dart +0 -42
  93. package/lib/scaffold/features/feedback/lib/features/feedbacks/providers/feedback_page_notifier.dart +0 -147
  94. package/lib/scaffold/features/feedback/lib/features/feedbacks/repositories/feature_request_repository.dart +0 -95
  95. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/component/add_feature_form.dart +0 -199
  96. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/feedback_page.dart +0 -175
  97. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -76
  98. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/feature_card.dart +0 -279
  99. package/lib/scaffold/features/ios-release/.kasy/apple.env.example +0 -8
  100. package/lib/scaffold/features/ios-release/.kasy/codemagic.env.example +0 -7
  101. package/lib/scaffold/features/ios-release/docs/codemagic-release.en.md +0 -50
  102. package/lib/scaffold/features/ios-release/docs/codemagic-release.es.md +0 -50
  103. package/lib/scaffold/features/ios-release/docs/codemagic-release.pt.md +0 -50
  104. package/lib/scaffold/features/ios-release/docs/ios-release.en.md +0 -41
  105. package/lib/scaffold/features/ios-release/docs/ios-release.es.md +0 -41
  106. package/lib/scaffold/features/ios-release/docs/ios-release.pt.md +0 -41
  107. package/lib/scaffold/features/ios-release/scripts/bump-ios-version.js +0 -38
  108. package/lib/scaffold/features/ios-release/scripts/release-ios.sh +0 -137
  109. package/lib/scaffold/features/llm_chat/lib/features/llm_chat/llm_chat_page.dart +0 -301
  110. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/providers/reminder_notifier.dart +0 -81
  111. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/repositories/reminder_preferences.dart +0 -76
  112. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/ui/reminder_page.dart +0 -282
  113. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/entities/user_info_entity.dart +0 -24
  114. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/user_infos_api.dart +0 -71
  115. package/lib/scaffold/features/onboarding/lib/features/onboarding/models/user_info.dart +0 -92
  116. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_model.dart +0 -15
  117. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_provider.dart +0 -78
  118. package/lib/scaffold/features/onboarding/lib/features/onboarding/repositories/user_infos_repository.dart +0 -29
  119. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/animations/page_transitions.dart +0 -30
  120. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_att_setup.dart +0 -66
  121. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_features.dart +0 -72
  122. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_loader.dart +0 -92
  123. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +0 -73
  124. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_questions.dart +0 -89
  125. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/onboarding_page.dart +0 -94
  126. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_background.dart +0 -80
  127. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_feature.dart +0 -139
  128. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +0 -110
  129. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_progress.dart +0 -84
  130. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +0 -173
  131. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_reassurance.dart +0 -45
  132. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +0 -77
  133. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +0 -392
  134. package/lib/scaffold/features/revenuecat/lib/core/data/api/tracking_api.dart +0 -116
  135. package/lib/scaffold/features/revenuecat/lib/core/data/models/subscription.dart +0 -322
  136. package/lib/scaffold/features/revenuecat/lib/core/home_widgets/home_widget_background_task.dart +0 -41
  137. package/lib/scaffold/features/revenuecat/lib/core/states/user_state_notifier.dart +0 -305
  138. package/templates/firebase/assets/images/splashscreen.png +0 -0
package/lib/utils/i18n.js CHANGED
@@ -624,6 +624,32 @@ const MESSAGES = {
624
624
  // docs command
625
625
  'cli.command.docs.description': 'Open the full documentation',
626
626
 
627
+ // splash command
628
+ 'cli.command.splash.description': 'Swap splash screen logos (light/dark) and regenerate native assets',
629
+ 'splash.intro': 'Splash screen',
630
+ 'splash.validating': 'Validating PNG files...',
631
+ 'splash.validated': 'PNG files look good',
632
+ 'splash.copying': 'Copying logos to assets/images/...',
633
+ 'splash.copied': 'Logos copied',
634
+ 'splash.generating': 'Regenerating native splash (Android, iOS, Web)...',
635
+ 'splash.generated': 'Native splash regenerated',
636
+ 'splash.done': 'Done. Run "flutter run" to see the new splash.',
637
+ 'splash.warn.title': 'Warnings',
638
+ 'splash.warn.noAlphaLight': '{path} has no alpha channel. The logo will show with a solid background instead of being transparent.',
639
+ 'splash.warn.noAlphaDark': '{path} has no alpha channel. The logo will show with a solid background instead of being transparent.',
640
+ 'splash.warn.smallLight': 'Light logo is {w}x{h}. Recommended is at least 768x768 to avoid blurry edges.',
641
+ 'splash.warn.smallDark': 'Dark logo is {w}x{h}. Recommended is at least 768x768 to avoid blurry edges.',
642
+ 'splash.summary.title': 'Saved',
643
+ 'splash.summary.light': 'Light mode',
644
+ 'splash.summary.dark': 'Dark mode',
645
+ 'splash.skipGenerate.title': 'Skipped generation',
646
+ 'splash.skipGenerate.hint': 'Run `dart run flutter_native_splash:create` when you are ready.',
647
+ 'splash.error.notKasyProject': 'pubspec.yaml not found. Run this command from inside a Flutter/Kasy project.',
648
+ 'splash.error.bothRequired': '--light and --dark are both required.',
649
+ 'splash.error.fileNotFound': 'File not found: {path}',
650
+ 'splash.error.notPng': 'One of the files is not a valid PNG.',
651
+ 'splash.error.generateFailed': 'flutter_native_splash:create failed. Check the output above.',
652
+
627
653
  // notifications command
628
654
  'cli.command.notifications.description': 'Edit the text of local notifications and reminders',
629
655
  'cli.command.notifications.text.description': 'Set titles and bodies shown in local notifications',
@@ -1421,6 +1447,32 @@ const MESSAGES = {
1421
1447
  // docs command
1422
1448
  'cli.command.docs.description': 'Abre a documentação completa',
1423
1449
 
1450
+ // splash command
1451
+ 'cli.command.splash.description': 'Troca os logos da splash (claro/escuro) e regenera os assets nativos',
1452
+ 'splash.intro': 'Splash screen',
1453
+ 'splash.validating': 'Validando arquivos PNG...',
1454
+ 'splash.validated': 'PNGs estão bons',
1455
+ 'splash.copying': 'Copiando logos para assets/images/...',
1456
+ 'splash.copied': 'Logos copiados',
1457
+ 'splash.generating': 'Regenerando splash nativa (Android, iOS, Web)...',
1458
+ 'splash.generated': 'Splash nativa regenerada',
1459
+ 'splash.done': 'Pronto. Rode "flutter run" para ver a nova splash.',
1460
+ 'splash.warn.title': 'Avisos',
1461
+ 'splash.warn.noAlphaLight': '{path} não tem canal alpha (fundo transparente). O logo vai aparecer com fundo sólido em vez de transparente.',
1462
+ 'splash.warn.noAlphaDark': '{path} não tem canal alpha (fundo transparente). O logo vai aparecer com fundo sólido em vez de transparente.',
1463
+ 'splash.warn.smallLight': 'Logo claro tem {w}x{h}. Recomendado pelo menos 768x768 para evitar bordas borradas.',
1464
+ 'splash.warn.smallDark': 'Logo escuro tem {w}x{h}. Recomendado pelo menos 768x768 para evitar bordas borradas.',
1465
+ 'splash.summary.title': 'Salvo',
1466
+ 'splash.summary.light': 'Modo claro',
1467
+ 'splash.summary.dark': 'Modo escuro',
1468
+ 'splash.skipGenerate.title': 'Geração pulada',
1469
+ 'splash.skipGenerate.hint': 'Rode `dart run flutter_native_splash:create` quando quiser regenerar.',
1470
+ 'splash.error.notKasyProject': 'pubspec.yaml não encontrado. Rode este comando dentro de um projeto Flutter/Kasy.',
1471
+ 'splash.error.bothRequired': '--light e --dark são obrigatórios.',
1472
+ 'splash.error.fileNotFound': 'Arquivo não encontrado: {path}',
1473
+ 'splash.error.notPng': 'Um dos arquivos não é um PNG válido.',
1474
+ 'splash.error.generateFailed': 'flutter_native_splash:create falhou. Veja a saída acima.',
1475
+
1424
1476
  // notifications command
1425
1477
  'cli.command.notifications.description': 'Edita os textos das notificações locais e lembretes',
1426
1478
  'cli.command.notifications.text.description': 'Define títulos e mensagens das notificações locais',
@@ -2218,6 +2270,32 @@ const MESSAGES = {
2218
2270
  // docs command
2219
2271
  'cli.command.docs.description': 'Abre la documentación completa',
2220
2272
 
2273
+ // splash command
2274
+ 'cli.command.splash.description': 'Cambia los logos del splash (claro/oscuro) y regenera los assets nativos',
2275
+ 'splash.intro': 'Splash screen',
2276
+ 'splash.validating': 'Validando archivos PNG...',
2277
+ 'splash.validated': 'Los PNGs están bien',
2278
+ 'splash.copying': 'Copiando logos a assets/images/...',
2279
+ 'splash.copied': 'Logos copiados',
2280
+ 'splash.generating': 'Regenerando splash nativo (Android, iOS, Web)...',
2281
+ 'splash.generated': 'Splash nativo regenerado',
2282
+ 'splash.done': 'Listo. Ejecuta "flutter run" para ver el nuevo splash.',
2283
+ 'splash.warn.title': 'Avisos',
2284
+ 'splash.warn.noAlphaLight': '{path} no tiene canal alpha (fondo transparente). El logo aparecerá con fondo sólido en vez de transparente.',
2285
+ 'splash.warn.noAlphaDark': '{path} no tiene canal alpha (fondo transparente). El logo aparecerá con fondo sólido en vez de transparente.',
2286
+ 'splash.warn.smallLight': 'El logo claro mide {w}x{h}. Lo recomendado es al menos 768x768 para evitar bordes borrosos.',
2287
+ 'splash.warn.smallDark': 'El logo oscuro mide {w}x{h}. Lo recomendado es al menos 768x768 para evitar bordes borrosos.',
2288
+ 'splash.summary.title': 'Guardado',
2289
+ 'splash.summary.light': 'Modo claro',
2290
+ 'splash.summary.dark': 'Modo oscuro',
2291
+ 'splash.skipGenerate.title': 'Generación omitida',
2292
+ 'splash.skipGenerate.hint': 'Ejecuta `dart run flutter_native_splash:create` cuando estés listo.',
2293
+ 'splash.error.notKasyProject': 'No se encontró pubspec.yaml. Ejecuta este comando dentro de un proyecto Flutter/Kasy.',
2294
+ 'splash.error.bothRequired': '--light y --dark son obligatorios.',
2295
+ 'splash.error.fileNotFound': 'Archivo no encontrado: {path}',
2296
+ 'splash.error.notPng': 'Uno de los archivos no es un PNG válido.',
2297
+ 'splash.error.generateFailed': 'flutter_native_splash:create falló. Revisa la salida.',
2298
+
2221
2299
  // notifications command
2222
2300
  'cli.command.notifications.description': 'Edita los textos de las notificaciones locales y recordatorios',
2223
2301
  'cli.command.notifications.text.description': 'Define titulos y mensajes de notificaciones locales',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kasy-cli",
3
- "version": "1.12.1",
3
+ "version": "1.13.0",
4
4
  "description": "CLI for scaffolding production-ready Flutter SaaS apps with Firebase, Supabase, or API REST backends.",
5
5
  "bin": {
6
6
  "kasy": "./bin/kasy.js"
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "scripts": {
34
- "prepack": "node scripts/bundle-template.js",
34
+ "prepack": "node scripts/check-feature-patches.js && node scripts/bundle-template.js",
35
35
  "start": "node ./bin/kasy.js",
36
36
  "setup": "node ./bin/kasy.js setup",
37
37
  "doctor": "node ./bin/kasy.js doctor",
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <item>
4
+ <bitmap android:gravity="fill" android:src="@drawable/background"/>
5
+ </item>
6
+ <item>
7
+ <bitmap android:gravity="center" android:src="@drawable/splash"/>
8
+ </item>
9
+ </layer-list>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <item>
4
+ <bitmap android:gravity="fill" android:src="@drawable/background"/>
5
+ </item>
6
+ <item>
7
+ <bitmap android:gravity="center" android:src="@drawable/splash"/>
8
+ </item>
9
+ </layer-list>
@@ -6,7 +6,8 @@
6
6
  <item name="android:windowFullscreen">true</item>
7
7
  <item name="android:windowDrawsSystemBarBackgrounds">true</item>
8
8
  <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
9
- <item name="android:windowSplashScreenBackground">#FFFFFF</item>
9
+ <item name="android:windowSplashScreenBackground">#000000</item>
10
+ <item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
10
11
  </style>
11
12
  <!-- Theme applied to the Android Window as soon as the process has started.
12
13
  This theme determines the color of the Android Window while your
@@ -7,6 +7,7 @@
7
7
  <item name="android:windowDrawsSystemBarBackgrounds">true</item>
8
8
  <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
9
9
  <item name="android:windowSplashScreenBackground">#FFFFFF</item>
10
+ <item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
10
11
  </style>
11
12
  <!-- Theme applied to the Android Window as soon as the process has started.
12
13
  This theme determines the color of the Android Window while your
@@ -2,16 +2,17 @@
2
2
  "images" : [
3
3
  {
4
4
  "filename" : "background.png",
5
- "idiom" : "universal",
6
- "scale" : "1x"
5
+ "idiom" : "universal"
7
6
  },
8
7
  {
9
- "idiom" : "universal",
10
- "scale" : "2x"
11
- },
12
- {
13
- "idiom" : "universal",
14
- "scale" : "3x"
8
+ "appearances" : [
9
+ {
10
+ "appearance" : "luminosity",
11
+ "value" : "dark"
12
+ }
13
+ ],
14
+ "filename" : "darkbackground.png",
15
+ "idiom" : "universal"
15
16
  }
16
17
  ],
17
18
  "info" : {
@@ -5,15 +5,48 @@
5
5
  "idiom" : "universal",
6
6
  "scale" : "1x"
7
7
  },
8
+ {
9
+ "appearances" : [
10
+ {
11
+ "appearance" : "luminosity",
12
+ "value" : "dark"
13
+ }
14
+ ],
15
+ "filename" : "LaunchImageDark.png",
16
+ "idiom" : "universal",
17
+ "scale" : "1x"
18
+ },
8
19
  {
9
20
  "filename" : "LaunchImage@2x.png",
10
21
  "idiom" : "universal",
11
22
  "scale" : "2x"
12
23
  },
24
+ {
25
+ "appearances" : [
26
+ {
27
+ "appearance" : "luminosity",
28
+ "value" : "dark"
29
+ }
30
+ ],
31
+ "filename" : "LaunchImageDark@2x.png",
32
+ "idiom" : "universal",
33
+ "scale" : "2x"
34
+ },
13
35
  {
14
36
  "filename" : "LaunchImage@3x.png",
15
37
  "idiom" : "universal",
16
38
  "scale" : "3x"
39
+ },
40
+ {
41
+ "appearances" : [
42
+ {
43
+ "appearance" : "luminosity",
44
+ "value" : "dark"
45
+ }
46
+ ],
47
+ "filename" : "LaunchImageDark@3x.png",
48
+ "idiom" : "universal",
49
+ "scale" : "3x"
17
50
  }
18
51
  ],
19
52
  "info" : {
@@ -38,7 +38,7 @@
38
38
  </scene>
39
39
  </scenes>
40
40
  <resources>
41
- <image name="LaunchImage" width="2732" height="2732"/>
41
+ <image name="LaunchImage" width="512" height="512"/>
42
42
  <image name="LaunchBackground" width="1" height="1"/>
43
43
  </resources>
44
44
  </document>
@@ -17,13 +17,8 @@ class ThemeProvider extends InheritedNotifier<AppTheme> {
17
17
 
18
18
  @override
19
19
  bool updateShouldNotify(covariant InheritedNotifier<AppTheme> oldWidget) {
20
- final isModeChanged = oldWidget.notifier!.mode != notifier!.mode;
21
- if (isModeChanged) {
22
- // keeep the same theme when switching between light and dark mode while hot reloading
23
- notifier!.mode = oldWidget.notifier!.mode;
24
- notifier!.setSystemBarColor();
25
- }
26
- return false;
20
+ return oldWidget.notifier != notifier ||
21
+ oldWidget.notifier?.mode != notifier?.mode;
27
22
  }
28
23
 
29
24
  static AppTheme of(BuildContext context) =>
@@ -37,7 +32,7 @@ class ThemeProvider extends InheritedNotifier<AppTheme> {
37
32
  ///
38
33
  /// Defining a theme for light and dark should only change the colors
39
34
  /// not redefining everything. (see ./docs/theme.md)
40
- class AppTheme with ChangeNotifier {
35
+ class AppTheme with ChangeNotifier, WidgetsBindingObserver {
41
36
  final KasyTheme? lightTheme;
42
37
  final KasyTheme? darkTheme;
43
38
  final SharedPreferences sharedPreferences;
@@ -50,6 +45,7 @@ class AppTheme with ChangeNotifier {
50
45
  this.darkTheme,
51
46
  }) {
52
47
  mode = _loadFromPrefs();
48
+ WidgetsBinding.instance.addObserver(this);
53
49
  setSystemBarColor();
54
50
  }
55
51
 
@@ -135,25 +131,55 @@ class AppTheme with ChangeNotifier {
135
131
  );
136
132
  }
137
133
 
138
- /// automatically toggle between light and dark mode
139
- /// call this using AppTheme.of(context).toggle()
140
- void toggle() {
141
- mode = mode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
134
+ @override
135
+ void didChangePlatformBrightness() {
136
+ super.didChangePlatformBrightness();
137
+ if (mode == ThemeMode.system) {
138
+ setSystemBarColor();
139
+ notifyListeners();
140
+ }
141
+ }
142
+
143
+ @override
144
+ void dispose() {
145
+ WidgetsBinding.instance.removeObserver(this);
146
+ super.dispose();
147
+ }
148
+
149
+ /// Resolves [mode] to either light or dark by reading the system brightness
150
+ /// when [mode] is [ThemeMode.system].
151
+ ThemeMode get effectiveMode {
152
+ if (mode != ThemeMode.system) return mode;
153
+ final brightness =
154
+ WidgetsBinding.instance.platformDispatcher.platformBrightness;
155
+ return brightness == Brightness.dark ? ThemeMode.dark : ThemeMode.light;
156
+ }
157
+
158
+ /// Set the theme mode and persist the preference.
159
+ void setMode(ThemeMode newMode) {
160
+ if (mode == newMode) return;
161
+ mode = newMode;
142
162
  _saveInPrefs(mode);
143
- notifyListeners();
144
163
  setSystemBarColor();
164
+ notifyListeners();
165
+ }
166
+
167
+ /// Toggle between light and dark based on the effective (visible) mode.
168
+ /// If the user is in system mode, this picks the opposite of the
169
+ /// currently displayed brightness and switches out of system mode.
170
+ void toggle() {
171
+ final next =
172
+ effectiveMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
173
+ setMode(next);
145
174
  }
146
175
 
147
176
  void setSystemBarColor() {
177
+ final isLight = effectiveMode == ThemeMode.light;
148
178
  SystemChrome.setSystemUIOverlayStyle(
149
179
  SystemUiOverlayStyle(
150
180
  statusBarColor: Colors.transparent,
151
- statusBarBrightness:
152
- mode == ThemeMode.light ? Brightness.light : Brightness.dark,
153
- statusBarIconBrightness:
154
- mode == ThemeMode.light ? Brightness.dark : Brightness.light,
155
- // statusBarColor: Colors.black, // color for android
156
- // statusBarBrightness: Brightness.light, // for ios Dark = white status
181
+ statusBarBrightness: isLight ? Brightness.light : Brightness.dark,
182
+ statusBarIconBrightness: isLight ? Brightness.dark : Brightness.light,
157
183
  ),
158
184
  );
159
185
  }
@@ -189,11 +215,7 @@ class AppTheme with ChangeNotifier {
189
215
  ThemeData get darkThemeData => darkTheme!.data.materialTheme;
190
216
 
191
217
  KasyTheme get current {
192
- if (mode == ThemeMode.light) {
193
- return lightTheme!;
194
- } else {
195
- return darkTheme!;
196
- }
218
+ return effectiveMode == ThemeMode.dark ? darkTheme! : lightTheme!;
197
219
  }
198
220
 
199
221
  ThemeMode _loadFromPrefs() {
@@ -202,6 +224,8 @@ class AppTheme with ChangeNotifier {
202
224
  return ThemeMode.dark;
203
225
  } else if (themeMode == ThemeMode.light.name) {
204
226
  return ThemeMode.light;
227
+ } else if (themeMode == ThemeMode.system.name) {
228
+ return ThemeMode.system;
205
229
  }
206
230
  return mode;
207
231
  }
@@ -5,11 +5,13 @@ import 'package:kasy_kit/i18n/translations.g.dart';
5
5
  class OnboardingFeatureOne extends StatelessWidget {
6
6
  final String nextRoute;
7
7
  final VoidCallback? onSkip;
8
+ final VoidCallback? onLogin;
8
9
 
9
10
  const OnboardingFeatureOne({
10
11
  super.key,
11
12
  required this.nextRoute,
12
13
  this.onSkip,
14
+ this.onLogin,
13
15
  });
14
16
 
15
17
  @override
@@ -25,6 +27,8 @@ class OnboardingFeatureOne extends StatelessWidget {
25
27
  progress: 0.1,
26
28
  onSkip: onSkip,
27
29
  skipLabel: translations.skip,
30
+ onSecondary: onLogin,
31
+ secondaryLabel: onLogin != null ? translations.login : null,
28
32
  );
29
33
  }
30
34
  }
@@ -33,6 +33,7 @@ class OnboardingPage extends ConsumerWidget {
33
33
  onSkip: () => Navigator.of(context).pushReplacementNamed(
34
34
  'skip_loader',
35
35
  ),
36
+ onLogin: () => ref.read(goRouterProvider).go('/signin'),
36
37
  ),
37
38
  settings: settings,
38
39
  ),
@@ -20,6 +20,8 @@ class OnboardingStep extends StatelessWidget {
20
20
  final bool withBg;
21
21
  final VoidCallback? onSkip;
22
22
  final String? skipLabel;
23
+ final VoidCallback? onSecondary;
24
+ final String? secondaryLabel;
23
25
 
24
26
  const OnboardingStep({
25
27
  super.key,
@@ -35,6 +37,8 @@ class OnboardingStep extends StatelessWidget {
35
37
  this.image,
36
38
  this.onSkip,
37
39
  this.skipLabel,
40
+ this.onSecondary,
41
+ this.secondaryLabel,
38
42
  });
39
43
 
40
44
  @override
@@ -128,6 +132,15 @@ class OnboardingStep extends StatelessWidget {
128
132
  }
129
133
  },
130
134
  ),
135
+ if (onSecondary != null && secondaryLabel != null) ...[
136
+ const SizedBox(height: KasySpacing.xs),
137
+ KasyButton(
138
+ label: secondaryLabel!,
139
+ variant: KasyButtonVariant.link,
140
+ expand: true,
141
+ onPressed: onSecondary,
142
+ ),
143
+ ],
131
144
  ],
132
145
  );
133
146