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,175 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:go_router/go_router.dart';
4
- import 'package:kasy_kit/components/kasy_toast.dart';
5
- import 'package:kasy_kit/core/theme/theme.dart';
6
- import 'package:kasy_kit/core/widgets/responsive_layout.dart';
7
- import 'package:kasy_kit/i18n/translations.g.dart';
8
- import 'package:kasy_kit/features/feedbacks/providers/feedback_page_notifier.dart';
9
- import 'package:kasy_kit/features/feedbacks/ui/widgets/add_feature_button.dart';
10
- import 'package:kasy_kit/features/feedbacks/ui/widgets/feature_card.dart';
11
-
12
- class FeedbackPage extends ConsumerWidget {
13
- const FeedbackPage({super.key});
14
-
15
- @override
16
- Widget build(BuildContext context, WidgetRef ref) {
17
- final state = ref.watch(feedbackPageProvider);
18
- final translations = Translations.of(context).feature_requests;
19
-
20
- return Scaffold(
21
- backgroundColor: context.colors.background,
22
- body: SafeArea(
23
- child: LargeLayoutContainer(
24
- child: CustomScrollView(
25
- slivers: [
26
- SliverAppBar(
27
- backgroundColor: Colors.transparent,
28
- leading: IconButton(
29
- icon: const Icon(Icons.arrow_back),
30
- onPressed: () =>
31
- context.canPop() ? context.pop() : context.go('/'),
32
- ),
33
- ),
34
- SliverToBoxAdapter(
35
- child: Padding(
36
- padding: const EdgeInsets.fromLTRB(
37
- KasySpacing.lg,
38
- KasySpacing.xl,
39
- KasySpacing.lg,
40
- 0,
41
- ),
42
- child: Text(
43
- translations.title,
44
- style: context.textTheme.headlineMedium?.copyWith(
45
- fontWeight: FontWeight.bold,
46
- ),
47
- ),
48
- ),
49
- ),
50
- SliverToBoxAdapter(
51
- child: Padding(
52
- padding: const EdgeInsets.fromLTRB(
53
- KasySpacing.lg,
54
- KasySpacing.sm,
55
- KasySpacing.lg,
56
- KasySpacing.md,
57
- ),
58
- child: Text(
59
- translations.description,
60
- style: context.textTheme.bodyLarge?.copyWith(
61
- fontWeight: FontWeight.w400,
62
- color: context.colors.muted,
63
- ),
64
- ),
65
- ),
66
- ),
67
- SliverToBoxAdapter(
68
- child: Padding(
69
- padding: const EdgeInsets.symmetric(
70
- horizontal: KasySpacing.lg,
71
- vertical: KasySpacing.md,
72
- ),
73
- child: AddFeatureButton(
74
- title: translations.add_feature.title,
75
- description: translations.add_feature.description,
76
- onPressed: () async {
77
- final success = await context.push<bool>('/feedback/new');
78
- if (success == true && context.mounted) {
79
- showSuccessToast(
80
- context: context,
81
- title: translations.add_feature.toast_success.title,
82
- text: translations.add_feature.toast_success.description,
83
- );
84
- }
85
- },
86
- ),
87
- ),
88
- ),
89
- state.map(
90
- data: (data) {
91
- if (data.value.featureRequests.isEmpty) {
92
- return SliverToBoxAdapter(
93
- child: Padding(
94
- padding: const EdgeInsets.symmetric(
95
- horizontal: KasySpacing.lg,
96
- vertical: KasySpacing.md,
97
- ),
98
- child: Text(
99
- translations.no_requests,
100
- textAlign: TextAlign.center,
101
- style: context.textTheme.bodyMedium?.copyWith(
102
- fontWeight: FontWeight.w300,
103
- color: context.colors.muted,
104
- ),
105
- ),
106
- ),
107
- );
108
- }
109
- return SliverList.separated(
110
- itemBuilder: (context, index) => Padding(
111
- padding: const EdgeInsets.symmetric(
112
- horizontal: KasySpacing.lg,
113
- ),
114
- child: FeatureCard(
115
- title: data.value.featureRequests[index].title,
116
- description:
117
- data.value.featureRequests[index].description,
118
- votes: data.value.featureRequests[index].votes,
119
- onVote: () {
120
- ref
121
- .read(feedbackPageProvider.notifier)
122
- .vote(data.value.featureRequests[index]);
123
- },
124
- voted: data.value.hasVoted(
125
- data.value.featureRequests[index],
126
- ),
127
- ),
128
- ),
129
- separatorBuilder: (context, index) =>
130
- const SizedBox(height: KasySpacing.smd),
131
- itemCount: data.value.featureRequests.length,
132
- );
133
- },
134
- error: (error) => SliverFillRemaining(
135
- child: Center(child: Text(error.error.toString())),
136
- ),
137
- loading: (data) {
138
- if (!data.hasValue) {
139
- return const SliverFillRemaining(
140
- child: Center(child: CircularProgressIndicator()),
141
- );
142
- }
143
- return SliverList.separated(
144
- itemBuilder: (context, index) => Padding(
145
- padding: const EdgeInsets.symmetric(
146
- horizontal: KasySpacing.lg,
147
- ),
148
- child: FeatureCard(
149
- title: data.value!.featureRequests[index].title,
150
- description:
151
- data.value!.featureRequests[index].description,
152
- votes: data.value!.featureRequests[index].votes,
153
- onVote: () {},
154
- disabled: true,
155
- voted: data.value!.hasVoted(
156
- data.value!.featureRequests[index],
157
- ),
158
- ),
159
- ),
160
- separatorBuilder: (context, index) =>
161
- const SizedBox(height: KasySpacing.smd),
162
- itemCount: data.value!.featureRequests.length,
163
- );
164
- },
165
- ),
166
- const SliverToBoxAdapter(
167
- child: SizedBox(height: KasySpacing.xxxl),
168
- ),
169
- ],
170
- ),
171
- ),
172
- ),
173
- );
174
- }
175
- }
@@ -1,76 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:kasy_kit/core/theme/theme.dart';
3
-
4
- class AddFeatureButton extends StatefulWidget {
5
- final String title;
6
- final String description;
7
- final VoidCallback onPressed;
8
-
9
- const AddFeatureButton({
10
- super.key,
11
- required this.title,
12
- required this.description,
13
- required this.onPressed,
14
- });
15
-
16
- @override
17
- State<AddFeatureButton> createState() => _AddFeatureButtonState();
18
- }
19
-
20
- class _AddFeatureButtonState extends State<AddFeatureButton> {
21
- @override
22
- Widget build(BuildContext context) {
23
- return InkWell(
24
- onTap: widget.onPressed,
25
- borderRadius: KasyRadius.mdBorderRadius,
26
- child: Ink(
27
- padding: const EdgeInsets.symmetric(
28
- horizontal: KasySpacing.lg,
29
- vertical: KasySpacing.md,
30
- ),
31
- decoration: BoxDecoration(
32
- color: context.colors.primary,
33
- borderRadius: KasyRadius.mdBorderRadius,
34
- border: Border.all(
35
- color: context.colors.onBackground.withValues(alpha: .05),
36
- ),
37
- boxShadow: [
38
- BoxShadow(
39
- color: context.colors.primary.withValues(alpha: 0.05),
40
- blurRadius: 8,
41
- offset: const Offset(0, 4),
42
- ),
43
- ],
44
- ),
45
- child: Row(
46
- children: [
47
- Icon(Icons.add, size: 32, color: context.colors.onPrimary),
48
- const SizedBox(width: KasySpacing.md),
49
- Expanded(
50
- child: Column(
51
- crossAxisAlignment: CrossAxisAlignment.start,
52
- spacing: KasySpacing.xs,
53
- children: [
54
- Text(
55
- widget.title,
56
- style: context.textTheme.titleLarge?.copyWith(
57
- fontWeight: FontWeight.bold,
58
- color: context.colors.onPrimary,
59
- ),
60
- ),
61
- Text(
62
- widget.description,
63
- style: context.textTheme.bodyMedium?.copyWith(
64
- fontWeight: FontWeight.w400,
65
- color: context.colors.onPrimary.withValues(alpha: 0.7),
66
- ),
67
- ),
68
- ],
69
- ),
70
- ),
71
- ],
72
- ),
73
- ),
74
- );
75
- }
76
- }
@@ -1,279 +0,0 @@
1
- import 'dart:math';
2
-
3
- import 'package:flutter/material.dart';
4
- import 'package:flutter/services.dart';
5
- import 'package:kasy_kit/core/theme/theme.dart';
6
- import 'package:kasy_kit/core/widgets/debouncer.dart';
7
-
8
- class FeatureCard extends StatefulWidget {
9
- final String title;
10
- final String description;
11
- final int votes;
12
- final VoidCallback onVote;
13
- final bool disabled;
14
- final bool voted;
15
-
16
- const FeatureCard({
17
- super.key,
18
- required this.title,
19
- required this.description,
20
- required this.votes,
21
- required this.onVote,
22
- this.disabled = false,
23
- required this.voted,
24
- });
25
-
26
- @override
27
- State<FeatureCard> createState() => _FeatureCardState();
28
- }
29
-
30
- class _FeatureCardState extends State<FeatureCard> {
31
- @override
32
- Widget build(BuildContext context) {
33
- return Container(
34
- padding: const EdgeInsets.all(KasySpacing.lg),
35
- decoration: BoxDecoration(
36
- color: context.colors.surface,
37
- borderRadius: KasyRadius.smBorderRadius,
38
- border: Border.all(
39
- color: context.colors.outline,
40
- ),
41
- boxShadow: [
42
- BoxShadow(
43
- color: context.colors.primary.withValues(alpha: 0.05),
44
- blurRadius: 8,
45
- offset: const Offset(0, 4),
46
- ),
47
- BoxShadow(
48
- color: context.colors.onBackground.withValues(alpha: 0.03),
49
- blurRadius: 8,
50
- offset: const Offset(0, 4),
51
- spreadRadius: 2,
52
- ),
53
- ],
54
- ),
55
- child: Row(
56
- children: [
57
- Expanded(
58
- child: Column(
59
- crossAxisAlignment: CrossAxisAlignment.start,
60
- children: [
61
- Text(
62
- widget.title,
63
- style: context.textTheme.bodyLarge?.copyWith(
64
- fontWeight: FontWeight.bold,
65
- ),
66
- ),
67
- const SizedBox(height: KasySpacing.xs),
68
- Text(
69
- widget.description,
70
- style: context.textTheme.bodyMedium?.copyWith(
71
- fontWeight: FontWeight.w400,
72
- color: context.colors.muted,
73
- ),
74
- ),
75
- ],
76
- ),
77
- ),
78
- const SizedBox(width: KasySpacing.md),
79
- switch (widget.voted) {
80
- false => VoteCard.blank(
81
- context: context,
82
- id: widget.title,
83
- votes: widget.votes,
84
- onVote: widget.onVote,
85
- disabled: widget.disabled,
86
- ),
87
- true => VoteCard.voted(
88
- context: context,
89
- id: widget.title,
90
- votes: widget.votes,
91
- onVote: widget.onVote,
92
- disabled: widget.disabled,
93
- ),
94
- }
95
- ],
96
- ),
97
- );
98
- }
99
- }
100
-
101
- class VoteCard extends StatefulWidget {
102
- final int votes;
103
- final VoidCallback onVote;
104
- final Color borderColor;
105
- final Color bgColor;
106
- final Color textColor;
107
- final bool isBold;
108
- final bool disabled;
109
- final String id;
110
-
111
- const VoteCard({
112
- super.key,
113
- required this.votes,
114
- required this.onVote,
115
- required this.bgColor,
116
- required this.textColor,
117
- required this.isBold,
118
- required this.borderColor,
119
- required this.disabled,
120
- required this.id,
121
- });
122
-
123
- factory VoteCard.blank({
124
- required BuildContext context,
125
- required VoidCallback onVote,
126
- required int votes,
127
- required bool disabled,
128
- required String id,
129
- }) =>
130
- VoteCard(
131
- id: id,
132
- onVote: onVote,
133
- votes: votes,
134
- bgColor: context.colors.primary,
135
- textColor: context.colors.onPrimary,
136
- borderColor: context.colors.primary,
137
- isBold: false,
138
- disabled: disabled,
139
- );
140
-
141
- factory VoteCard.voted({
142
- required BuildContext context,
143
- required VoidCallback onVote,
144
- required int votes,
145
- required bool disabled,
146
- required String id,
147
- }) =>
148
- VoteCard(
149
- id: id,
150
- onVote: onVote,
151
- votes: votes,
152
- bgColor: context.colors.primary.withValues(alpha: .1),
153
- textColor: context.colors.onBackground,
154
- borderColor: context.colors.outline,
155
- isBold: true,
156
- disabled: disabled,
157
- );
158
-
159
- @override
160
- State<VoteCard> createState() => _VoteCardState();
161
- }
162
-
163
- class _VoteCardState extends State<VoteCard>
164
- with SingleTickerProviderStateMixin {
165
- // ignore: use_late_for_private_fields_and_variables
166
- AnimationController? _controller;
167
- // ignore: use_late_for_private_fields_and_variables
168
- Animation<double>? _animation;
169
-
170
- final debouncer = Debouncer(delay: const Duration(milliseconds: 250));
171
- bool _goingUp = true;
172
-
173
- @override
174
- void initState() {
175
- super.initState();
176
- _controller = AnimationController(
177
- duration: const Duration(milliseconds: 250),
178
- vsync: this,
179
- );
180
- _animation = Tween<double>(begin: 1, end: 1.2).animate(
181
- CurvedAnimation(parent: _controller!, curve: Curves.easeInOut),
182
- );
183
- }
184
-
185
- @override
186
- void didUpdateWidget(VoteCard oldWidget) {
187
- super.didUpdateWidget(oldWidget);
188
- if (widget.votes != oldWidget.votes) {
189
- _goingUp = widget.votes > oldWidget.votes;
190
- }
191
- }
192
-
193
- @override
194
- void dispose() {
195
- _controller?.dispose();
196
- super.dispose();
197
- }
198
-
199
- @override
200
- Widget build(BuildContext context) {
201
- return AnimatedBuilder(
202
- animation: _animation!,
203
- builder: (context, child) {
204
- return Transform.scale(scale: _animation!.value, child: child);
205
- },
206
- child: Material(
207
- color: Colors.transparent,
208
- child: InkWell(
209
- onTap: () {
210
- if (widget.disabled) return;
211
- HapticFeedback.selectionClick();
212
- SystemSound.play(SystemSoundType.click);
213
- widget.onVote();
214
- _controller!.forward().then((_) => _controller!.reverse());
215
- },
216
- child: Ink(
217
- width: 48,
218
- height: 64,
219
- decoration: BoxDecoration(
220
- color: widget.bgColor,
221
- borderRadius: KasyRadius.smBorderRadius,
222
- border: Border.all(color: widget.borderColor),
223
- ),
224
- padding: const EdgeInsets.all(KasySpacing.sm),
225
- child: Column(
226
- mainAxisAlignment: MainAxisAlignment.center,
227
- children: [
228
- Transform.rotate(
229
- angle: pi / 2,
230
- child: Icon(
231
- Icons.arrow_back_ios,
232
- size: 16,
233
- color: widget.textColor,
234
- ),
235
- ),
236
- ClipRect(
237
- child: AnimatedSwitcher(
238
- duration: const Duration(milliseconds: 250),
239
- transitionBuilder: (child, animation) {
240
- final isIncoming = (child.key as ValueKey?)?.value ==
241
- 'votes-${widget.id}-${widget.votes}';
242
- final beginOffset = isIncoming
243
- ? (_goingUp
244
- ? const Offset(0, 1)
245
- : const Offset(0, -1))
246
- : (_goingUp
247
- ? const Offset(0, -1)
248
- : const Offset(0, 1));
249
- return SlideTransition(
250
- position: Tween<Offset>(
251
- begin: beginOffset,
252
- end: Offset.zero,
253
- ).animate(CurvedAnimation(
254
- parent: animation,
255
- curve: Curves.easeOut,
256
- )),
257
- child:
258
- FadeTransition(opacity: animation, child: child),
259
- );
260
- },
261
- child: Text(
262
- key: ValueKey('votes-${widget.id}-${widget.votes}'),
263
- widget.votes.toString(),
264
- style: context.textTheme.bodyLarge?.copyWith(
265
- fontWeight:
266
- widget.isBold ? FontWeight.bold : FontWeight.w400,
267
- color: widget.textColor,
268
- ),
269
- ),
270
- ),
271
- ),
272
- ],
273
- ),
274
- ),
275
- ),
276
- ),
277
- );
278
- }
279
- }
@@ -1,8 +0,0 @@
1
- # App Store Connect API — copy to apple.env and fill in (never commit apple.env)
2
- # Run: kasy ios configure
3
-
4
- APP_STORE_API_KEY=
5
- APP_STORE_ISSUER_ID=
6
-
7
- # Optional: numeric App Store Connect app ID (for reference / future sync)
8
- # APP_STORE_APP_ID=
@@ -1,7 +0,0 @@
1
- # Codemagic API — copy to codemagic.env and fill in (never commit codemagic.env)
2
- # Run: kasy codemagic configure
3
-
4
- CODEMAGIC_API_TOKEN=
5
- CODEMAGIC_APP_ID=
6
- CODEMAGIC_WORKFLOW_ID=ios-workflow
7
- CODEMAGIC_BRANCH=main
@@ -1,50 +0,0 @@
1
- # Publish iOS with Codemagic (no Mac)
2
-
3
- ## Prerequisites
4
-
5
- - [Codemagic](https://codemagic.io) account
6
- - Git repository connected to Codemagic
7
- - Apple Developer account + app in App Store Connect
8
-
9
- ## 1. Add CI to the project (if missing)
10
-
11
- ```bash
12
- kasy add ci
13
- ```
14
-
15
- Creates `codemagic.yaml` at the project root.
16
-
17
- ## 2. Configure in the Codemagic dashboard
18
-
19
- 1. Open [codemagic.io/apps](https://codemagic.io/apps) and add your repository.
20
- 2. **Code signing (iOS):** set up App Store distribution certificate and profile.
21
- 3. **Integrations → App Store Connect:** link your Apple account.
22
- 4. **Environment variables:** add to your variable group (e.g. `appstore_credentials`):
23
- - `BACKEND_URL`, `SENTRY_DSN`, `RC_IOS_API_KEY`, `RC_ANDROID_API_KEY`, `MIXPANEL_TOKEN`
24
- 5. In `codemagic.yaml`, set `APP_ID` (numeric App Store Connect app ID from the app URL).
25
-
26
- ## 3. Configure from the terminal
27
-
28
- ```bash
29
- kasy codemagic configure
30
- ```
31
-
32
- Enter **API token** (Settings → Codemagic API), **App ID**, and **Workflow ID** (default `ios-workflow`).
33
-
34
- ## 4. Trigger a build
35
-
36
- ```bash
37
- kasy codemagic release
38
- ```
39
-
40
- The cloud build runs and may upload to TestFlight per `codemagic.yaml`.
41
-
42
- ## Build status
43
-
44
- ```bash
45
- kasy codemagic status <buildId>
46
- ```
47
-
48
- ## Local Mac
49
-
50
- If you have a Mac: [ios-release.md](./ios-release.md) and `kasy ios release`.
@@ -1,50 +0,0 @@
1
- # Publicar iOS con Codemagic (sin Mac)
2
-
3
- ## Requisitos
4
-
5
- - Cuenta [Codemagic](https://codemagic.io)
6
- - Repositorio Git conectado a Codemagic
7
- - Cuenta Apple Developer + app en App Store Connect
8
-
9
- ## 1. Agregar CI al proyecto (si falta)
10
-
11
- ```bash
12
- kasy add ci
13
- ```
14
-
15
- Crea `codemagic.yaml` en la raíz del proyecto.
16
-
17
- ## 2. Configurar en el panel Codemagic
18
-
19
- 1. Abre [codemagic.io/apps](https://codemagic.io/apps) y agrega el repositorio.
20
- 2. **Code signing (iOS):** certificado y perfil de distribución App Store.
21
- 3. **Integrations → App Store Connect:** vincula la cuenta Apple.
22
- 4. **Environment variables:** en el grupo del app (ej. `appstore_credentials`):
23
- - `BACKEND_URL`, `SENTRY_DSN`, `RC_IOS_API_KEY`, `RC_ANDROID_API_KEY`, `MIXPANEL_TOKEN`
24
- 5. En `codemagic.yaml`, completa `APP_ID` (ID numérico del app en App Store Connect).
25
-
26
- ## 3. Configurar en la terminal
27
-
28
- ```bash
29
- kasy codemagic configure
30
- ```
31
-
32
- Indica **API token** (Settings → Codemagic API), **App ID** y **Workflow ID** (`ios-workflow` por defecto).
33
-
34
- ## 4. Disparar build
35
-
36
- ```bash
37
- kasy codemagic release
38
- ```
39
-
40
- El build en la nube puede subir a TestFlight según `codemagic.yaml`.
41
-
42
- ## Estado del build
43
-
44
- ```bash
45
- kasy codemagic status <buildId>
46
- ```
47
-
48
- ## Mac local
49
-
50
- Si tienes Mac: [ios-release.md](./ios-release.md) y `kasy ios release`.
@@ -1,50 +0,0 @@
1
- # Publicar iOS com Codemagic (sem Mac)
2
-
3
- ## Pré-requisitos
4
-
5
- - Conta [Codemagic](https://codemagic.io)
6
- - Repositório Git conectado ao Codemagic
7
- - Conta Apple Developer + app no App Store Connect
8
-
9
- ## 1. Adicionar CI ao projeto (se ainda não tiver)
10
-
11
- ```bash
12
- kasy add ci
13
- ```
14
-
15
- Isso cria `codemagic.yaml` na raiz do projeto.
16
-
17
- ## 2. Configurar no painel Codemagic
18
-
19
- 1. Abra [codemagic.io/apps](https://codemagic.io/apps) e adicione o repositório.
20
- 2. **Code signing (iOS):** configure certificado e perfil de distribuição App Store.
21
- 3. **Integrations → App Store Connect:** conecte a conta Apple (recomendado).
22
- 4. **Environment variables:** adicione no grupo do app (ex.: `appstore_credentials`):
23
- - `BACKEND_URL`, `SENTRY_DSN`, `RC_IOS_API_KEY`, `RC_ANDROID_API_KEY`, `MIXPANEL_TOKEN`
24
- 5. No `codemagic.yaml`, preencha `APP_ID` (ID numérico do app no App Store Connect — aparece na URL do app).
25
-
26
- ## 3. Configurar no terminal
27
-
28
- ```bash
29
- kasy codemagic configure
30
- ```
31
-
32
- Informe o **API token** (Settings → Codemagic API), **App ID** e **Workflow ID** (`ios-workflow` por padrão).
33
-
34
- ## 4. Disparar build
35
-
36
- ```bash
37
- kasy codemagic release
38
- ```
39
-
40
- O build roda na nuvem e, conforme o `codemagic.yaml`, pode enviar para TestFlight automaticamente.
41
-
42
- ## Status do build
43
-
44
- ```bash
45
- kasy codemagic status <buildId>
46
- ```
47
-
48
- ## Mac local
49
-
50
- Se tiver Mac: [ios-release.md](./ios-release.md) e `kasy ios release`.