kasy-cli 1.12.1 → 1.14.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 (249) hide show
  1. package/bin/kasy.js +143 -7
  2. package/lib/commands/add.js +2 -2
  3. package/lib/commands/codemagic.js +11 -4
  4. package/lib/commands/deploy.js +3 -3
  5. package/lib/commands/favicon.js +115 -0
  6. package/lib/commands/icon.js +143 -0
  7. package/lib/commands/ios.js +20 -5
  8. package/lib/commands/new.js +8 -20
  9. package/lib/commands/remove.js +1 -1
  10. package/lib/commands/reset.js +287 -0
  11. package/lib/commands/run.js +24 -17
  12. package/lib/commands/splash.js +219 -0
  13. package/lib/commands/update.js +1 -1
  14. package/lib/scaffold/CHANGELOG.json +9 -0
  15. package/lib/scaffold/backends/api/patch/README.md +1 -1
  16. package/lib/scaffold/backends/api/patch/android/app/src/main/AndroidManifest.xml +1 -1
  17. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/device_api.dart +53 -0
  18. package/lib/scaffold/backends/api/patch/lib/main.dart +29 -10
  19. package/lib/scaffold/backends/api/pubspec.yaml.tpl +11 -1
  20. package/lib/scaffold/backends/firebase/tokens.js +2 -2
  21. package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/index.ts +8 -2
  22. package/lib/scaffold/backends/supabase/migrations/20240101000011_dedupe_device_tokens.sql +34 -0
  23. package/lib/scaffold/backends/supabase/patch/README.md +1 -1
  24. package/lib/scaffold/backends/supabase/patch/android/app/src/main/AndroidManifest.xml +1 -1
  25. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/device_api.dart +43 -0
  26. package/lib/scaffold/backends/supabase/patch/lib/main.dart +29 -10
  27. package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +11 -1
  28. package/lib/scaffold/features/README.md +15 -139
  29. package/lib/scaffold/shared/generator-utils.js +16 -15
  30. package/lib/utils/apple-release.js +85 -16
  31. package/lib/utils/checks.js +4 -105
  32. package/lib/utils/flutter-run.js +173 -0
  33. package/lib/utils/i18n.js +413 -0
  34. package/lib/utils/mobile-identity.js +35 -0
  35. package/lib/utils/ui.js +114 -0
  36. package/package.json +2 -3
  37. package/templates/firebase/README.en.md +1 -1
  38. package/templates/firebase/README.es.md +1 -1
  39. package/templates/firebase/README.md +1 -1
  40. package/templates/firebase/android/app/build.gradle.kts +10 -1
  41. package/templates/firebase/android/app/src/main/AndroidManifest.xml +1 -1
  42. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MainActivity.kt +25 -1
  43. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MyWidget.kt +160 -11
  44. package/templates/firebase/android/app/src/main/res/drawable/widget_add_button.xml +15 -0
  45. package/templates/firebase/android/app/src/main/res/drawable/widget_gradient_bg.xml +9 -0
  46. package/templates/firebase/android/app/src/main/res/drawable/widget_gradient_inner.xml +12 -0
  47. package/templates/firebase/android/app/src/main/res/drawable/widget_plan_pill_bg.xml +5 -0
  48. package/templates/firebase/android/app/src/main/res/drawable/widget_preview_image.xml +17 -0
  49. package/templates/firebase/android/app/src/main/res/drawable/widget_pro_pill_bg.xml +5 -0
  50. package/templates/firebase/android/app/src/main/res/drawable-hdpi/android12splash.png +0 -0
  51. package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
  52. package/templates/firebase/android/app/src/main/res/drawable-mdpi/android12splash.png +0 -0
  53. package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
  54. package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
  55. package/templates/firebase/android/app/src/main/res/drawable-night/launch_background.xml +9 -0
  56. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/android12splash.png +0 -0
  57. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/splash.png +0 -0
  58. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/android12splash.png +0 -0
  59. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/splash.png +0 -0
  60. package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
  61. package/templates/firebase/android/app/src/main/res/drawable-night-v21/launch_background.xml +9 -0
  62. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/android12splash.png +0 -0
  63. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/splash.png +0 -0
  64. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png +0 -0
  65. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/splash.png +0 -0
  66. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png +0 -0
  67. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/splash.png +0 -0
  68. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/android12splash.png +0 -0
  69. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
  70. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/android12splash.png +0 -0
  71. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
  72. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/android12splash.png +0 -0
  73. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
  74. package/templates/firebase/android/app/src/main/res/layout/widget_loading.xml +8 -0
  75. package/templates/firebase/android/app/src/main/res/layout/widget_preview.xml +46 -0
  76. package/templates/firebase/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  77. package/templates/firebase/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  78. package/templates/firebase/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  79. package/templates/firebase/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  80. package/templates/firebase/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  81. package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +2 -1
  82. package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -0
  83. package/templates/firebase/android/app/src/main/res/xml/mywidget_info.xml +9 -3
  84. package/templates/firebase/assets/images/favicon.png +0 -0
  85. package/templates/firebase/assets/images/icon.png +0 -0
  86. package/templates/firebase/assets/images/splash_logo_dark.png +0 -0
  87. package/templates/firebase/assets/images/splash_logo_light.png +0 -0
  88. package/templates/firebase/firestore.indexes.json +10 -0
  89. package/templates/firebase/functions/src/core/data/entities/user_device_entity.ts +3 -0
  90. package/templates/firebase/functions/src/core/data/repositories/user_device_repository.ts +17 -1
  91. package/templates/firebase/functions/src/index.ts +1 -0
  92. package/templates/firebase/functions/src/notifications/device_triggers.ts +58 -0
  93. package/templates/firebase/ios/HomeWidgetExtension/MyWidget.swift +116 -33
  94. package/templates/firebase/ios/Runner/AppDelegate.swift +17 -1
  95. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png +0 -0
  96. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png +0 -0
  97. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png +0 -0
  98. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png +0 -0
  99. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png +0 -0
  100. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png +0 -0
  101. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png +0 -0
  102. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png +0 -0
  103. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png +0 -0
  104. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png +0 -0
  105. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png +0 -0
  106. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png +0 -0
  107. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png +0 -0
  108. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png +0 -0
  109. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png +0 -0
  110. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png +0 -0
  111. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png +0 -0
  112. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png +0 -0
  113. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png +0 -0
  114. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png +0 -0
  115. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png +0 -0
  116. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json +9 -8
  117. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
  118. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +33 -0
  119. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
  120. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
  121. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
  122. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png +0 -0
  123. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png +0 -0
  124. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png +0 -0
  125. package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +1 -1
  126. package/templates/firebase/ios/Runner/Info.plist +2 -2
  127. package/templates/firebase/ios/Runner/es.lproj/InfoPlist.strings +1 -1
  128. package/templates/firebase/ios/Runner/pt-BR.lproj/InfoPlist.strings +1 -1
  129. package/templates/firebase/ios/Runner/pt.lproj/InfoPlist.strings +1 -1
  130. package/templates/firebase/lib/components/kasy_button.dart +8 -0
  131. package/templates/firebase/lib/core/bottom_menu/kasy_bottom_bar_factory.dart +18 -0
  132. package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +67 -19
  133. package/templates/firebase/lib/core/home_widgets/home_widget_service.dart +22 -8
  134. package/templates/firebase/lib/core/shared_preferences/shared_preferences.dart +16 -4
  135. package/templates/firebase/lib/core/states/components/maybeshow_component.dart +4 -8
  136. package/templates/firebase/lib/core/states/user_state_notifier.dart +13 -1
  137. package/templates/firebase/lib/core/theme/providers/theme_provider.dart +48 -24
  138. package/templates/firebase/lib/features/home/home_page.dart +0 -6
  139. package/templates/firebase/lib/features/notifications/api/device_api.dart +57 -0
  140. package/templates/firebase/lib/features/notifications/providers/models/notification.dart +11 -1
  141. package/templates/firebase/lib/features/notifications/repositories/device_repository.dart +9 -0
  142. package/templates/firebase/lib/features/notifications/repositories/notifications_repository.dart +1 -4
  143. package/templates/firebase/lib/features/notifications/shared/att_permission.dart +28 -8
  144. package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +16 -1
  145. package/templates/firebase/lib/features/notifications/ui/widgets/empty_notifications.dart +44 -11
  146. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +4 -0
  147. package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +1 -0
  148. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +13 -0
  149. package/templates/firebase/lib/features/settings/settings_page.dart +158 -18
  150. package/templates/firebase/lib/features/settings/ui/components/admin/admin_bottom_sheet.dart +31 -29
  151. package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +21 -5
  152. package/templates/firebase/lib/i18n/en.i18n.json +10 -3
  153. package/templates/firebase/lib/i18n/es.i18n.json +10 -3
  154. package/templates/firebase/lib/i18n/pt.i18n.json +10 -3
  155. package/templates/firebase/lib/main.dart +29 -10
  156. package/templates/firebase/pubspec.yaml +10 -6
  157. package/templates/firebase/test/core/data/repositories/user_repository_test.dart +1 -1
  158. package/templates/firebase/test/features/notifications/data/device_api_fake.dart +9 -0
  159. package/templates/firebase/web/favicon.png +0 -0
  160. package/templates/firebase/web/icons/Icon-192.png +0 -0
  161. package/templates/firebase/web/icons/Icon-512.png +0 -0
  162. package/templates/firebase/web/icons/Icon-maskable-192.png +0 -0
  163. package/templates/firebase/web/icons/Icon-maskable-512.png +0 -0
  164. package/templates/firebase/web/index.html +50 -39
  165. package/templates/firebase/web/manifest.json +3 -3
  166. package/templates/firebase/web/splash/img/dark-1x.png +0 -0
  167. package/templates/firebase/web/splash/img/dark-2x.png +0 -0
  168. package/templates/firebase/web/splash/img/dark-3x.png +0 -0
  169. package/templates/firebase/web/splash/img/dark-4x.png +0 -0
  170. package/templates/firebase/web/splash/img/light-1x.png +0 -0
  171. package/templates/firebase/web/splash/img/light-2x.png +0 -0
  172. package/templates/firebase/web/splash/img/light-3x.png +0 -0
  173. package/templates/firebase/web/splash/img/light-4x.png +0 -0
  174. package/lib/scaffold/features/analytics/lib/core/data/api/analytics_api.dart +0 -124
  175. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.es.md +0 -35
  176. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.md +0 -35
  177. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.pt.md +0 -35
  178. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.es.md +0 -12
  179. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.md +0 -12
  180. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.pt.md +0 -12
  181. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.es.md +0 -17
  182. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  183. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.pt.md +0 -17
  184. package/lib/scaffold/features/ci/.github/dependabot.yml +0 -16
  185. package/lib/scaffold/features/ci/.github/workflows/app.yml +0 -20
  186. package/lib/scaffold/features/ci/.gitlab/templates/deploy.yaml +0 -14
  187. package/lib/scaffold/features/ci/.gitlab/templates/dropbox.yaml +0 -19
  188. package/lib/scaffold/features/ci/.gitlab/templates/flutter.yaml +0 -163
  189. package/lib/scaffold/features/ci/.gitlab/templates/mailgun.yaml +0 -28
  190. package/lib/scaffold/features/ci/.gitlab-ci.yml +0 -37
  191. package/lib/scaffold/features/ci/codemagic.yaml +0 -157
  192. package/lib/scaffold/features/facebook/lib/core/data/api/tracking_api.dart +0 -111
  193. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_request_entity.dart +0 -27
  194. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_vote_entity.dart +0 -27
  195. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_request_api.dart +0 -50
  196. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_vote_api.dart +0 -79
  197. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feature_requests.dart +0 -48
  198. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feedback_state.dart +0 -42
  199. package/lib/scaffold/features/feedback/lib/features/feedbacks/providers/feedback_page_notifier.dart +0 -147
  200. package/lib/scaffold/features/feedback/lib/features/feedbacks/repositories/feature_request_repository.dart +0 -95
  201. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/component/add_feature_form.dart +0 -199
  202. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/feedback_page.dart +0 -175
  203. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -76
  204. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/feature_card.dart +0 -279
  205. package/lib/scaffold/features/ios-release/.kasy/apple.env.example +0 -8
  206. package/lib/scaffold/features/ios-release/.kasy/codemagic.env.example +0 -7
  207. package/lib/scaffold/features/ios-release/docs/codemagic-release.en.md +0 -50
  208. package/lib/scaffold/features/ios-release/docs/codemagic-release.es.md +0 -50
  209. package/lib/scaffold/features/ios-release/docs/codemagic-release.pt.md +0 -50
  210. package/lib/scaffold/features/ios-release/docs/ios-release.en.md +0 -41
  211. package/lib/scaffold/features/ios-release/docs/ios-release.es.md +0 -41
  212. package/lib/scaffold/features/ios-release/docs/ios-release.pt.md +0 -41
  213. package/lib/scaffold/features/ios-release/scripts/bump-ios-version.js +0 -38
  214. package/lib/scaffold/features/ios-release/scripts/release-ios.sh +0 -137
  215. package/lib/scaffold/features/llm_chat/lib/features/llm_chat/llm_chat_page.dart +0 -301
  216. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/providers/reminder_notifier.dart +0 -81
  217. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/repositories/reminder_preferences.dart +0 -76
  218. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/ui/reminder_page.dart +0 -282
  219. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/entities/user_info_entity.dart +0 -24
  220. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/user_infos_api.dart +0 -71
  221. package/lib/scaffold/features/onboarding/lib/features/onboarding/models/user_info.dart +0 -92
  222. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_model.dart +0 -15
  223. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_provider.dart +0 -78
  224. package/lib/scaffold/features/onboarding/lib/features/onboarding/repositories/user_infos_repository.dart +0 -29
  225. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/animations/page_transitions.dart +0 -30
  226. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_att_setup.dart +0 -66
  227. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_features.dart +0 -72
  228. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_loader.dart +0 -92
  229. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +0 -73
  230. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_questions.dart +0 -89
  231. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/onboarding_page.dart +0 -94
  232. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_background.dart +0 -80
  233. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_feature.dart +0 -139
  234. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +0 -110
  235. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_progress.dart +0 -84
  236. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +0 -173
  237. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_reassurance.dart +0 -45
  238. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +0 -77
  239. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +0 -392
  240. package/lib/scaffold/features/revenuecat/lib/core/data/api/tracking_api.dart +0 -116
  241. package/lib/scaffold/features/revenuecat/lib/core/data/models/subscription.dart +0 -322
  242. package/lib/scaffold/features/revenuecat/lib/core/home_widgets/home_widget_background_task.dart +0 -41
  243. package/lib/scaffold/features/revenuecat/lib/core/states/user_state_notifier.dart +0 -305
  244. package/templates/firebase/assets/images/app_icon.png +0 -0
  245. package/templates/firebase/assets/images/onboarding/img1.jpg +0 -0
  246. package/templates/firebase/assets/images/onboarding/onboarding.png +0 -0
  247. package/templates/firebase/assets/images/splashscreen.png +0 -0
  248. package/templates/firebase/lib/core/states/components/maybe_ask_biometric_setup.dart +0 -88
  249. package/templates/firebase/lib/features/notifications/shared/notification_permission_bottom_sheet.dart +0 -144
@@ -1,139 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_animate/flutter_animate.dart';
3
- import 'package:kasy_kit/components/components.dart';
4
- import 'package:kasy_kit/core/theme/theme.dart';
5
- import 'package:kasy_kit/core/widgets/responsive_layout.dart';
6
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_background.dart';
7
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart';
8
-
9
- /// A generic onboarding step widget with text and image.
10
- class OnboardingStep extends StatelessWidget {
11
- final String? title;
12
- final Widget? titleWidget;
13
- final String imgPath;
14
- final String description;
15
- final String btnText;
16
- final String nextRoute;
17
- final VoidCallback? onNext;
18
- final double progress;
19
- final Widget? image;
20
- final bool withBg;
21
-
22
- const OnboardingStep({
23
- super.key,
24
- this.title,
25
- this.titleWidget,
26
- required this.imgPath,
27
- required this.description,
28
- required this.btnText,
29
- required this.nextRoute,
30
- required this.progress,
31
- this.onNext,
32
- this.withBg = false,
33
- this.image,
34
- });
35
-
36
- @override
37
- Widget build(BuildContext context) {
38
- final Widget? illustration = image ??
39
- (imgPath.isNotEmpty
40
- ? Animate(
41
- effects: const [
42
- FadeEffect(
43
- delay: Duration(milliseconds: 100),
44
- duration: Duration(milliseconds: 200),
45
- curve: Curves.easeIn,
46
- ),
47
- MoveEffect(
48
- delay: Duration(milliseconds: 100),
49
- duration: Duration(milliseconds: 450),
50
- curve: Curves.easeOut,
51
- begin: Offset(0, 50),
52
- end: Offset.zero,
53
- ),
54
- ],
55
- child: Image.asset(imgPath, fit: BoxFit.contain),
56
- )
57
- : null);
58
-
59
- final scaffold = OnboardingIllustrationScaffold(
60
- progress: progress,
61
- title: title ?? '',
62
- titleWidget: title != null
63
- ? Animate(
64
- effects: const [
65
- FadeEffect(
66
- delay: Duration(milliseconds: 200),
67
- duration: Duration(milliseconds: 200),
68
- curve: Curves.easeIn,
69
- ),
70
- MoveEffect(
71
- delay: Duration(milliseconds: 200),
72
- duration: Duration(milliseconds: 450),
73
- curve: Curves.easeOut,
74
- begin: Offset(0, 50),
75
- end: Offset.zero,
76
- ),
77
- ],
78
- child: Text(
79
- title!,
80
- textAlign: TextAlign.center,
81
- style: context.textTheme.headlineMedium?.copyWith(
82
- color: context.colors.onBackground,
83
- fontWeight: FontWeight.w600,
84
- ),
85
- ),
86
- )
87
- : titleWidget,
88
- description: description,
89
- descriptionWidget: Animate(
90
- effects: const [
91
- FadeEffect(
92
- delay: Duration(milliseconds: 300),
93
- duration: Duration(milliseconds: 200),
94
- curve: Curves.easeIn,
95
- ),
96
- MoveEffect(
97
- delay: Duration(milliseconds: 300),
98
- duration: Duration(milliseconds: 450),
99
- curve: Curves.easeOut,
100
- begin: Offset(0, 50),
101
- end: Offset.zero,
102
- ),
103
- ],
104
- child: Text(
105
- description,
106
- textAlign: TextAlign.center,
107
- style: context.textTheme.bodyLarge?.copyWith(
108
- color: context.colors.onBackground.withValues(alpha: 0.6),
109
- ),
110
- ),
111
- ),
112
- image: illustration,
113
- footerActions: [
114
- KasyButton(
115
- label: btnText,
116
- expand: true,
117
- onPressed: () {
118
- if (onNext != null) {
119
- onNext!.call();
120
- } else {
121
- Navigator.of(context).pushReplacementNamed(nextRoute);
122
- }
123
- },
124
- ),
125
- ],
126
- );
127
-
128
- final content = ResponsiveLayout(
129
- small: withBg
130
- ? OnboardingBackground(child: scaffold)
131
- : ColoredBox(
132
- color: context.colors.background,
133
- child: scaffold,
134
- ),
135
- );
136
-
137
- return content;
138
- }
139
- }
@@ -1,110 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:kasy_kit/core/theme/theme.dart';
3
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_progress.dart';
4
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_sticky_footer.dart';
5
-
6
- /// Layout compartilhado para passos de onboarding com ilustração e ações no rodapé.
7
- ///
8
- /// Evita buracos grandes de [Expanded] + [Spacer] com imagens [BoxFit.contain].
9
- class OnboardingIllustrationScaffold extends StatelessWidget {
10
- const OnboardingIllustrationScaffold({
11
- super.key,
12
- required this.progress,
13
- required this.title,
14
- required this.description,
15
- required this.footerActions,
16
- this.imageAsset,
17
- this.image,
18
- this.imageMaxHeight = 280,
19
- this.titleWidget,
20
- this.descriptionWidget,
21
- this.footerAnimationDelayMs = 400,
22
- this.animateFooter = true,
23
- });
24
-
25
- final double progress;
26
- final String title;
27
- final String description;
28
- final String? imageAsset;
29
- final Widget? image;
30
- final List<Widget> footerActions;
31
- final double imageMaxHeight;
32
- final Widget? titleWidget;
33
- final Widget? descriptionWidget;
34
- final int footerAnimationDelayMs;
35
- final bool animateFooter;
36
-
37
- @override
38
- Widget build(BuildContext context) {
39
- final Widget? illustration = image ??
40
- (imageAsset != null && imageAsset!.isNotEmpty
41
- ? Image.asset(imageAsset!, fit: BoxFit.contain)
42
- : null);
43
-
44
- return Column(
45
- crossAxisAlignment: CrossAxisAlignment.stretch,
46
- children: [
47
- Expanded(
48
- child: SafeArea(
49
- bottom: false,
50
- child: Column(
51
- crossAxisAlignment: CrossAxisAlignment.stretch,
52
- children: [
53
- OnboardingProgress(value: progress),
54
- Expanded(
55
- child: SingleChildScrollView(
56
- padding: const EdgeInsets.fromLTRB(
57
- KasySpacing.xl,
58
- KasySpacing.lg,
59
- KasySpacing.xl,
60
- KasySpacing.md,
61
- ),
62
- child: Column(
63
- children: [
64
- titleWidget ??
65
- Text(
66
- title,
67
- textAlign: TextAlign.center,
68
- style:
69
- context.textTheme.headlineMedium?.copyWith(
70
- color: context.colors.onBackground,
71
- fontWeight: FontWeight.w600,
72
- ),
73
- ),
74
- const SizedBox(height: KasySpacing.smd),
75
- descriptionWidget ??
76
- Text(
77
- description,
78
- textAlign: TextAlign.center,
79
- style: context.textTheme.bodyLarge?.copyWith(
80
- color: context.colors.onBackground.withValues(
81
- alpha: 0.6,
82
- ),
83
- ),
84
- ),
85
- if (illustration != null) ...[
86
- const SizedBox(height: KasySpacing.xl),
87
- ConstrainedBox(
88
- constraints:
89
- BoxConstraints(maxHeight: imageMaxHeight),
90
- child: illustration,
91
- ),
92
- ],
93
- ],
94
- ),
95
- ),
96
- ),
97
- ],
98
- ),
99
- ),
100
- ),
101
- OnboardingStickyFooter(
102
- animate: animateFooter,
103
- animationDelayMs: footerAnimationDelayMs,
104
- horizontalPadding: KasySpacing.xl,
105
- children: footerActions,
106
- ),
107
- ],
108
- );
109
- }
110
- }
@@ -1,84 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:kasy_kit/core/theme/theme.dart';
3
-
4
- class OnboardingProgress extends StatefulWidget {
5
- final double value;
6
-
7
- const OnboardingProgress({super.key, required this.value});
8
-
9
- @override
10
- State<OnboardingProgress> createState() => _OnboardingProgressState();
11
- }
12
-
13
- class _OnboardingProgressState extends State<OnboardingProgress>
14
- with SingleTickerProviderStateMixin {
15
- late final AnimationController animationController;
16
-
17
- late Animation<double> _progressAnimation;
18
-
19
- @override
20
- void initState() {
21
- super.initState();
22
-
23
- animationController = AnimationController(
24
- vsync: this,
25
- duration: const Duration(milliseconds: 1500),
26
- );
27
- _setProgressValueAndStart();
28
- }
29
-
30
- @override
31
- void didUpdateWidget(OnboardingProgress oldWidget) {
32
- super.didUpdateWidget(oldWidget);
33
- if (oldWidget.value != widget.value) {
34
- _setProgressValueAndStart();
35
- }
36
- }
37
-
38
- @override
39
- void dispose() {
40
- animationController.dispose();
41
- super.dispose();
42
- }
43
-
44
- void _setProgressValueAndStart() {
45
- var start = 0.0;
46
- if (widget.value > 0) {
47
- start = widget.value - 0.1;
48
- }
49
- _progressAnimation = Tween<double>(
50
- begin: start,
51
- end: widget.value,
52
- ).animate(
53
- CurvedAnimation(
54
- parent: animationController,
55
- curve: Curves.ease,
56
- ),
57
- );
58
- animationController.forward(from: 0);
59
- }
60
-
61
- @override
62
- Widget build(BuildContext context) {
63
- return AnimatedBuilder(
64
- animation: _progressAnimation,
65
- builder: (context, child) {
66
- return Padding(
67
- // Intentionally narrow (80px lateral) — visual design choice for progress bar
68
- padding: const EdgeInsets.fromLTRB(80, KasySpacing.md, 80, 0),
69
- child: ClipRRect(
70
- borderRadius: KasyRadius.fullBorderRadius,
71
- child: LinearProgressIndicator(
72
- value: _progressAnimation.value,
73
- minHeight: 16,
74
- valueColor: AlwaysStoppedAnimation<Color>(
75
- context.colors.primary,
76
- ),
77
- backgroundColor: context.colors.primary.withValues(alpha: 0.1),
78
- ),
79
- ),
80
- );
81
- },
82
- );
83
- }
84
- }
@@ -1,173 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_animate/flutter_animate.dart';
3
- import 'package:flutter_riverpod/flutter_riverpod.dart';
4
- import 'package:kasy_kit/components/components.dart';
5
- import 'package:kasy_kit/core/animations/movefade_anim.dart';
6
- import 'package:kasy_kit/core/theme/theme.dart';
7
- import 'package:kasy_kit/core/widgets/responsive_layout.dart';
8
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_background.dart';
9
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_progress.dart';
10
- import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_sticky_footer.dart';
11
- import 'package:kasy_kit/features/onboarding/ui/widgets/selectable_row_tile.dart';
12
-
13
- typedef OptionBuilder = Widget Function(String key, bool selected);
14
-
15
- typedef ReassuranceBuilder = Widget? Function(String key);
16
-
17
- typedef OnOptionIdSelected = void Function(String id);
18
-
19
- typedef OnValidate = void Function(String? key);
20
-
21
- /// Single choice question with radio buttons
22
- class OnboardingRadioQuestion extends ConsumerStatefulWidget {
23
- final double? progress;
24
- final String title;
25
- final String description;
26
- final String btnText;
27
- final List<String> optionIds;
28
- final OptionBuilder optionBuilder;
29
- final ReassuranceBuilder? reassuranceBuilder;
30
- final OnOptionIdSelected? onOptionIdSelected;
31
- final OnValidate? onValidate;
32
-
33
- const OnboardingRadioQuestion({
34
- super.key,
35
- required this.title,
36
- required this.description,
37
- required this.btnText,
38
- required this.optionIds,
39
- required this.optionBuilder,
40
- this.progress,
41
- this.onOptionIdSelected,
42
- this.onValidate,
43
- this.reassuranceBuilder,
44
- });
45
-
46
- @override
47
- ConsumerState<OnboardingRadioQuestion> createState() =>
48
- _OnboardingRadioQuestionState();
49
- }
50
-
51
- class _OnboardingRadioQuestionState
52
- extends ConsumerState<OnboardingRadioQuestion> {
53
- String? selectedChoiceId;
54
-
55
- @override
56
- Widget build(BuildContext context) {
57
- final scrollBody = Column(
58
- crossAxisAlignment: CrossAxisAlignment.stretch,
59
- children: [
60
- if (widget.progress != null)
61
- OnboardingProgress(value: widget.progress!),
62
- Padding(
63
- padding: const EdgeInsets.fromLTRB(
64
- KasySpacing.md,
65
- KasySpacing.xl,
66
- KasySpacing.md,
67
- 0,
68
- ),
69
- child: MoveFadeAnim(
70
- delayInMs: 100,
71
- child: Text(
72
- widget.title,
73
- textAlign: TextAlign.center,
74
- style: context.textTheme.headlineLarge?.copyWith(
75
- color: context.colors.onBackground,
76
- ),
77
- ),
78
- ),
79
- ),
80
- Padding(
81
- padding: const EdgeInsets.fromLTRB(
82
- KasySpacing.lg,
83
- KasySpacing.md,
84
- KasySpacing.lg,
85
- KasySpacing.xl,
86
- ),
87
- child: MoveFadeAnim(
88
- delayInMs: 200,
89
- child: Text(
90
- widget.description,
91
- textAlign: TextAlign.center,
92
- style: context.textTheme.bodyLarge?.copyWith(
93
- color: context.colors.onBackground.withValues(alpha: 0.6),
94
- ),
95
- ),
96
- ),
97
- ),
98
- Padding(
99
- padding: const EdgeInsets.symmetric(horizontal: KasySpacing.md),
100
- child: OnboardingSelectableRowGroup(
101
- physics: const NeverScrollableScrollPhysics(),
102
- options: widget.optionIds
103
- .map(
104
- (e) {
105
- final index = widget.optionIds.indexOf(e);
106
- return Animate(
107
- effects: [
108
- FadeEffect(
109
- delay: Duration(milliseconds: 300 + index * 100),
110
- duration: const Duration(milliseconds: 550),
111
- curve: Curves.easeInOut,
112
- ),
113
- ],
114
- child: widget.optionBuilder(e, e == selectedChoiceId),
115
- );
116
- },
117
- ).toList(),
118
- onSelect: (index, selected) {
119
- widget.onOptionIdSelected?.call(widget.optionIds[index]);
120
- setState(() {
121
- selectedChoiceId = widget.optionIds[index];
122
- });
123
- },
124
- onSelectInfoWidget: widget.optionIds
125
- .map((el) => widget.reassuranceBuilder?.call(el))
126
- .toList(),
127
- ),
128
- ),
129
- const SizedBox(height: KasySpacing.xl),
130
- ],
131
- );
132
-
133
- return OnboardingBackground(
134
- child: Column(
135
- crossAxisAlignment: CrossAxisAlignment.stretch,
136
- children: [
137
- Expanded(
138
- child: SafeArea(
139
- bottom: false,
140
- child: SingleChildScrollView(
141
- padding: const EdgeInsets.only(bottom: KasySpacing.md),
142
- child: ResponsiveBuilder(
143
- small: scrollBody,
144
- medium: Center(
145
- child: ConstrainedBox(
146
- constraints: const BoxConstraints(maxWidth: 600),
147
- child: scrollBody,
148
- ),
149
- ),
150
- ),
151
- ),
152
- ),
153
- ),
154
- DeviceSizeBuilder(
155
- builder: (device) => OnboardingStickyFooter(
156
- maxContentWidth:
157
- device == DeviceType.small ? null : 600,
158
- children: [
159
- KasyButton(
160
- label: widget.btnText,
161
- expand: true,
162
- onPressed: selectedChoiceId == null
163
- ? null
164
- : () => widget.onValidate?.call(selectedChoiceId),
165
- ),
166
- ],
167
- ),
168
- ),
169
- ],
170
- ),
171
- );
172
- }
173
- }
@@ -1,45 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_animate/flutter_animate.dart';
3
- import 'package:kasy_kit/core/theme/theme.dart';
4
-
5
- class CheckedReassurance extends StatelessWidget {
6
- final String text;
7
-
8
- const CheckedReassurance({super.key, required this.text});
9
-
10
- @override
11
- Widget build(BuildContext context) {
12
- return Animate(
13
- effects: const [
14
- FadeEffect(
15
- duration: Duration(milliseconds: 300),
16
- curve: Curves.easeInOut,
17
- ),
18
- MoveEffect(
19
- duration: Duration(milliseconds: 250),
20
- curve: Curves.easeInOut,
21
- begin: Offset(0, -20),
22
- end: Offset.zero,
23
- ),
24
- ],
25
- child: Container(
26
- padding: const EdgeInsets.all(KasySpacing.lg),
27
- decoration: BoxDecoration(
28
- color: context.colors.success.withValues(alpha: 0.05),
29
- borderRadius: KasyRadius.smBorderRadius,
30
- border: Border.all(
31
- color: context.colors.muted,
32
- ),
33
- ),
34
- child: Text(
35
- text,
36
- textAlign: TextAlign.left,
37
- style: context.textTheme.bodyLarge?.copyWith(
38
- color: context.colors.muted,
39
- fontWeight: FontWeight.w900,
40
- ),
41
- ),
42
- ),
43
- );
44
- }
45
- }
@@ -1,77 +0,0 @@
1
- import 'package:flutter/foundation.dart';
2
- import 'package:flutter/material.dart';
3
- import 'package:kasy_kit/core/animations/movefade_anim.dart';
4
- import 'package:kasy_kit/core/theme/theme.dart';
5
-
6
- /// Rodapé fixo do onboarding: fundo até a borda inferior + animação de entrada.
7
- class OnboardingStickyFooter extends StatelessWidget {
8
- const OnboardingStickyFooter({
9
- super.key,
10
- required this.children,
11
- this.animate = true,
12
- this.animationDelayMs = 400,
13
- this.horizontalPadding = KasySpacing.lg,
14
- this.maxContentWidth,
15
- });
16
-
17
- final List<Widget> children;
18
- final bool animate;
19
- final int animationDelayMs;
20
- final double horizontalPadding;
21
-
22
- /// Largura máxima do conteúdo (ex.: 600 em telas médias).
23
- final double? maxContentWidth;
24
-
25
- @override
26
- Widget build(BuildContext context) {
27
- final bottomInset = MediaQuery.viewPaddingOf(context).bottom;
28
-
29
- Widget content = Column(
30
- crossAxisAlignment: CrossAxisAlignment.stretch,
31
- children: children,
32
- );
33
-
34
- if (maxContentWidth != null) {
35
- content = Center(
36
- child: ConstrainedBox(
37
- constraints: BoxConstraints(maxWidth: maxContentWidth!),
38
- child: content,
39
- ),
40
- );
41
- }
42
-
43
- Widget footer = Container(
44
- width: double.infinity,
45
- decoration: BoxDecoration(
46
- color: context.colors.background,
47
- boxShadow: [
48
- BoxShadow(
49
- color: context.colors.onBackground.withValues(alpha: 0.06),
50
- blurRadius: 16,
51
- offset: const Offset(0, -4),
52
- ),
53
- ],
54
- ),
55
- padding: EdgeInsets.fromLTRB(
56
- horizontalPadding,
57
- KasySpacing.md,
58
- horizontalPadding,
59
- KasySpacing.md +
60
- bottomInset +
61
- (defaultTargetPlatform == TargetPlatform.android
62
- ? KasySpacing.sm
63
- : 0),
64
- ),
65
- child: content,
66
- );
67
-
68
- if (animate) {
69
- footer = MoveFadeAnim(
70
- delayInMs: animationDelayMs,
71
- child: footer,
72
- );
73
- }
74
-
75
- return footer;
76
- }
77
- }