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
@@ -426,35 +426,175 @@ class HapticFeedbackSwitcher extends ConsumerWidget {
426
426
  }
427
427
  }
428
428
 
429
- class ThemeSwitcher extends StatefulWidget {
429
+ class ThemeSwitcher extends StatelessWidget {
430
430
  const ThemeSwitcher({super.key});
431
431
 
432
+ IconData _iconFor(ThemeMode mode) {
433
+ switch (mode) {
434
+ case ThemeMode.system:
435
+ return KasyIcons.phoneAndroid;
436
+ case ThemeMode.dark:
437
+ return KasyIcons.darkMode;
438
+ case ThemeMode.light:
439
+ return KasyIcons.lightMode;
440
+ }
441
+ }
442
+
432
443
  @override
433
- State<ThemeSwitcher> createState() => _ThemeSwitcherState();
444
+ Widget build(BuildContext context) {
445
+ final tr = context.t.settings;
446
+ final theme = ThemeProvider.of(context);
447
+ final options = <({ThemeMode mode, IconData icon, String label})>[
448
+ (
449
+ mode: ThemeMode.system,
450
+ icon: KasyIcons.phoneAndroid,
451
+ label: tr.theme_option_system,
452
+ ),
453
+ (
454
+ mode: ThemeMode.light,
455
+ icon: KasyIcons.lightMode,
456
+ label: tr.theme_option_light,
457
+ ),
458
+ (
459
+ mode: ThemeMode.dark,
460
+ icon: KasyIcons.darkMode,
461
+ label: tr.theme_option_dark,
462
+ ),
463
+ ];
464
+ return Padding(
465
+ padding: const EdgeInsets.symmetric(vertical: KasySpacing.sm),
466
+ child: Column(
467
+ crossAxisAlignment: CrossAxisAlignment.stretch,
468
+ children: [
469
+ Row(
470
+ children: [
471
+ Icon(
472
+ _iconFor(theme.mode),
473
+ size: 21,
474
+ color: context.colors.onSurface,
475
+ ),
476
+ const SizedBox(width: KasySpacing.sm),
477
+ Expanded(
478
+ child: Text(
479
+ tr.theme_title,
480
+ style: context.textTheme.titleMedium?.copyWith(
481
+ color: context.colors.onSurface,
482
+ ),
483
+ ),
484
+ ),
485
+ ],
486
+ ),
487
+ const SizedBox(height: KasySpacing.sm),
488
+ _ThemeModeSegmented(
489
+ current: theme.mode,
490
+ options: options,
491
+ onChanged: theme.setMode,
492
+ ),
493
+ ],
494
+ ),
495
+ );
496
+ }
434
497
  }
435
498
 
436
- class _ThemeSwitcherState extends State<ThemeSwitcher> {
437
- bool darkMode = false;
499
+ class _ThemeModeSegmented extends StatelessWidget {
500
+ const _ThemeModeSegmented({
501
+ required this.current,
502
+ required this.options,
503
+ required this.onChanged,
504
+ });
505
+
506
+ final ThemeMode current;
507
+ final List<({ThemeMode mode, IconData icon, String label})> options;
508
+ final ValueChanged<ThemeMode> onChanged;
438
509
 
439
510
  @override
440
- void didChangeDependencies() {
441
- super.didChangeDependencies();
442
- WidgetsBinding.instance.addPostFrameCallback((_) {
443
- darkMode = ThemeProvider.of(context).mode == ThemeMode.dark;
444
- setState(() {});
445
- });
511
+ Widget build(BuildContext context) {
512
+ final trackColor = context.colors.onSurface.withValues(alpha: 0.06);
513
+ return Container(
514
+ padding: const EdgeInsets.all(3),
515
+ decoration: BoxDecoration(
516
+ color: trackColor,
517
+ borderRadius: BorderRadius.circular(10),
518
+ ),
519
+ child: Row(
520
+ children: [
521
+ for (final opt in options)
522
+ Expanded(
523
+ child: _ThemeModeSegment(
524
+ icon: opt.icon,
525
+ label: opt.label,
526
+ selected: current == opt.mode,
527
+ onTap: () => onChanged(opt.mode),
528
+ ),
529
+ ),
530
+ ],
531
+ ),
532
+ );
446
533
  }
534
+ }
535
+
536
+ class _ThemeModeSegment extends StatelessWidget {
537
+ const _ThemeModeSegment({
538
+ required this.icon,
539
+ required this.label,
540
+ required this.selected,
541
+ required this.onTap,
542
+ });
543
+
544
+ final IconData icon;
545
+ final String label;
546
+ final bool selected;
547
+ final VoidCallback onTap;
447
548
 
448
549
  @override
449
550
  Widget build(BuildContext context) {
450
- return SettingsSwitchTile(
451
- icon: darkMode ? KasyIcons.darkMode : KasyIcons.lightMode,
452
- title: context.t.settings.theme_title,
453
- value: darkMode,
454
- onChanged: (value) {
455
- setState(() => darkMode = value);
456
- ThemeProvider.of(context).toggle();
457
- },
551
+ final selectedBg = context.colors.surface;
552
+ final selectedFg = context.colors.onSurface;
553
+ final unselectedFg = context.colors.muted;
554
+ return Semantics(
555
+ button: true,
556
+ selected: selected,
557
+ label: label,
558
+ child: GestureDetector(
559
+ onTap: onTap,
560
+ behavior: HitTestBehavior.opaque,
561
+ child: AnimatedContainer(
562
+ duration: const Duration(milliseconds: 160),
563
+ curve: Curves.easeOut,
564
+ padding: const EdgeInsets.symmetric(vertical: 8),
565
+ decoration: BoxDecoration(
566
+ color: selected ? selectedBg : Colors.transparent,
567
+ borderRadius: BorderRadius.circular(8),
568
+ boxShadow: selected
569
+ ? [
570
+ BoxShadow(
571
+ color: Colors.black.withValues(alpha: 0.06),
572
+ blurRadius: 4,
573
+ offset: const Offset(0, 1),
574
+ ),
575
+ ]
576
+ : const [],
577
+ ),
578
+ child: Column(
579
+ mainAxisSize: MainAxisSize.min,
580
+ children: [
581
+ Icon(
582
+ icon,
583
+ size: 18,
584
+ color: selected ? selectedFg : unselectedFg,
585
+ ),
586
+ const SizedBox(height: 2),
587
+ Text(
588
+ label,
589
+ style: context.textTheme.labelSmall?.copyWith(
590
+ color: selected ? selectedFg : unselectedFg,
591
+ fontWeight: selected ? FontWeight.w600 : FontWeight.w500,
592
+ ),
593
+ ),
594
+ ],
595
+ ),
596
+ ),
597
+ ),
458
598
  );
459
599
  }
460
600
  }
@@ -175,7 +175,8 @@
175
175
  "title": "Subscriptions module",
176
176
  "description": "Manage subscriptions with premade paywalls",
177
177
  "action": "Continue",
178
- "skip": "Skip"
178
+ "skip": "Skip",
179
+ "login": "Already have an account? Log in"
179
180
  },
180
181
  "feature_2": {
181
182
  "title": "Authentication module",
@@ -321,7 +322,10 @@
321
322
  "cancel": "Cancel"
322
323
  },
323
324
  "language_title": "Languages",
324
- "theme_title": "Light/Dark mode",
325
+ "theme_title": "Theme",
326
+ "theme_option_system": "System",
327
+ "theme_option_light": "Light",
328
+ "theme_option_dark": "Dark",
325
329
  "haptic_feedback_title": "Haptic feedback",
326
330
  "section_preferences_label": "PREFERENCES",
327
331
  "section_security_label": "SECURITY",
@@ -175,7 +175,8 @@
175
175
  "title": "Módulo de suscripciones",
176
176
  "description": "Gestiona suscripciones con paywalls listos para usar",
177
177
  "action": "Continuar",
178
- "skip": "Omitir"
178
+ "skip": "Omitir",
179
+ "login": "¿Ya tienes cuenta? Iniciar sesión"
179
180
  },
180
181
  "feature_2": {
181
182
  "title": "Módulo de autenticación",
@@ -321,7 +322,10 @@
321
322
  "cancel": "Cancelar"
322
323
  },
323
324
  "language_title": "Idiomas",
324
- "theme_title": "Modo claro/oscuro",
325
+ "theme_title": "Tema",
326
+ "theme_option_system": "Sistema",
327
+ "theme_option_light": "Claro",
328
+ "theme_option_dark": "Oscuro",
325
329
  "haptic_feedback_title": "Feedback háptico",
326
330
  "section_preferences_label": "PREFERENCIAS",
327
331
  "section_security_label": "SEGURIDAD",
@@ -175,7 +175,8 @@
175
175
  "title": "Módulo de assinaturas",
176
176
  "description": "Gerencie assinaturas com paywalls prontos para usar",
177
177
  "action": "Continuar",
178
- "skip": "Pular"
178
+ "skip": "Pular",
179
+ "login": "Já tem conta? Entrar"
179
180
  },
180
181
  "feature_2": {
181
182
  "title": "Módulo de autenticação",
@@ -321,7 +322,10 @@
321
322
  "cancel": "Cancelar"
322
323
  },
323
324
  "language_title": "Idiomas",
324
- "theme_title": "Modo claro/escuro",
325
+ "theme_title": "Tema",
326
+ "theme_option_system": "Sistema",
327
+ "theme_option_light": "Claro",
328
+ "theme_option_dark": "Escuro",
325
329
  "haptic_feedback_title": "Feedback háptico",
326
330
  "section_preferences_label": "PREFERÊNCIAS",
327
331
  "section_security_label": "SEGURANÇA",
@@ -115,28 +115,47 @@ void run(SharedPreferences prefs) => runApp(
115
115
  // mode: ThemeMode.dark,
116
116
  // ),
117
117
  // See ./docs/theme.md for more details
118
- class MyApp extends ConsumerWidget {
118
+ class MyApp extends ConsumerStatefulWidget {
119
119
  final SharedPreferences sharedPreferences;
120
120
 
121
121
  const MyApp({super.key, required this.sharedPreferences});
122
122
 
123
+ @override
124
+ ConsumerState<MyApp> createState() => _MyAppState();
125
+ }
126
+
127
+ class _MyAppState extends ConsumerState<MyApp> {
128
+ late final AppTheme _appTheme;
129
+
130
+ @override
131
+ void initState() {
132
+ super.initState();
133
+ _appTheme = AppTheme.uniform(
134
+ sharedPreferences: widget.sharedPreferences,
135
+ themeFactory: const UniversalThemeFactory(),
136
+ lightColors: KasyColors.light(),
137
+ darkColors: KasyColors.dark(),
138
+ textTheme: KasyTextTheme.build(),
139
+ defaultMode: ThemeMode.system,
140
+ );
141
+ }
142
+
143
+ @override
144
+ void dispose() {
145
+ _appTheme.dispose();
146
+ super.dispose();
147
+ }
148
+
123
149
  // This widget is the root of your application.
124
150
  @override
125
- Widget build(BuildContext context, WidgetRef ref) {
151
+ Widget build(BuildContext context) {
126
152
  ErrorWidget.builder = (FlutterErrorDetails details) {
127
153
  return AppErrorWidget(error: details);
128
154
  };
129
155
  final goRouter = ref.watch(goRouterProvider);
130
156
 
131
157
  return ThemeProvider(
132
- notifier: AppTheme.uniform(
133
- sharedPreferences: sharedPreferences,
134
- themeFactory: const UniversalThemeFactory(),
135
- lightColors: KasyColors.light(),
136
- darkColors: KasyColors.dark(),
137
- textTheme: KasyTextTheme.build(),
138
- defaultMode: ThemeMode.light,
139
- ),
158
+ notifier: _appTheme,
140
159
  child: Builder(
141
160
  builder: (context) {
142
161
  return WebDevicePreview.wrap(
@@ -134,16 +134,15 @@ flutter_native_splash:
134
134
  color: "#FFFFFF"
135
135
  color_dark: "#000000"
136
136
  fullscreen: true
137
- preserve: true
138
137
  ios: true
139
138
  android: true
140
- image: assets/images/splashscreen.png
141
- image_dark: assets/images/splashscreen.png
139
+ image: assets/images/splash_logo_light.png
140
+ image_dark: assets/images/splash_logo_dark.png
142
141
  android_12:
143
142
  color: "#FFFFFF"
144
143
  color_dark: "#000000"
145
- image: assets/images/splashscreen.png
146
- image_dark: assets/images/splashscreen.png
144
+ image: assets/images/splash_logo_light.png
145
+ image_dark: assets/images/splash_logo_dark.png
147
146
 
148
147
  # To add assets to your application, add an assets section, like this:
149
148
  # assets:
@@ -30,7 +30,7 @@ void main() {
30
30
  await tester.runAsync(() async {
31
31
  final userRepository = await init();
32
32
 
33
- final file = await rootBundle.load('assets/images/splashscreen.png');
33
+ final file = await rootBundle.load('assets/images/splash_logo_light.png');
34
34
  final bytes = file.buffer.asUint8List();
35
35
  // if you want to create an XFile from bytes
36
36
  // final xfile = XFile.fromData(bytes);
@@ -29,73 +29,80 @@
29
29
 
30
30
  <title>kasy</title>
31
31
  <link rel="manifest" href="manifest.json">
32
+
33
+
34
+ <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
32
35
  <style id="splash-screen-style">
33
36
  html {
34
- height: 100%;
37
+ height: 100%
35
38
  }
36
39
 
37
40
  body {
38
41
  margin: 0;
39
42
  min-height: 100%;
40
43
  background-color: #FFFFFF;
44
+ background-size: 100% 100%;
41
45
  }
42
46
 
43
- @media (prefers-color-scheme: dark) {
44
- body { background-color: #000000; }
47
+ .center {
48
+ margin: 0;
49
+ position: absolute;
50
+ top: 50%;
51
+ left: 50%;
52
+ -ms-transform: translate(-50%, -50%);
53
+ transform: translate(-50%, -50%);
45
54
  }
46
55
 
47
- #splash {
48
- position: fixed;
49
- inset: 0;
50
- display: flex;
51
- align-items: center;
52
- justify-content: center;
53
- background-color: #FFFFFF;
54
- transition: opacity 0.35s ease;
55
- z-index: 9999;
56
+ .contain {
57
+ display:block;
58
+ width:100%; height:100%;
59
+ object-fit: contain;
56
60
  }
57
61
 
58
- @media (prefers-color-scheme: dark) {
59
- #splash { background-color: #000000; }
62
+ .stretch {
63
+ display:block;
64
+ width:100%; height:100%;
60
65
  }
61
66
 
62
- #splash img {
63
- width: 160px;
64
- height: 160px;
65
- object-fit: contain;
67
+ .cover {
68
+ display:block;
69
+ width:100%; height:100%;
70
+ object-fit: cover;
66
71
  }
67
72
 
68
- .center {
69
- margin: 0;
73
+ .bottom {
70
74
  position: absolute;
71
- top: 50%;
75
+ bottom: 0;
72
76
  left: 50%;
73
- -ms-transform: translate(-50%, -50%);
74
- transform: translate(-50%, -50%);
77
+ -ms-transform: translate(-50%, 0);
78
+ transform: translate(-50%, 0);
75
79
  }
76
80
 
77
- .contain { display:block; width:100%; height:100%; object-fit: contain; }
78
- .stretch { display:block; width:100%; height:100%; }
79
- .cover { display:block; width:100%; height:100%; object-fit: cover; }
81
+ .bottomLeft {
82
+ position: absolute;
83
+ bottom: 0;
84
+ left: 0;
85
+ }
80
86
 
81
- .bottom { position: absolute; bottom: 0; left: 50%; transform: translate(-50%, 0); }
82
- .bottomLeft { position: absolute; bottom: 0; left: 0; }
83
- .bottomRight { position: absolute; bottom: 0; right: 0; }
87
+ .bottomRight {
88
+ position: absolute;
89
+ bottom: 0;
90
+ right: 0;
91
+ }
92
+
93
+ @media (prefers-color-scheme: dark) {
94
+ body {
95
+ background-color: #000000;
96
+ }
97
+ }
84
98
  </style>
85
99
  <script id="splash-screen-script">
86
100
  function removeSplashFromWeb() {
87
- var splash = document.getElementById("splash");
88
- if (splash) {
89
- splash.style.opacity = "0";
90
- setTimeout(function() {
91
- splash.remove();
92
- document.getElementById("splash-branding")?.remove();
93
- document.body.style.background = "transparent";
94
- }, 380);
95
- }
101
+ document.getElementById("splash")?.remove();
102
+ document.getElementById("splash-branding")?.remove();
103
+ document.body.style.background = "transparent";
96
104
  }
97
105
  </script>
98
- <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
99
106
  </head>
100
107
  <body>
101
108
  <picture id="splash">
@@ -103,6 +110,7 @@
103
110
  <source srcset="splash/img/dark-1x.png 1x, splash/img/dark-2x.png 2x, splash/img/dark-3x.png 3x, splash/img/dark-4x.png 4x" media="(prefers-color-scheme: dark)">
104
111
  <img class="center" aria-hidden="true" src="splash/img/light-1x.png" alt="">
105
112
  </picture>
113
+
106
114
  <script src="flutter_bootstrap.js" async=""></script>
107
115
  <script src="./local_notifications.js"></script>
108
116
 
@@ -1,124 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:mixpanel_flutter/mixpanel_flutter.dart';
4
- import 'package:kasy_kit/core/data/models/user.dart';
5
- import 'package:kasy_kit/core/initializer/onstart_service.dart';
6
- import 'package:kasy_kit/environnements.dart';
7
-
8
- final analyticsApiProvider = Provider<AnalyticsApi>(
9
- (ref) => MixpanelAnalyticsApi.instance(),
10
-
11
- );
12
-
13
- abstract class AnalyticsApi implements OnStartService {
14
- /// Log an event to your analytics platform
15
- Future<void> logEvent(String name, Map<String, dynamic> params);
16
-
17
- /// Log a signout event to your analytics platform
18
- Future<void> logSignout();
19
-
20
- /// Identify a user to your analytics platform
21
- Future<void> identify(User user);
22
- }
23
-
24
-
25
- class MixpanelAnalyticsApi implements AnalyticsApi {
26
- final Environment environment;
27
- Mixpanel? mixpanel;
28
- MixpanelAnalyticsApi._({
29
- required this.environment,
30
- });
31
-
32
- static MixpanelAnalyticsApi? _instance;
33
-
34
- factory MixpanelAnalyticsApi.instance() {
35
- return _instance ??= MixpanelAnalyticsApi._(
36
- environment: Environment.fromEnv(),
37
- );
38
- }
39
-
40
- @override
41
- Future<void> init() async {
42
- if (environment.mixpanelToken == null ||
43
- environment.mixpanelToken!.isEmpty) {
44
- return;
45
- }
46
- try {
47
- mixpanel = await Mixpanel.init(
48
- environment.mixpanelToken!,
49
- trackAutomaticEvents: true,
50
- );
51
- } catch (e, s) {
52
- debugPrint('Error initializing Mixpanel: $e\n$s');
53
- }
54
- }
55
-
56
- @override
57
- Future<void> logEvent(String name, Map<String, dynamic> params) async {
58
- mixpanel?.track(name, properties: params);
59
- }
60
-
61
- @override
62
- Future<void> logSignout() async {
63
- mixpanel?.reset();
64
- mixpanel?.track('logout');
65
- }
66
-
67
- @override
68
- Future<void> identify(User user) async {
69
- mixpanel?.track('login');
70
- final userId = user.idOrNull;
71
- if (userId != null) {
72
- mixpanel?.identify(userId);
73
- }
74
- }
75
- }
76
-
77
-
78
-
79
-
80
- class AnalyticsObserver extends RouteObserver<ModalRoute<dynamic>> {
81
- final AnalyticsApi analyticsApi;
82
- final String? prefix;
83
-
84
- AnalyticsObserver({
85
- required this.analyticsApi,
86
- this.prefix,
87
- });
88
-
89
- @override
90
- void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
91
- // debugPrint('didPush $prefix${route.settings.name} ');
92
- if (route.settings.name != null && prefix != null) {
93
- analyticsApi.logEvent('$prefix${route.settings.name}', {});
94
- } else if (route.settings.name != null && prefix == null) {
95
- analyticsApi.logEvent('${route.settings.name}', {});
96
- }
97
- }
98
-
99
- @override
100
- void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
101
- // debugPrint('didReplace ${newRoute?.settings.name}');
102
- if (newRoute?.settings.name != null && prefix != null) {
103
- analyticsApi.logEvent('$prefix${newRoute!.settings.name!}', {});
104
- } else if (newRoute?.settings.name != null && prefix == null) {
105
- analyticsApi.logEvent(newRoute!.settings.name!, {});
106
- }
107
- }
108
-
109
- @override
110
- void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {}
111
-
112
- @override
113
- void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {}
114
-
115
- @override
116
- void didStartUserGesture(
117
- Route<dynamic> route,
118
- Route<dynamic>? previousRoute,
119
- ) {}
120
-
121
- @override
122
- void didStopUserGesture() {}
123
- }
124
-
@@ -1,35 +0,0 @@
1
- ---
2
- name: Encontré un problema.
3
- about: El proyecto no compila o hace crash...
4
- title: ''
5
- labels: ''
6
- assignees: ''
7
-
8
- ---
9
-
10
- ## Pasos para reproducir
11
-
12
- *Describe cómo reproducir el error, proporciona un dartpad o código simple para reproducir*
13
-
14
- ## Resultados esperados
15
-
16
- *Qué debería pasar*
17
-
18
- ## Resultados reales
19
-
20
- *Qué ves*
21
-
22
- ## Sobre tu dispositivo
23
-
24
- | Marca | Modelo | SO |
25
- | ------- | ----------- | --------- |
26
- | *Apple* | *iPhone X* | *13.6.1* |
27
-
28
- ## Tu versión de Flutter
29
-
30
- Ejecuta en la terminal:
31
- ```flutter --version```
32
-
33
- *Pega el resultado aquí*
34
-
35
- </details>