create-flutterinit 0.1.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.
- package/bin/index.ts +3 -0
- package/package.json +46 -0
- package/templates/base/.cursor/rules/flutter-project.mdc.hbs +132 -0
- package/templates/base/AGENTS.md.hbs +137 -0
- package/templates/base/DESIGN.md.hbs +149 -0
- package/templates/base/README.md.hbs +19 -0
- package/templates/base/SETUP.md.hbs +253 -0
- package/templates/base/analysis_options.yaml +88 -0
- package/templates/base/assets/.keep +1 -0
- package/templates/base/assets/icons/apple.svg +1 -0
- package/templates/base/assets/icons/facebook.svg +1 -0
- package/templates/base/assets/icons/google.svg +1 -0
- package/templates/base/assets/images/.gitkeep +0 -0
- package/templates/base/flutter_native_splash.yaml.hbs +8 -0
- package/templates/base/lib/main.dart.hbs +43 -0
- package/templates/base/lib/src/app.dart.hbs +105 -0
- package/templates/base/lib/src/config/app_config.dart.hbs +112 -0
- package/templates/base/lib/src/extensions/collection_extension.dart.hbs +55 -0
- package/templates/base/lib/src/extensions/context_extension.dart.hbs +167 -0
- package/templates/base/lib/src/extensions/date_time_extension.dart.hbs +40 -0
- package/templates/base/lib/src/extensions/extensions.dart.hbs +6 -0
- package/templates/base/lib/src/extensions/num_extension.dart.hbs +14 -0
- package/templates/base/lib/src/extensions/string_extension.dart.hbs +91 -0
- package/templates/base/lib/src/extensions/widget_extension.dart.hbs +47 -0
- package/templates/base/lib/src/imports/core_imports.dart.hbs +50 -0
- package/templates/base/lib/src/imports/imports.dart.hbs +2 -0
- package/templates/base/lib/src/imports/packages_imports.dart.hbs +110 -0
- package/templates/base/lib/src/routing/(isGetX)@app_bindings.dart.hbs +23 -0
- package/templates/base/lib/src/routing/app_router.dart.hbs +252 -0
- package/templates/base/lib/src/routing/app_routes.dart.hbs +46 -0
- package/templates/base/lib/src/routing/global_navigator.dart.hbs +15 -0
- package/templates/base/lib/src/services/auth_service.dart.hbs +78 -0
- package/templates/base/lib/src/services/copy_service.dart.hbs +16 -0
- package/templates/base/lib/src/services/internet_connection_service.dart.hbs +10 -0
- package/templates/base/lib/src/services/services.dart.hbs +45 -0
- package/templates/base/lib/src/shared/app_assets.dart.hbs +15 -0
- package/templates/base/lib/src/shared/enums/app_status.dart.hbs +40 -0
- package/templates/base/lib/src/shared/enums/button_enums.dart.hbs +22 -0
- package/templates/base/lib/src/shared/enums/enums.dart.hbs +3 -0
- package/templates/base/lib/src/shared/enums/snack_bar_type.dart.hbs +22 -0
- package/templates/base/lib/src/shared/helpers/format_number.dart.hbs +18 -0
- package/templates/base/lib/src/shared/helpers/imports.dart.hbs +3 -0
- package/templates/base/lib/src/shared/helpers/show_app_sheet.dart.hbs +42 -0
- package/templates/base/lib/src/shared/helpers/show_dialog.dart.hbs +49 -0
- package/templates/base/lib/src/shared/helpers/show_toast.dart.hbs +92 -0
- package/templates/base/lib/src/shared/hooks/hooks.dart.hbs +13 -0
- package/templates/base/lib/src/shared/hooks/use_copy.dart.hbs +41 -0
- package/templates/base/lib/src/shared/hooks/use_timer.dart.hbs +158 -0
- package/templates/base/lib/src/shared/shared.dart.hbs +12 -0
- package/templates/base/lib/src/shared/widgets/app_button.dart.hbs +144 -0
- package/templates/base/lib/src/shared/widgets/app_card.dart.hbs +126 -0
- package/templates/base/lib/src/shared/widgets/app_divider.dart.hbs +88 -0
- package/templates/base/lib/src/shared/widgets/app_empty_state.dart.hbs +73 -0
- package/templates/base/lib/src/shared/widgets/app_error_widget.dart.hbs +69 -0
- package/templates/base/lib/src/shared/widgets/app_icon.dart.hbs +25 -0
- package/templates/base/lib/src/shared/widgets/app_loading.dart.hbs +54 -0
- package/templates/base/lib/src/shared/widgets/app_text_field.dart.hbs +89 -0
- package/templates/base/lib/src/shared/widgets/app_top_bar.dart.hbs +105 -0
- package/templates/base/lib/src/shared/widgets/common_image.dart.hbs +120 -0
- package/templates/base/lib/src/shared/widgets/toast/imports.dart.hbs +4 -0
- package/templates/base/lib/src/shared/widgets/toast/raw_toast.dart.hbs +109 -0
- package/templates/base/lib/src/shared/widgets/toast/toast.dart.hbs +142 -0
- package/templates/base/lib/src/shared/widgets/toast/toast_card.dart.hbs +57 -0
- package/templates/base/lib/src/shared/widgets/widgets.dart.hbs +14 -0
- package/templates/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs +51 -0
- package/templates/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs +25 -0
- package/templates/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs +27 -0
- package/templates/base/lib/src/shared/wrappers/(usesSkeletonizer)@skeleton_wrapper.dart.hbs +81 -0
- package/templates/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs +258 -0
- package/templates/base/lib/src/shared/wrappers/wrappers.dart.hbs +15 -0
- package/templates/base/lib/src/theme/app_borders.dart.hbs +70 -0
- package/templates/base/lib/src/theme/app_curves.dart.hbs +69 -0
- package/templates/base/lib/src/theme/app_durations.dart.hbs +48 -0
- package/templates/base/lib/src/theme/app_shadows.dart.hbs +73 -0
- package/templates/base/lib/src/theme/app_spacing.dart.hbs +80 -0
- package/templates/base/lib/src/theme/color_schemes.dart.hbs +126 -0
- package/templates/base/lib/src/theme/text_theme.dart.hbs +167 -0
- package/templates/base/lib/src/theme/theme.dart.hbs +431 -0
- package/templates/base/lib/src/theme/theme_constants.dart.hbs +20 -0
- package/templates/base/lib/src/utils/app_utils.dart.hbs +46 -0
- package/templates/base/lib/src/utils/debouncer.dart.hbs +31 -0
- package/templates/base/lib/src/utils/error_handler.dart.hbs +14 -0
- package/templates/base/lib/src/utils/failure.dart.hbs +30 -0
- package/templates/base/lib/src/utils/input_formatters.dart.hbs +27 -0
- package/templates/base/lib/src/utils/logger.dart.hbs +37 -0
- package/templates/base/lib/src/utils/platform_info.dart.hbs +13 -0
- package/templates/base/lib/src/utils/task_runner.dart.hbs +42 -0
- package/templates/base/lib/src/utils/typedefs.dart.hbs +6 -0
- package/templates/base/lib/src/utils/utils.dart.hbs +9 -0
- package/templates/base/pubspec.yaml.hbs +256 -0
- package/templates/base/test/widget_test.dart.hbs +56 -0
- package/templates/overlays/architecture/clean/architecture.md +6 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/clean/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/architecture.md +5 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/feature-first/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/architecture.md +6 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/datasources/local/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/datasources/remote/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/entities/user.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/domain/usecases/auth/.gitkeep +0 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/layer-first/lib/src/presentation/widgets/.gitkeep +0 -0
- package/templates/overlays/architecture/mvc/architecture.md +5 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isNoneState)@session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/services/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/services/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvc/lib/src/views/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/architecture.md +6 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/models/user_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/auth_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/session_bloc.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/auth_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/session_controller.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/auth_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/session_store.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/auth_view_model.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/session_manager.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/auth_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/session_provider.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/forgot_password_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/login_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/auth/signup_screen.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/home/home_page.dart.hbs +1 -0
- package/templates/overlays/architecture/mvvm/lib/src/ui/onboarding/onboarding_page.dart.hbs +1 -0
- package/templates/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs +101 -0
- package/templates/overlays/backend/custom/lib/src/services/auth_service.dart.hbs +158 -0
- package/templates/overlays/backend/firebase/lib/src/services/(usesFirebaseAuth)@auth_service.dart.hbs +96 -0
- package/templates/overlays/backend/supabase/lib/src/services/(usesSupabaseAuth)@auth_service.dart.hbs +97 -0
- package/templates/overlays/device/app_version_update/lib/src/services/(usesAppVersionUpdate)@version_update_service.dart.hbs +118 -0
- package/templates/overlays/device/device_info/lib/src/services/(usesDeviceInfoPlus)@device_info_service.dart.hbs +54 -0
- package/templates/overlays/extras/dotenv/.env.hbs +33 -0
- package/templates/overlays/extras/flavors/lib/src/flavors.dart.hbs +15 -0
- package/templates/overlays/extras/localization/assets/translations/en.json.hbs +47 -0
- package/templates/overlays/media/lib/src/services/(usesImagePicker,usesFilePicker)@media_service.dart.hbs +148 -0
- package/templates/overlays/networking/cached_image/lib/src/shared/widgets/app_cached_image.dart.hbs +160 -0
- package/templates/overlays/networking/dio/lib/src/services/(usesDio)@dio_service.dart.hbs +50 -0
- package/templates/overlays/networking/http/lib/src/services/(usesHttp)@http_service.dart.hbs +82 -0
- package/templates/overlays/storage/hive/lib/src/services/(usesHive)@hive_service.dart.hbs +59 -0
- package/templates/overlays/storage/secure_storage/lib/src/services/(usesSecureStorage)@secure_storage_service.dart.hbs +39 -0
- package/templates/overlays/storage/shared_preferences/lib/src/services/(usesSharedPreferences)@storage_service.dart.hbs +53 -0
- package/templates/overlays/utilities/geolocator/lib/src/services/(usesGeolocator)@location_service.dart.hbs +78 -0
- package/templates/overlays/utilities/path_provider/lib/src/services/(usesPathProvider)@path_service.dart.hbs +30 -0
- package/templates/overlays/utilities/permission_handler/lib/src/services/(usesPermissionHandler)@permission_service.dart.hbs +28 -0
- package/templates/overlays/utilities/permission_handler/lib/src/shared/hooks/use_permission.dart.hbs +44 -0
- package/templates/overlays/utilities/share_plus/lib/src/services/(usesSharePlus)@share_service.dart.hbs +22 -0
- package/templates/overlays/utilities/share_plus/lib/src/shared/hooks/use_share.dart.hbs +26 -0
- package/templates/overlays/utilities/url_launcher/lib/src/services/(usesUrlLauncher)@url_launcher_service.dart.hbs +37 -0
- package/templates/overlays/utilities/url_launcher/lib/src/shared/hooks/use_launch_url.dart.hbs +52 -0
- package/templates/partials/features/auth/auth_logic.hbs +611 -0
- package/templates/partials/features/auth/auth_repository.hbs +32 -0
- package/templates/partials/features/auth/auth_repository_impl.hbs +116 -0
- package/templates/partials/features/auth/forgot_password_screen.hbs +368 -0
- package/templates/partials/features/auth/login_screen.hbs +540 -0
- package/templates/partials/features/auth/session_provider.hbs +437 -0
- package/templates/partials/features/auth/signup_screen.hbs +511 -0
- package/templates/partials/features/auth/user_model.hbs +23 -0
- package/templates/partials/features/home/home_page.hbs +156 -0
- package/templates/partials/features/onboarding/onboarding_page.hbs +264 -0
- package/templates/partials/llm/add-feature-workflow.hbs +38 -0
- package/templates/partials/llm/architecture-rules.hbs +92 -0
- package/templates/partials/llm/backend-rules.hbs +30 -0
- package/templates/partials/llm/build-runner-note.hbs +15 -0
- package/templates/partials/llm/design-quick-ref.hbs +14 -0
- package/templates/partials/llm/design-quick-reference.hbs +14 -0
- package/templates/partials/llm/navigation-rules.hbs +27 -0
- package/templates/partials/llm/networking-rules.hbs +16 -0
- package/templates/partials/llm/packages-list.hbs +26 -0
- package/templates/partials/llm/services-conventions.hbs +20 -0
- package/templates/partials/llm/stack-summary.hbs +22 -0
- package/templates/partials/llm/state-management-rules.hbs +40 -0
- package/templates/partials/state_label.hbs +1 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# 🎉 Welcome to {{appName}}!
|
|
2
|
+
|
|
3
|
+
This project was generated dynamically based on your specific requirements. Before running your app for the first time, follow this brief setup guide to configure the required environment variables, permissions, and dependencies locally.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 📦 Initial Dependencies & Generation
|
|
8
|
+
|
|
9
|
+
First, fetch all pub packages:
|
|
10
|
+
```bash
|
|
11
|
+
flutter pub get
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Code Generation
|
|
15
|
+
{{#if (or flags.isMobX (eq flags.routerPackage "auto_route") flags.usesFirebase flags.usesHive)}}
|
|
16
|
+
Your stack relies on code generation ({{#if flags.usesHive}}Hive Adapters, {{/if}}{{#if flags.isMobX}}MobX, {{/if}}{{#if (eq flags.routerPackage "auto_route")}}Auto Route, {{/if}}{{#if flags.usesFirebase}}Firebase, {{/if}}etc.). Run the following command right away to generate the necessary files:
|
|
17
|
+
```bash
|
|
18
|
+
dart run build_runner build --delete-conflicting-outputs
|
|
19
|
+
```
|
|
20
|
+
{{else}}
|
|
21
|
+
*(No initial code generation required for your main stack)*
|
|
22
|
+
{{/if}}
|
|
23
|
+
|
|
24
|
+
### Localization
|
|
25
|
+
{{#if flags.supportsLocalization}}
|
|
26
|
+
Since you chose to include `easy_localization`, run these commands whenever you add or modify string translations to generate your keys correctly:
|
|
27
|
+
```bash
|
|
28
|
+
flutter pub run easy_localization:generate -S assets/translations -O lib/src/core/i18n -o locale_keys.g.dart
|
|
29
|
+
```
|
|
30
|
+
{{else}}
|
|
31
|
+
*(Localization is not enabled for this project)*
|
|
32
|
+
{{/if}}
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. 🎨 Native Splash Screen Setup
|
|
37
|
+
|
|
38
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
39
|
+
This project uses `flutter_native_splash`.
|
|
40
|
+
|
|
41
|
+
**To apply your custom app launch screen:**
|
|
42
|
+
1. Place your transparent splash logo at [`assets/images/splash.png`](assets/images/splash.png).
|
|
43
|
+
2. Open [`flutter_native_splash.yaml`](flutter_native_splash.yaml) in the root of your project.
|
|
44
|
+
3. Uncomment the `image:` paths so it looks like:
|
|
45
|
+
```yaml
|
|
46
|
+
flutter_native_splash:
|
|
47
|
+
color: "#{{theme.primaryColor}}"
|
|
48
|
+
image: assets/images/splash.png
|
|
49
|
+
android_12:
|
|
50
|
+
image: assets/images/splash.png
|
|
51
|
+
icon_background_color: "#{{theme.primaryColor}}"
|
|
52
|
+
```
|
|
53
|
+
4. Apply the native configuration natively by running:
|
|
54
|
+
```bash
|
|
55
|
+
dart run flutter_native_splash:create --path=flutter_native_splash.yaml
|
|
56
|
+
```
|
|
57
|
+
*Note: Run this command every time you change your splash image or background color.*
|
|
58
|
+
{{else}}
|
|
59
|
+
*(Native splash screen generation is disabled for this project)*
|
|
60
|
+
{{/if}}
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 3. 🔐 App Permissions (Android & iOS)
|
|
65
|
+
|
|
66
|
+
Based on your chosen flags (e.g. {{#if flags.usesImagePicker}}Image Picker{{/if}} {{#if flags.usesGeolocator}}, Geolocator{{/if}} {{#if flags.usesFilePicker}}, File Picker{{/if}}), you must configure Native permissions before testing these features.
|
|
67
|
+
|
|
68
|
+
### Android Setup
|
|
69
|
+
Open [`android/app/src/main/AndroidManifest.xml`](android/app/src/main/AndroidManifest.xml) and add the following required permissions inside the `<manifest>` tag, directly above the `<application>` block:
|
|
70
|
+
|
|
71
|
+
```xml
|
|
72
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
73
|
+
<!-- Internet is standard and required -->
|
|
74
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
75
|
+
|
|
76
|
+
{{#if flags.usesImagePicker}}
|
|
77
|
+
<!-- Required for image_picker -->
|
|
78
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
79
|
+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
|
80
|
+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- Android 13+ -->
|
|
81
|
+
{{/if}}
|
|
82
|
+
{{#if flags.usesFilePicker}}
|
|
83
|
+
<!-- Required for file_picker -->
|
|
84
|
+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
85
|
+
{{/if}}
|
|
86
|
+
{{#if flags.usesGeolocator}}
|
|
87
|
+
<!-- Required for geolocator -->
|
|
88
|
+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
89
|
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
90
|
+
{{/if}}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### iOS Setup
|
|
94
|
+
First, describe why you need permissions. Open [`ios/Runner/Info.plist`](ios/Runner/Info.plist) and add the following inside the main `<dict>` block:
|
|
95
|
+
|
|
96
|
+
```xml
|
|
97
|
+
<dict>
|
|
98
|
+
...
|
|
99
|
+
{{#if flags.usesImagePicker}}
|
|
100
|
+
<!-- Required for image_picker -->
|
|
101
|
+
<key>NSCameraUsageDescription</key>
|
|
102
|
+
<string>This app requires access to the camera to take profile photos.</string>
|
|
103
|
+
<key>NSPhotoLibraryUsageDescription</key>
|
|
104
|
+
<string>This app requires access to the photo library to upload images.</string>
|
|
105
|
+
{{/if}}
|
|
106
|
+
{{#if flags.usesFilePicker}}
|
|
107
|
+
<!-- Required for file_picker -->
|
|
108
|
+
<key>NSAppleMusicUsageDescription</key>
|
|
109
|
+
<string>This app requires access to media to upload files.</string>
|
|
110
|
+
{{/if}}
|
|
111
|
+
{{#if flags.usesGeolocator}}
|
|
112
|
+
<!-- Required for geolocator -->
|
|
113
|
+
<key>NSLocationWhenInUseUsageDescription</key>
|
|
114
|
+
<string>This app requires access to location to provide localized content.</string>
|
|
115
|
+
<key>NSLocationAlwaysUsageDescription</key>
|
|
116
|
+
<string>This app requires access to location in the background.</string>
|
|
117
|
+
{{/if}}
|
|
118
|
+
</dict>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
{{#if flags.usesPermissionHandler}}
|
|
122
|
+
**IMPORTANT: Podfile Configuration**
|
|
123
|
+
Since you've enabled `permission_handler`, you **MUST** configure your requested iOS permissions using Podfile macros to comply with App Store rules.
|
|
124
|
+
|
|
125
|
+
Open [`ios/Podfile`](ios/Podfile), find the `post_install` block at the bottom, and replace it completely with this snippet:
|
|
126
|
+
|
|
127
|
+
```ruby
|
|
128
|
+
post_install do |installer|
|
|
129
|
+
installer.pods_project.targets.each do |target|
|
|
130
|
+
flutter_additional_ios_build_settings(target)
|
|
131
|
+
|
|
132
|
+
target.build_configurations.each do |config|
|
|
133
|
+
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
|
134
|
+
'$(inherited)',
|
|
135
|
+
|
|
136
|
+
## dart: PermissionGroup.camera
|
|
137
|
+
'PERMISSION_CAMERA={{#if flags.usesImagePicker}}1{{else}}0{{/if}}',
|
|
138
|
+
|
|
139
|
+
## dart: PermissionGroup.photos
|
|
140
|
+
'PERMISSION_PHOTOS={{#if flags.usesImagePicker}}1{{else}}0{{/if}}',
|
|
141
|
+
|
|
142
|
+
## dart: PermissionGroup.location
|
|
143
|
+
'PERMISSION_LOCATION={{#if flags.usesGeolocator}}1{{else}}0{{/if}}',
|
|
144
|
+
'PERMISSION_LOCATION_WHENINUSE={{#if flags.usesGeolocator}}1{{else}}0{{/if}}',
|
|
145
|
+
|
|
146
|
+
## dart: PermissionGroup.mediaLibrary
|
|
147
|
+
'PERMISSION_MEDIA_LIBRARY={{#if flags.usesFilePicker}}1{{else}}0{{/if}}',
|
|
148
|
+
|
|
149
|
+
## dart: PermissionGroup.microphone (Usually 1 if video recording is active with image_picker)
|
|
150
|
+
'PERMISSION_MICROPHONE={{#if flags.usesImagePicker}}1{{else}}0{{/if}}',
|
|
151
|
+
|
|
152
|
+
## Unused permissions forcefully disabled to avoid App Store Rejection
|
|
153
|
+
'PERMISSION_EVENTS=0',
|
|
154
|
+
'PERMISSION_EVENTS_FULL_ACCESS=0',
|
|
155
|
+
'PERMISSION_REMINDERS=0',
|
|
156
|
+
'PERMISSION_CONTACTS=0',
|
|
157
|
+
'PERMISSION_SPEECH_RECOGNIZER=0',
|
|
158
|
+
'PERMISSION_NOTIFICATIONS=0',
|
|
159
|
+
'PERMISSION_SENSORS=0',
|
|
160
|
+
'PERMISSION_BLUETOOTH=0',
|
|
161
|
+
'PERMISSION_APP_TRACKING_TRANSPARENCY=0',
|
|
162
|
+
'PERMISSION_CRITICAL_ALERTS=0',
|
|
163
|
+
'PERMISSION_ASSISTANT=0',
|
|
164
|
+
]
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
```
|
|
169
|
+
{{/if}}
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 4. 🌍 Environment Variables
|
|
174
|
+
|
|
175
|
+
Your project relies on `flutter_dotenv` to load secrets.
|
|
176
|
+
|
|
177
|
+
1. Create a [`.env`](.env) file in the project root folder.
|
|
178
|
+
2. Insert your required variables (e.g. `API_URL=https://api.example.com`).
|
|
179
|
+
3. These keys are now accessible in Dart via `dotenv.env['API_URL']`.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 5. 💾 Local Storage (Hive)
|
|
184
|
+
|
|
185
|
+
{{#if flags.usesHive}}
|
|
186
|
+
Your project uses **Hive CE** (Community Edition) for high-performance local NoSQL storage.
|
|
187
|
+
|
|
188
|
+
- **Automatic Init:** Hive is automatically initialized at startup in `lib/main.dart`.
|
|
189
|
+
- **Adapters:** When creating custom data models, use `@HiveType` and `@HiveField` annotations.
|
|
190
|
+
- **Generation:** Whenever you add a new Hive adapter, run the [Code Generation](#code-generation) command:
|
|
191
|
+
```bash
|
|
192
|
+
dart run build_runner build --delete-conflicting-outputs
|
|
193
|
+
```
|
|
194
|
+
{{else}}
|
|
195
|
+
*(No local storage (Hive) selected for this project)*
|
|
196
|
+
{{/if}}
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 6. ☁️ Backend Connections
|
|
201
|
+
|
|
202
|
+
{{#if (eq backend.provider "firebase")}}
|
|
203
|
+
You chose **Firebase** as your backend architecture.
|
|
204
|
+
|
|
205
|
+
**Initialize Firebase natively:**
|
|
206
|
+
1. Ensure the [Firebase CLI](https://firebase.google.com/docs/cli) is installed and logged in (`firebase login`).
|
|
207
|
+
2. Run the secure configuration tool:
|
|
208
|
+
```bash
|
|
209
|
+
dart pub global activate flutterfire_cli
|
|
210
|
+
flutterfire configure
|
|
211
|
+
```
|
|
212
|
+
3. This generates `lib/firebase_options.dart`. Your integration is already set up in `lib/src/app.dart` or `lib/main.dart` to securely initialize using this file!
|
|
213
|
+
{{else if (eq backend.provider "supabase")}}
|
|
214
|
+
You chose **Supabase** as your backend architecture.
|
|
215
|
+
|
|
216
|
+
1. Create an empty project at [supabase.com](https://supabase.com/).
|
|
217
|
+
2. Grab your `SUPABASE_URL` and `SUPABASE_ANON_KEY` from your Project API Settings.
|
|
218
|
+
3. Locate the Supabase initialization inside `lib/main.dart` and bind these keys.
|
|
219
|
+
*(Tip: You can securely point these to `dotenv.env['SUPABASE_URL']` from your newly created `.env` file!)*
|
|
220
|
+
{{else if (eq backend.provider "appwrite")}}
|
|
221
|
+
You chose **Appwrite** as your backend architecture.
|
|
222
|
+
|
|
223
|
+
1. Locate the `Appwrite` Initialization code inside `lib/main.dart`.
|
|
224
|
+
2. Ensure you apply your Project ID and Endpoint values to the client configuration.
|
|
225
|
+
*(Tip: You can securely point these to `dotenv.env['APPWRITE_ENDPOINT']`!)*
|
|
226
|
+
{{else if (eq backend.provider "custom")}}
|
|
227
|
+
You chose to structure your APIs using **Custom Backend**.
|
|
228
|
+
|
|
229
|
+
Verify that your Base URL pointing to staging/production is correctly initialized inside your globally injected network class.
|
|
230
|
+
*(Tip: Read this via `dotenv.env['BASE_API_URL']` inside your network initializer!)*
|
|
231
|
+
{{else}}
|
|
232
|
+
*(No remote backend provider selected. The application defaults to managing state via Mock services locally).*
|
|
233
|
+
{{/if}}
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 7. 🚀 Running the App
|
|
238
|
+
|
|
239
|
+
Once everything above is verified:
|
|
240
|
+
|
|
241
|
+
1. **For iOS Simulators/Devices**, map your native pods locally:
|
|
242
|
+
```bash
|
|
243
|
+
cd ios
|
|
244
|
+
pod install
|
|
245
|
+
cd ..
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
2. Run your app via VS Code, Android Studio, or CLI:
|
|
249
|
+
```bash
|
|
250
|
+
flutter run
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Congratulations, and happy coding!
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# This file configures the analyzer, which statically analyzes Dart code to
|
|
2
|
+
# check for errors, warnings, and lints.
|
|
3
|
+
#
|
|
4
|
+
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
|
5
|
+
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
|
6
|
+
# invoked from the command line by running `flutter analyze`.
|
|
7
|
+
|
|
8
|
+
# The following line activates a set of recommended lints for Flutter apps,
|
|
9
|
+
# packages, and plugins designed to encourage good coding practices.
|
|
10
|
+
include: package:flutter_lints/flutter.yaml
|
|
11
|
+
|
|
12
|
+
analyzer:
|
|
13
|
+
errors:
|
|
14
|
+
inference_failure_on_untyped_parameter: ignore
|
|
15
|
+
plugins:
|
|
16
|
+
- custom_lint
|
|
17
|
+
exclude:
|
|
18
|
+
- "**/*.g.dart"
|
|
19
|
+
- "**/*.freezed.dart"
|
|
20
|
+
- "**/*.gr.dart"
|
|
21
|
+
- "**/*.config.dart"
|
|
22
|
+
- "**/generated/**"
|
|
23
|
+
- "**/build/**"
|
|
24
|
+
- "**/.dart_tool/**"
|
|
25
|
+
- "**/ios/Pods/**"
|
|
26
|
+
- "**/android/.gradle/**"
|
|
27
|
+
- "**/android/app/build/**"
|
|
28
|
+
- "**/android/build/**"
|
|
29
|
+
- "**/web/**"
|
|
30
|
+
- "**/test/**"
|
|
31
|
+
- "**/integration_test/**"
|
|
32
|
+
strong-mode:
|
|
33
|
+
implicit-casts: true
|
|
34
|
+
implicit-dynamic: false
|
|
35
|
+
language:
|
|
36
|
+
strict-casts: false
|
|
37
|
+
strict-inference: true
|
|
38
|
+
strict-raw-types: true
|
|
39
|
+
|
|
40
|
+
linter:
|
|
41
|
+
rules:
|
|
42
|
+
prefer_const_constructors: true
|
|
43
|
+
prefer_const_declarations: true
|
|
44
|
+
prefer_const_literals_to_create_immutables: true
|
|
45
|
+
avoid_print: true
|
|
46
|
+
prefer_single_quotes: true
|
|
47
|
+
avoid_unnecessary_containers: true
|
|
48
|
+
avoid_web_libraries_in_flutter: true
|
|
49
|
+
prefer_const_constructors_in_immutables: true
|
|
50
|
+
prefer_final_fields: true
|
|
51
|
+
prefer_final_locals: true
|
|
52
|
+
prefer_final_in_for_each: true
|
|
53
|
+
prefer_for_elements_to_map_fromIterable: true
|
|
54
|
+
prefer_function_declarations_over_variables: true
|
|
55
|
+
prefer_if_elements_to_conditional_expressions: true
|
|
56
|
+
prefer_if_null_operators: true
|
|
57
|
+
prefer_initializing_formals: true
|
|
58
|
+
prefer_inlined_adds: true
|
|
59
|
+
prefer_int_literals: true
|
|
60
|
+
prefer_interpolation_to_compose_strings: true
|
|
61
|
+
prefer_is_empty: true
|
|
62
|
+
prefer_is_not_empty: true
|
|
63
|
+
prefer_is_not_operator: true
|
|
64
|
+
prefer_iterable_whereType: true
|
|
65
|
+
prefer_null_aware_operators: true
|
|
66
|
+
prefer_relative_imports: false
|
|
67
|
+
prefer_typing_uninitialized_variables: true
|
|
68
|
+
sort_child_properties_last: true
|
|
69
|
+
use_build_context_synchronously: true
|
|
70
|
+
use_colored_box: true
|
|
71
|
+
use_decorated_box: true
|
|
72
|
+
use_enums: true
|
|
73
|
+
use_full_hex_values_for_flutter_colors: true
|
|
74
|
+
use_function_type_syntax_for_parameters: true
|
|
75
|
+
use_if_null_to_convert_nulls_to_bools: true
|
|
76
|
+
use_is_even_rather_than_modulo: true
|
|
77
|
+
use_key_in_widget_constructors: true
|
|
78
|
+
use_late_for_private_fields_and_variables: true
|
|
79
|
+
use_named_constants: true
|
|
80
|
+
use_raw_strings: true
|
|
81
|
+
use_rethrow_when_possible: true
|
|
82
|
+
use_setters_to_change_properties: true
|
|
83
|
+
use_string_buffers: true
|
|
84
|
+
use_super_parameters: true
|
|
85
|
+
use_test_throws_matchers: true
|
|
86
|
+
use_to_and_as_if_applicable: true
|
|
87
|
+
valid_regexps: true
|
|
88
|
+
void_checks: true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none"><path fill="#ffffff" fill-rule="evenodd" d="M19.1 19.16c.59-.9.81-1.36 1.26-2.37-3.32-1.26-3.85-5.99-.57-7.8-1-1.26-2.41-1.99-3.74-1.99-.96 0-1.62.25-2.21.48-.5.19-.95.36-1.51.36-.6 0-1.13-.19-1.69-.39C10.03 7.23 9.39 7 8.59 7 7.1 7 5.51 7.91 4.5 9.47c-1.42 2.2-1.17 6.32 1.12 9.84.82 1.26 1.92 2.67 3.35 2.69.6.01.99-.17 1.42-.36.49-.22 1.02-.46 1.95-.46.93-.01 1.45.24 1.94.46.42.19.8.37 1.39.36 1.45-.02 2.61-1.58 3.43-2.84zM15.84 2c.16 1.1-.29 2.19-.88 2.95-.63.82-1.73 1.46-2.79 1.42-.19-1.06.3-2.15.9-2.88.67-.8 1.8-1.42 2.77-1.49z" clip-rule="evenodd"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none"><path fill="#ffffff" d="M22 16.19c0 3.64-2.17 5.81-5.81 5.81H15c-.55 0-1-.45-1-1v-5.77c0-.27.22-.5.49-.5l1.76-.03c.14-.01.26-.11.29-.25l.35-1.91a.303.303 0 00-.3-.35l-2.13.03c-.28 0-.5-.22-.51-.49l-.04-2.45c0-.16.13-.3.3-.3l2.4-.04c.17 0 .3-.13.3-.3l-.04-2.4c0-.17-.13-.3-.3-.3l-2.7.04a2.996 2.996 0 00-2.95 3.05l.05 2.75c.01.28-.21.5-.49.51l-1.2.02c-.17 0-.3.13-.3.3l.03 1.9c0 .17.13.3.3.3l1.2-.02c.28 0 .5.22.51.49l.09 5.7c.01.56-.44 1.02-1 1.02h-2.3C4.17 22 2 19.83 2 16.18V7.81C2 4.17 4.17 2 7.81 2h8.38C19.83 2 22 4.17 22 7.81v8.38z"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none"><path fill="#ffffff" d="M21.74 11.07a.989.989 0 00-.99-.89H13.2c-.55 0-1 .45-1 1v1.71c0 .55.45 1 1 1h4.51c-.11.92-.71 2.31-2.04 3.24-.85.59-1.98 1-3.47 1-.07 0-.13 0-.2-.01-2.55-.08-4.71-1.79-5.49-4.14A6.23 6.23 0 016.18 12c0-.69.12-1.36.32-1.98.06-.18.13-.36.21-.54.92-2.07 2.93-3.53 5.29-3.6.06-.01.13-.01.2-.01 1.43 0 2.5.47 3.25.99.39.27.91.21 1.25-.12l1.39-1.36c.44-.43.4-1.16-.1-1.52C16.4 2.69 14.46 2 12.2 2c-.07 0-.13 0-.2.01a9.96 9.96 0 00-8.73 5.5C2.59 8.87 2.2 10.39 2.2 12c0 1.61.39 3.13 1.07 4.49h.01a9.956 9.956 0 008.72 5.5c.07.01.13.01.2.01 2.7 0 4.97-.89 6.62-2.42 1.89-1.75 2.98-4.31 2.98-7.36 0-.43-.02-.8-.06-1.15z"></path></svg>
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import 'src/imports/core_imports.dart';
|
|
2
|
+
import 'src/imports/packages_imports.dart';
|
|
3
|
+
{{#if extras.flavors}}
|
|
4
|
+
import 'src/flavors.dart';
|
|
5
|
+
{{/if}}
|
|
6
|
+
import 'src/app.dart';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Future<void> main() async {
|
|
10
|
+
{{#if flags.usesFlutterNativeSplash}}
|
|
11
|
+
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
|
12
|
+
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
|
13
|
+
{{else}}
|
|
14
|
+
WidgetsFlutterBinding.ensureInitialized();
|
|
15
|
+
{{/if}}
|
|
16
|
+
|
|
17
|
+
{{#if flags.supportsLocalization}}
|
|
18
|
+
await EasyLocalization.ensureInitialized();
|
|
19
|
+
{{/if}}
|
|
20
|
+
await dotenv.load(fileName: '.env');
|
|
21
|
+
{{#if extras.flavors}}
|
|
22
|
+
FlavorConfig.load(Flavor.dev);
|
|
23
|
+
{{/if}}
|
|
24
|
+
|
|
25
|
+
await AppConfig.init();
|
|
26
|
+
{{#if flags.usesHive}}
|
|
27
|
+
await HiveService.instance.init();
|
|
28
|
+
{{/if}}
|
|
29
|
+
|
|
30
|
+
runApp(
|
|
31
|
+
{{#if flags.supportsLocalization}}
|
|
32
|
+
const LocalizationWrapper(
|
|
33
|
+
child: {{#if (eq stateManagement "none")}}App(){{else}}StateWrapper(
|
|
34
|
+
child: App(),
|
|
35
|
+
){{/if}},
|
|
36
|
+
),
|
|
37
|
+
{{else}}
|
|
38
|
+
{{#if (eq stateManagement "none")}}const App(){{else}}const StateWrapper(
|
|
39
|
+
child: App(),
|
|
40
|
+
){{/if}},
|
|
41
|
+
{{/if}}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import 'package:{{flags.appSnake}}/src/imports/core_imports.dart';
|
|
2
|
+
|
|
3
|
+
class App extends StatelessWidget {
|
|
4
|
+
const App({super.key});
|
|
5
|
+
|
|
6
|
+
@override
|
|
7
|
+
Widget build(BuildContext context) {
|
|
8
|
+
final current = {{#if flags.isCupertino}}_buildCupertinoApp(context){{else}}_buildMaterialApp(context){{/if}};
|
|
9
|
+
{{#if flags.usesScreenutil}}
|
|
10
|
+
return ScreenUtilWrapper(child: current);
|
|
11
|
+
{{else}}
|
|
12
|
+
return current;
|
|
13
|
+
{{/if}}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
{{#if flags.isCupertino}}
|
|
17
|
+
Widget _buildCupertinoApp(BuildContext context) {
|
|
18
|
+
return {{#if flags.isGetX}}GetCupertinoApp{{else}}CupertinoApp{{/if}}{{#if (and flags.routerPackage (not flags.isGetX))}}.router{{/if}}(
|
|
19
|
+
{{#if flags.isGetX}}
|
|
20
|
+
initialBinding: AppBindings(),
|
|
21
|
+
{{/if}}
|
|
22
|
+
{{#unless flags.routerPackage}}
|
|
23
|
+
navigatorKey: rootNavigatorKey,
|
|
24
|
+
{{/unless}}
|
|
25
|
+
title: '{{appName}}',
|
|
26
|
+
debugShowCheckedModeBanner: false,
|
|
27
|
+
theme: buildCupertinoTheme(primaryColorHex: '{{theme.primaryColor}}'),
|
|
28
|
+
{{#if (eq flags.routerPackage "getx")}}
|
|
29
|
+
initialRoute: AppRoutes.onboarding,
|
|
30
|
+
getPages: AppRouter.getPages,
|
|
31
|
+
{{else if flags.routerPackage}}
|
|
32
|
+
routerConfig: {{#if (eq flags.routerPackage "go_router")}}appRouter{{else}}AppRouter().config(){{/if}},
|
|
33
|
+
{{else}}
|
|
34
|
+
home: const OnboardingPage(),
|
|
35
|
+
onGenerateRoute: AppRouter.onGenerateRoute,
|
|
36
|
+
{{/if}}
|
|
37
|
+
{{#if flags.supportsLocalization}}
|
|
38
|
+
localizationsDelegates: context.localizationDelegates,
|
|
39
|
+
supportedLocales: context.supportedLocales,
|
|
40
|
+
locale: context.locale,
|
|
41
|
+
{{/if}}
|
|
42
|
+
builder: (context, child) {
|
|
43
|
+
Widget current = child!;
|
|
44
|
+
{{#if flags.usesSkeletonizer}}
|
|
45
|
+
current = SkeletonWrapper(child: current);
|
|
46
|
+
{{/if}}
|
|
47
|
+
current = SessionListenerWrapper(child: current);
|
|
48
|
+
|
|
49
|
+
// Ensure Material themes (tokens, widget styles like dialogs/buttons/inputs)
|
|
50
|
+
// are available even in Cupertino mode, as many apps use a mix of both.
|
|
51
|
+
{{#if flags.isCupertino}}
|
|
52
|
+
current = Theme(
|
|
53
|
+
data: {{#if flags.hasDarkMode}}{{#if theme.darkMode.system}}(MediaQuery.of(context).platformBrightness == Brightness.dark){{else}}true{{/if}}{{else}}false{{/if}}
|
|
54
|
+
? buildDarkTheme(primaryColorHex: '{{theme.primaryColor}}')
|
|
55
|
+
: buildLightTheme(primaryColorHex: '{{theme.primaryColor}}'),
|
|
56
|
+
child: current,
|
|
57
|
+
);
|
|
58
|
+
{{/if}}
|
|
59
|
+
|
|
60
|
+
return current;
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
{{else}}
|
|
65
|
+
Widget _buildMaterialApp(BuildContext context) {
|
|
66
|
+
return {{#if flags.isGetX}}GetMaterialApp{{else}}MaterialApp{{/if}}{{#if (and flags.routerPackage (not (eq flags.routerPackage "getx")))}}.router{{/if}}(
|
|
67
|
+
{{#if flags.isGetX}}
|
|
68
|
+
initialBinding: AppBindings(),
|
|
69
|
+
{{/if}}
|
|
70
|
+
{{#unless flags.routerPackage}}
|
|
71
|
+
navigatorKey: rootNavigatorKey,
|
|
72
|
+
{{/unless}}
|
|
73
|
+
title: '{{appName}}',
|
|
74
|
+
debugShowCheckedModeBanner: false,
|
|
75
|
+
theme: buildLightTheme(primaryColorHex: '{{theme.primaryColor}}'),
|
|
76
|
+
{{#if flags.hasDarkMode}}
|
|
77
|
+
darkTheme: buildDarkTheme(primaryColorHex: '{{theme.primaryColor}}'),
|
|
78
|
+
themeMode: {{#if theme.darkMode.system}}ThemeMode.system{{else}}ThemeMode.dark{{/if}},
|
|
79
|
+
{{/if}}
|
|
80
|
+
{{#if (eq flags.routerPackage "getx")}}
|
|
81
|
+
initialRoute: AppRoutes.onboarding,
|
|
82
|
+
getPages: AppRouter.getPages,
|
|
83
|
+
{{else if flags.routerPackage}}
|
|
84
|
+
routerConfig: {{#if (eq flags.routerPackage "go_router")}}appRouter{{else}}AppRouter().config(){{/if}},
|
|
85
|
+
{{else}}
|
|
86
|
+
home: const OnboardingPage(),
|
|
87
|
+
onGenerateRoute: AppRouter.onGenerateRoute,
|
|
88
|
+
{{/if}}
|
|
89
|
+
{{#if flags.supportsLocalization}}
|
|
90
|
+
localizationsDelegates: context.localizationDelegates,
|
|
91
|
+
supportedLocales: context.supportedLocales,
|
|
92
|
+
locale: context.locale,
|
|
93
|
+
{{/if}}
|
|
94
|
+
builder: (context, child) {
|
|
95
|
+
Widget current = child!;
|
|
96
|
+
{{#if flags.usesSkeletonizer}}
|
|
97
|
+
current = SkeletonWrapper(child: current);
|
|
98
|
+
{{/if}}
|
|
99
|
+
current = SessionListenerWrapper(child: current);
|
|
100
|
+
return current;
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
{{/if}}
|
|
105
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{{#if flags.usesDio}}
|
|
2
|
+
import '../imports/core_imports.dart';
|
|
3
|
+
{{/if}}
|
|
4
|
+
{{#if flags.usesDio}}
|
|
5
|
+
import 'package:dio/dio.dart';
|
|
6
|
+
{{/if}}
|
|
7
|
+
{{#if flags.usesHttp}}
|
|
8
|
+
import 'package:http/http.dart' as http;
|
|
9
|
+
{{/if}}
|
|
10
|
+
{{#if (eq backend.provider "firebase")}}
|
|
11
|
+
import 'package:firebase_core/firebase_core.dart';
|
|
12
|
+
import 'package:firebase_auth/firebase_auth.dart';
|
|
13
|
+
{{#if backend.options.firestore}}import 'package:cloud_firestore/cloud_firestore.dart';{{/if}}
|
|
14
|
+
{{#if backend.options.realtimeDb}}import 'package:firebase_database/firebase_database.dart';{{/if}}
|
|
15
|
+
{{#if backend.options.storage}}import 'package:firebase_storage/firebase_storage.dart';{{/if}}
|
|
16
|
+
{{/if}}
|
|
17
|
+
{{#if (eq backend.provider "supabase")}}
|
|
18
|
+
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
19
|
+
{{/if}}
|
|
20
|
+
{{#if (eq backend.provider "appwrite")}}
|
|
21
|
+
import 'package:appwrite/appwrite.dart';
|
|
22
|
+
{{/if}}
|
|
23
|
+
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
24
|
+
|
|
25
|
+
class AppConfig {
|
|
26
|
+
AppConfig._();
|
|
27
|
+
{{#if flags.usesDio}}
|
|
28
|
+
static late final Dio dio;
|
|
29
|
+
{{/if}}
|
|
30
|
+
{{#if flags.usesHttp}}
|
|
31
|
+
static late final http.Client httpClient;
|
|
32
|
+
{{/if}}
|
|
33
|
+
{{#if (eq backend.provider "supabase")}}
|
|
34
|
+
static late final SupabaseClient supabase;
|
|
35
|
+
{{/if}}
|
|
36
|
+
{{#if (eq backend.provider "appwrite")}}
|
|
37
|
+
static late final Client appwriteClient;
|
|
38
|
+
static late final Account appwriteAccount;
|
|
39
|
+
{{/if}}
|
|
40
|
+
{{#if (eq backend.provider "firebase")}}
|
|
41
|
+
static FirebaseAuth get firebaseAuth => FirebaseAuth.instance;
|
|
42
|
+
{{#if backend.options.firestore}}
|
|
43
|
+
static FirebaseFirestore get firestore => FirebaseFirestore.instance;
|
|
44
|
+
{{/if}}
|
|
45
|
+
{{#if backend.options.realtimeDb}}
|
|
46
|
+
static FirebaseDatabase get realtimeDb => FirebaseDatabase.instance;
|
|
47
|
+
{{/if}}
|
|
48
|
+
{{#if backend.options.storage}}
|
|
49
|
+
static FirebaseStorage get storage => FirebaseStorage.instance;
|
|
50
|
+
{{/if}}
|
|
51
|
+
{{/if}}
|
|
52
|
+
|
|
53
|
+
static String get baseUrl => _getBaseUrl();
|
|
54
|
+
|
|
55
|
+
static Future<void> init() async {
|
|
56
|
+
{{#if (eq backend.provider "firebase")}}
|
|
57
|
+
await Firebase.initializeApp();
|
|
58
|
+
{{/if}}
|
|
59
|
+
{{#if (eq backend.provider "supabase")}}
|
|
60
|
+
await Supabase.initialize(
|
|
61
|
+
url: dotenv.get('SUPABASE_URL', fallback: 'https://YOUR-PROJECT.supabase.co'),
|
|
62
|
+
publishableKey: dotenv.get('SUPABASE_ANON_KEY', fallback: 'YOUR-ANON-KEY'),
|
|
63
|
+
);
|
|
64
|
+
supabase = Supabase.instance.client;
|
|
65
|
+
{{/if}}
|
|
66
|
+
{{#if (eq backend.provider "appwrite")}}
|
|
67
|
+
appwriteClient = Client()
|
|
68
|
+
..setEndpoint(dotenv.get('APPWRITE_ENDPOINT', fallback: 'https://cloud.appwrite.io/v1'))
|
|
69
|
+
..setProject(dotenv.get('APPWRITE_PROJECT_ID', fallback: 'your-project-id'))
|
|
70
|
+
..setSelfSigned(status: true);
|
|
71
|
+
appwriteAccount = Account(appwriteClient);
|
|
72
|
+
{{/if}}
|
|
73
|
+
{{#if flags.usesDio}}
|
|
74
|
+
dio = Dio(
|
|
75
|
+
BaseOptions(
|
|
76
|
+
baseUrl: _getBaseUrl(),
|
|
77
|
+
connectTimeout: const Duration(seconds: 30),
|
|
78
|
+
receiveTimeout: const Duration(seconds: 30),
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
'Accept': 'application/json',
|
|
82
|
+
},
|
|
83
|
+
),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
dio.interceptors.add(
|
|
87
|
+
InterceptorsWrapper(
|
|
88
|
+
onRequest: (options, handler) {
|
|
89
|
+
AppLogger.info('🌐 [DIO] REQUEST[${options.method}] => PATH: ${options.path}');
|
|
90
|
+
return handler.next(options);
|
|
91
|
+
},
|
|
92
|
+
onResponse: (response, handler) {
|
|
93
|
+
AppLogger.info('✅ [DIO] RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
|
|
94
|
+
return handler.next(response);
|
|
95
|
+
},
|
|
96
|
+
onError: (DioException e, handler) {
|
|
97
|
+
AppLogger.error('❌ [DIO] ERROR[${e.response?.statusCode}] => PATH: ${e.requestOptions.path}');
|
|
98
|
+
return handler.next(e);
|
|
99
|
+
},
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
{{/if}}
|
|
103
|
+
|
|
104
|
+
{{#if flags.usesHttp}}
|
|
105
|
+
httpClient = http.Client();
|
|
106
|
+
{{/if}}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static String _getBaseUrl() {
|
|
110
|
+
return dotenv.get('API_BASE_URL', fallback: '{{#if (eq backend.provider "custom")}}{{backend.options.baseUrl}}{{else}}https://api.example.com{{/if}}');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import 'package:flutter/widgets.dart';
|
|
2
|
+
|
|
3
|
+
extension IterableExtension<T> on Iterable<T> {
|
|
4
|
+
// Safe accessors
|
|
5
|
+
T? get firstOrNull => isEmpty ? null : first;
|
|
6
|
+
T? get lastOrNull => isEmpty ? null : last;
|
|
7
|
+
|
|
8
|
+
// Iteration
|
|
9
|
+
Iterable<E> mapIndexed<E>(E Function(int index, T item) f) {
|
|
10
|
+
var i = 0;
|
|
11
|
+
return map((e) => f(i++, e));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Data manipulation
|
|
15
|
+
Map<K, List<T>> groupBy<K>(K Function(T item) keySelector) {
|
|
16
|
+
final groups = <K, List<T>>{};
|
|
17
|
+
for (final item in this) {
|
|
18
|
+
final key = keySelector(item);
|
|
19
|
+
groups.putIfAbsent(key, () => []).add(item);
|
|
20
|
+
}
|
|
21
|
+
return groups;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Iterable<List<T>> chunk(int size) {
|
|
25
|
+
if (size <= 0) return [toList()];
|
|
26
|
+
final chunks = <List<T>>[];
|
|
27
|
+
final list = toList();
|
|
28
|
+
for (var i = 0; i < list.length; i += size) {
|
|
29
|
+
chunks.add(list.sublist(i, i + size > list.length ? list.length : i + size));
|
|
30
|
+
}
|
|
31
|
+
return chunks;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
List<T> get distinct => toSet().toList();
|
|
35
|
+
|
|
36
|
+
List<T> distinctBy(Object Function(T item) keySelector) {
|
|
37
|
+
final seen = <Object>{};
|
|
38
|
+
return where((item) => seen.add(keySelector(item))).toList();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
extension ListWidgetExtension on List<Widget> {
|
|
43
|
+
// UI Helpers
|
|
44
|
+
List<Widget> separatedBy(Widget separator) {
|
|
45
|
+
if (isEmpty) return [];
|
|
46
|
+
final result = <Widget>[];
|
|
47
|
+
for (var i = 0; i < length; i++) {
|
|
48
|
+
result.add(this[i]);
|
|
49
|
+
if (i < length - 1) {
|
|
50
|
+
result.add(separator);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
}
|