maxsim-flutter 1.0.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/CHANGELOG.md +42 -0
- package/LICENSE +21 -0
- package/README.md +445 -0
- package/claude-plugin/.claude-plugin/plugin.json +46 -0
- package/claude-plugin/agents/flutter-setup-agent.md +54 -0
- package/claude-plugin/commands/flutter-add.md +32 -0
- package/claude-plugin/commands/flutter-create.md +28 -0
- package/claude-plugin/commands/flutter-migrate.md +28 -0
- package/claude-plugin/skills/flutter-scaffolding/SKILL.md +109 -0
- package/dist/claude-setup/agent-writer.d.ts +21 -0
- package/dist/claude-setup/agent-writer.d.ts.map +1 -0
- package/dist/claude-setup/agent-writer.js +365 -0
- package/dist/claude-setup/agent-writer.js.map +1 -0
- package/dist/claude-setup/claude-md-generator.d.ts +7 -0
- package/dist/claude-setup/claude-md-generator.d.ts.map +1 -0
- package/dist/claude-setup/claude-md-generator.js +428 -0
- package/dist/claude-setup/claude-md-generator.js.map +1 -0
- package/dist/claude-setup/commands-writer.d.ts +7 -0
- package/dist/claude-setup/commands-writer.d.ts.map +1 -0
- package/dist/claude-setup/commands-writer.js +303 -0
- package/dist/claude-setup/commands-writer.js.map +1 -0
- package/dist/claude-setup/hooks-writer.d.ts +3 -0
- package/dist/claude-setup/hooks-writer.d.ts.map +1 -0
- package/dist/claude-setup/hooks-writer.js +34 -0
- package/dist/claude-setup/hooks-writer.js.map +1 -0
- package/dist/claude-setup/index.d.ts +10 -0
- package/dist/claude-setup/index.d.ts.map +1 -0
- package/dist/claude-setup/index.js +9 -0
- package/dist/claude-setup/index.js.map +1 -0
- package/dist/claude-setup/mcp-config-writer.d.ts +3 -0
- package/dist/claude-setup/mcp-config-writer.d.ts.map +1 -0
- package/dist/claude-setup/mcp-config-writer.js +42 -0
- package/dist/claude-setup/mcp-config-writer.js.map +1 -0
- package/dist/claude-setup/plugin-assembler.d.ts +2 -0
- package/dist/claude-setup/plugin-assembler.d.ts.map +1 -0
- package/dist/claude-setup/plugin-assembler.js +3 -0
- package/dist/claude-setup/plugin-assembler.js.map +1 -0
- package/dist/claude-setup/prd-generator.d.ts +10 -0
- package/dist/claude-setup/prd-generator.d.ts.map +1 -0
- package/dist/claude-setup/prd-generator.js +295 -0
- package/dist/claude-setup/prd-generator.js.map +1 -0
- package/dist/claude-setup/setup-orchestrator.d.ts +11 -0
- package/dist/claude-setup/setup-orchestrator.d.ts.map +1 -0
- package/dist/claude-setup/setup-orchestrator.js +46 -0
- package/dist/claude-setup/setup-orchestrator.js.map +1 -0
- package/dist/claude-setup/skill-writer.d.ts +3 -0
- package/dist/claude-setup/skill-writer.d.ts.map +1 -0
- package/dist/claude-setup/skill-writer.js +256 -0
- package/dist/claude-setup/skill-writer.js.map +1 -0
- package/dist/cli/commands/add.d.ts +16 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +414 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/create.d.ts +3 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +161 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/list.d.ts +12 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +148 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +3 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +332 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +34 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/prompts.d.ts +9 -0
- package/dist/cli/ui/prompts.d.ts.map +1 -0
- package/dist/cli/ui/prompts.js +74 -0
- package/dist/cli/ui/prompts.js.map +1 -0
- package/dist/cli/ui/spinner.d.ts +2 -0
- package/dist/cli/ui/spinner.d.ts.map +1 -0
- package/dist/cli/ui/spinner.js +5 -0
- package/dist/cli/ui/spinner.js.map +1 -0
- package/dist/cli/version-check.d.ts +7 -0
- package/dist/cli/version-check.d.ts.map +1 -0
- package/dist/cli/version-check.js +92 -0
- package/dist/cli/version-check.js.map +1 -0
- package/dist/core/config/defaults.d.ts +3 -0
- package/dist/core/config/defaults.d.ts.map +1 -0
- package/dist/core/config/defaults.js +21 -0
- package/dist/core/config/defaults.js.map +1 -0
- package/dist/core/config/loader.d.ts +4 -0
- package/dist/core/config/loader.d.ts.map +1 -0
- package/dist/core/config/loader.js +38 -0
- package/dist/core/config/loader.js.map +1 -0
- package/dist/core/config/schema.d.ts +406 -0
- package/dist/core/config/schema.d.ts.map +1 -0
- package/dist/core/config/schema.js +119 -0
- package/dist/core/config/schema.js.map +1 -0
- package/dist/core/context.d.ts +57 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +99 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/detector.d.ts +28 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +200 -0
- package/dist/core/detector.js.map +1 -0
- package/dist/core/validator.d.ts +7 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +35 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/composer.d.ts +50 -0
- package/dist/modules/composer.d.ts.map +1 -0
- package/dist/modules/composer.js +122 -0
- package/dist/modules/composer.js.map +1 -0
- package/dist/modules/definitions/analytics/module.d.ts +7 -0
- package/dist/modules/definitions/analytics/module.d.ts.map +1 -0
- package/dist/modules/definitions/analytics/module.js +28 -0
- package/dist/modules/definitions/analytics/module.js.map +1 -0
- package/dist/modules/definitions/api/module.d.ts +7 -0
- package/dist/modules/definitions/api/module.d.ts.map +1 -0
- package/dist/modules/definitions/api/module.js +41 -0
- package/dist/modules/definitions/api/module.js.map +1 -0
- package/dist/modules/definitions/auth/module.d.ts +7 -0
- package/dist/modules/definitions/auth/module.d.ts.map +1 -0
- package/dist/modules/definitions/auth/module.js +53 -0
- package/dist/modules/definitions/auth/module.js.map +1 -0
- package/dist/modules/definitions/cicd/module.d.ts +7 -0
- package/dist/modules/definitions/cicd/module.d.ts.map +1 -0
- package/dist/modules/definitions/cicd/module.js +34 -0
- package/dist/modules/definitions/cicd/module.js.map +1 -0
- package/dist/modules/definitions/core/module.d.ts +7 -0
- package/dist/modules/definitions/core/module.d.ts.map +1 -0
- package/dist/modules/definitions/core/module.js +31 -0
- package/dist/modules/definitions/core/module.js.map +1 -0
- package/dist/modules/definitions/database/module.d.ts +8 -0
- package/dist/modules/definitions/database/module.d.ts.map +1 -0
- package/dist/modules/definitions/database/module.js +47 -0
- package/dist/modules/definitions/database/module.js.map +1 -0
- package/dist/modules/definitions/deep-linking/module.d.ts +7 -0
- package/dist/modules/definitions/deep-linking/module.d.ts.map +1 -0
- package/dist/modules/definitions/deep-linking/module.js +48 -0
- package/dist/modules/definitions/deep-linking/module.js.map +1 -0
- package/dist/modules/definitions/i18n/module.d.ts +7 -0
- package/dist/modules/definitions/i18n/module.d.ts.map +1 -0
- package/dist/modules/definitions/i18n/module.js +37 -0
- package/dist/modules/definitions/i18n/module.js.map +1 -0
- package/dist/modules/definitions/push/module.d.ts +7 -0
- package/dist/modules/definitions/push/module.d.ts.map +1 -0
- package/dist/modules/definitions/push/module.js +40 -0
- package/dist/modules/definitions/push/module.js.map +1 -0
- package/dist/modules/definitions/theme/module.d.ts +7 -0
- package/dist/modules/definitions/theme/module.d.ts.map +1 -0
- package/dist/modules/definitions/theme/module.js +42 -0
- package/dist/modules/definitions/theme/module.js.map +1 -0
- package/dist/modules/registry.d.ts +50 -0
- package/dist/modules/registry.d.ts.map +1 -0
- package/dist/modules/registry.js +104 -0
- package/dist/modules/registry.js.map +1 -0
- package/dist/modules/resolver.d.ts +42 -0
- package/dist/modules/resolver.d.ts.map +1 -0
- package/dist/modules/resolver.js +140 -0
- package/dist/modules/resolver.js.map +1 -0
- package/dist/ralph/prd-generator.d.ts +2 -0
- package/dist/ralph/prd-generator.d.ts.map +1 -0
- package/dist/ralph/prd-generator.js +3 -0
- package/dist/ralph/prd-generator.js.map +1 -0
- package/dist/ralph/ralph-converter.d.ts +2 -0
- package/dist/ralph/ralph-converter.d.ts.map +1 -0
- package/dist/ralph/ralph-converter.js +3 -0
- package/dist/ralph/ralph-converter.js.map +1 -0
- package/dist/ralph/story-sizer.d.ts +2 -0
- package/dist/ralph/story-sizer.d.ts.map +1 -0
- package/dist/ralph/story-sizer.js +3 -0
- package/dist/ralph/story-sizer.js.map +1 -0
- package/dist/scaffold/engine.d.ts +40 -0
- package/dist/scaffold/engine.d.ts.map +1 -0
- package/dist/scaffold/engine.js +233 -0
- package/dist/scaffold/engine.js.map +1 -0
- package/dist/scaffold/file-writer.d.ts +22 -0
- package/dist/scaffold/file-writer.d.ts.map +1 -0
- package/dist/scaffold/file-writer.js +68 -0
- package/dist/scaffold/file-writer.js.map +1 -0
- package/dist/scaffold/post-processors/build-runner.d.ts +2 -0
- package/dist/scaffold/post-processors/build-runner.d.ts.map +1 -0
- package/dist/scaffold/post-processors/build-runner.js +5 -0
- package/dist/scaffold/post-processors/build-runner.js.map +1 -0
- package/dist/scaffold/post-processors/dart-format.d.ts +2 -0
- package/dist/scaffold/post-processors/dart-format.d.ts.map +1 -0
- package/dist/scaffold/post-processors/dart-format.js +5 -0
- package/dist/scaffold/post-processors/dart-format.js.map +1 -0
- package/dist/scaffold/post-processors/flutter-pub-get.d.ts +2 -0
- package/dist/scaffold/post-processors/flutter-pub-get.d.ts.map +1 -0
- package/dist/scaffold/post-processors/flutter-pub-get.js +5 -0
- package/dist/scaffold/post-processors/flutter-pub-get.js.map +1 -0
- package/dist/scaffold/renderer.d.ts +20 -0
- package/dist/scaffold/renderer.d.ts.map +1 -0
- package/dist/scaffold/renderer.js +75 -0
- package/dist/scaffold/renderer.js.map +1 -0
- package/dist/scaffold/template-helpers.d.ts +25 -0
- package/dist/scaffold/template-helpers.d.ts.map +1 -0
- package/dist/scaffold/template-helpers.js +115 -0
- package/dist/scaffold/template-helpers.js.map +1 -0
- package/dist/types/config.d.ts +4 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/module.d.ts +85 -0
- package/dist/types/module.d.ts.map +1 -0
- package/dist/types/module.js +2 -0
- package/dist/types/module.js.map +1 -0
- package/dist/types/project.d.ts +13 -0
- package/dist/types/project.d.ts.map +1 -0
- package/dist/types/project.js +2 -0
- package/dist/types/project.js.map +1 -0
- package/package.json +80 -0
- package/templates/core/analysis_options.yaml.hbs +21 -0
- package/templates/core/lib/app.dart.hbs +20 -0
- package/templates/core/lib/core/providers/app_providers.dart.hbs +3 -0
- package/templates/core/lib/core/router/app_router.dart.hbs +19 -0
- package/templates/core/lib/core/theme/app_theme.dart.hbs +15 -0
- package/templates/core/lib/features/home/data/models/.gitkeep +0 -0
- package/templates/core/lib/features/home/data/repositories/.gitkeep +0 -0
- package/templates/core/lib/features/home/domain/entities/.gitkeep +0 -0
- package/templates/core/lib/features/home/domain/repositories/.gitkeep +0 -0
- package/templates/core/lib/features/home/presentation/pages/home_page.dart.hbs +18 -0
- package/templates/core/lib/features/home/presentation/widgets/.gitkeep +0 -0
- package/templates/core/lib/main.dart.hbs +11 -0
- package/templates/core/pubspec.yaml.hbs +30 -0
- package/templates/core/test/widget_test.dart.hbs +16 -0
- package/templates/modules/analytics/lib/features/analytics/data/observers/analytics_route_observer.dart.hbs +53 -0
- package/templates/modules/analytics/lib/features/analytics/data/services/firebase_analytics_service.dart.hbs +39 -0
- package/templates/modules/analytics/lib/features/analytics/domain/services/analytics_service.dart.hbs +25 -0
- package/templates/modules/analytics/lib/features/analytics/presentation/providers/analytics_provider.dart.hbs +17 -0
- package/templates/modules/analytics/pubspec.partial.yaml +2 -0
- package/templates/modules/api/lib/features/api/data/datasources/api_client.dart.hbs +171 -0
- package/templates/modules/api/lib/features/api/data/interceptors/auth_interceptor.dart.hbs +25 -0
- package/templates/modules/api/lib/features/api/data/interceptors/retry_interceptor.dart.hbs +42 -0
- package/templates/modules/api/lib/features/api/data/repositories/api_repository_impl.dart.hbs +21 -0
- package/templates/modules/api/lib/features/api/domain/exceptions/api_exception.dart.hbs +31 -0
- package/templates/modules/api/lib/features/api/domain/repositories/api_repository.dart.hbs +8 -0
- package/templates/modules/api/lib/features/api/presentation/providers/api_provider.dart.hbs +17 -0
- package/templates/modules/api/pubspec.partial.yaml +7 -0
- package/templates/modules/auth/lib/features/auth/data/datasources/auth_remote_datasource.dart.hbs +181 -0
- package/templates/modules/auth/lib/features/auth/data/models/auth_user_model.dart.hbs +27 -0
- package/templates/modules/auth/lib/features/auth/data/repositories/auth_repository_impl.dart.hbs +49 -0
- package/templates/modules/auth/lib/features/auth/domain/entities/user_entity.dart.hbs +18 -0
- package/templates/modules/auth/lib/features/auth/domain/repositories/auth_repository.dart.hbs +22 -0
- package/templates/modules/auth/lib/features/auth/domain/usecases/register_usecase.dart.hbs +20 -0
- package/templates/modules/auth/lib/features/auth/domain/usecases/sign_in_usecase.dart.hbs +15 -0
- package/templates/modules/auth/lib/features/auth/domain/usecases/sign_out_usecase.dart.hbs +11 -0
- package/templates/modules/auth/lib/features/auth/presentation/pages/login_page.dart.hbs +118 -0
- package/templates/modules/auth/lib/features/auth/presentation/pages/register_page.dart.hbs +131 -0
- package/templates/modules/auth/lib/features/auth/presentation/providers/auth_provider.dart.hbs +31 -0
- package/templates/modules/auth/pubspec.partial.yaml +13 -0
- package/templates/modules/cicd/.github/workflows/ci.yml.hbs +45 -0
- package/templates/modules/cicd/.gitlab-ci.yml.hbs +53 -0
- package/templates/modules/cicd/bitbucket-pipelines.yml.hbs +39 -0
- package/templates/modules/cicd/pubspec.partial.yaml +1 -0
- package/templates/modules/database/lib/features/database/data/datasources/database_datasource.dart.hbs +115 -0
- package/templates/modules/database/lib/features/database/data/repositories/database_repository_impl.dart.hbs +73 -0
- package/templates/modules/database/lib/features/database/domain/repositories/database_repository.dart.hbs +10 -0
- package/templates/modules/database/lib/features/database/presentation/providers/database_provider.dart.hbs +43 -0
- package/templates/modules/database/pubspec.partial.yaml +27 -0
- package/templates/modules/deep-linking/lib/features/deep_linking/data/datasources/deep_link_datasource.dart.hbs +18 -0
- package/templates/modules/deep-linking/lib/features/deep_linking/data/repositories/deep_link_repository_impl.dart.hbs +14 -0
- package/templates/modules/deep-linking/lib/features/deep_linking/domain/repositories/deep_link_repository.dart.hbs +7 -0
- package/templates/modules/deep-linking/lib/features/deep_linking/presentation/providers/deep_link_provider.dart.hbs +57 -0
- package/templates/modules/deep-linking/pubspec.partial.yaml +2 -0
- package/templates/modules/i18n/l10n.yaml.hbs +5 -0
- package/templates/modules/i18n/lib/core/l10n/l10n_config.dart.hbs +29 -0
- package/templates/modules/i18n/lib/core/l10n/l10n_provider.dart.hbs +20 -0
- package/templates/modules/i18n/lib/l10n/app_de.arb.hbs +27 -0
- package/templates/modules/i18n/lib/l10n/app_en.arb.hbs +27 -0
- package/templates/modules/i18n/pubspec.partial.yaml +7 -0
- package/templates/modules/push/lib/features/push/data/datasources/push_datasource.dart.hbs +124 -0
- package/templates/modules/push/lib/features/push/data/repositories/push_repository_impl.dart.hbs +28 -0
- package/templates/modules/push/lib/features/push/domain/repositories/push_repository.dart.hbs +31 -0
- package/templates/modules/push/lib/features/push/presentation/providers/push_provider.dart.hbs +34 -0
- package/templates/modules/push/pubspec.partial.yaml +8 -0
- package/templates/modules/theme/lib/core/theme/app_theme.dart.hbs +74 -0
- package/templates/modules/theme/lib/core/theme/theme_provider.dart.hbs +46 -0
- package/templates/modules/theme/pubspec.partial.yaml +2 -0
package/templates/modules/auth/lib/features/auth/presentation/providers/auth_provider.dart.hbs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
2
|
+
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
3
|
+
import '../../data/datasources/auth_remote_datasource.dart';
|
|
4
|
+
import '../../data/repositories/auth_repository_impl.dart';
|
|
5
|
+
import '../../domain/entities/user_entity.dart';
|
|
6
|
+
import '../../domain/repositories/auth_repository.dart';
|
|
7
|
+
|
|
8
|
+
part 'auth_provider.g.dart';
|
|
9
|
+
|
|
10
|
+
@riverpod
|
|
11
|
+
AuthRemoteDataSource authDataSource(Ref ref) {
|
|
12
|
+
{{#ifEquals modules.auth.provider "firebase"}}
|
|
13
|
+
return FirebaseAuthDataSource();
|
|
14
|
+
{{/ifEquals}}
|
|
15
|
+
{{#ifEquals modules.auth.provider "supabase"}}
|
|
16
|
+
return SupabaseAuthDataSource();
|
|
17
|
+
{{/ifEquals}}
|
|
18
|
+
{{#ifEquals modules.auth.provider "custom"}}
|
|
19
|
+
return CustomAuthDataSource();
|
|
20
|
+
{{/ifEquals}}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@riverpod
|
|
24
|
+
AuthRepository authRepository(Ref ref) {
|
|
25
|
+
return AuthRepositoryImpl(ref.watch(authDataSourceProvider));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@riverpod
|
|
29
|
+
Stream<UserEntity?> authState(Ref ref) {
|
|
30
|
+
return ref.watch(authRepositoryProvider).authStateChanges;
|
|
31
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{#ifEquals modules.auth.provider "firebase"}}
|
|
2
|
+
dependencies:
|
|
3
|
+
firebase_core: ^3.8.0
|
|
4
|
+
firebase_auth: ^5.3.4
|
|
5
|
+
{{/ifEquals}}
|
|
6
|
+
{{#ifEquals modules.auth.provider "supabase"}}
|
|
7
|
+
dependencies:
|
|
8
|
+
supabase_flutter: ^2.8.2
|
|
9
|
+
{{/ifEquals}}
|
|
10
|
+
{{#ifEquals modules.auth.provider "custom"}}
|
|
11
|
+
dependencies:
|
|
12
|
+
dio: ^5.7.0
|
|
13
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{{#ifEquals modules.cicd.provider "github"}}
|
|
2
|
+
name: CI
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main, develop]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main, develop]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
flutter:
|
|
12
|
+
name: Flutter CI
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Flutter
|
|
20
|
+
uses: subosito/flutter-action@v2
|
|
21
|
+
with:
|
|
22
|
+
flutter-version: 'stable'
|
|
23
|
+
channel: 'stable'
|
|
24
|
+
cache: true
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: flutter pub get
|
|
28
|
+
|
|
29
|
+
- name: Verify formatting
|
|
30
|
+
run: dart format --output=none --set-exit-if-changed .
|
|
31
|
+
|
|
32
|
+
- name: Analyze code
|
|
33
|
+
run: flutter analyze --fatal-infos
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: flutter test --coverage
|
|
37
|
+
|
|
38
|
+
- name: Build Android APK
|
|
39
|
+
run: flutter build apk --debug
|
|
40
|
+
|
|
41
|
+
- name: Upload coverage
|
|
42
|
+
uses: codecov/codecov-action@v4
|
|
43
|
+
with:
|
|
44
|
+
file: coverage/lcov.info
|
|
45
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{{#ifEquals modules.cicd.provider "gitlab"}}
|
|
2
|
+
image: ghcr.io/cirruslabs/flutter:stable
|
|
3
|
+
|
|
4
|
+
stages:
|
|
5
|
+
- validate
|
|
6
|
+
- test
|
|
7
|
+
- build
|
|
8
|
+
|
|
9
|
+
variables:
|
|
10
|
+
PUB_CACHE: "$CI_PROJECT_DIR/.pub-cache"
|
|
11
|
+
|
|
12
|
+
cache:
|
|
13
|
+
key: "$CI_COMMIT_REF_SLUG"
|
|
14
|
+
paths:
|
|
15
|
+
- .pub-cache/
|
|
16
|
+
- .dart_tool/
|
|
17
|
+
|
|
18
|
+
format:
|
|
19
|
+
stage: validate
|
|
20
|
+
script:
|
|
21
|
+
- flutter pub get
|
|
22
|
+
- dart format --output=none --set-exit-if-changed .
|
|
23
|
+
|
|
24
|
+
analyze:
|
|
25
|
+
stage: validate
|
|
26
|
+
script:
|
|
27
|
+
- flutter pub get
|
|
28
|
+
- flutter analyze --fatal-infos
|
|
29
|
+
|
|
30
|
+
test:
|
|
31
|
+
stage: test
|
|
32
|
+
script:
|
|
33
|
+
- flutter pub get
|
|
34
|
+
- flutter test --coverage
|
|
35
|
+
artifacts:
|
|
36
|
+
reports:
|
|
37
|
+
coverage_report:
|
|
38
|
+
coverage_format: cobertura
|
|
39
|
+
path: coverage/cobertura.xml
|
|
40
|
+
|
|
41
|
+
build_apk:
|
|
42
|
+
stage: build
|
|
43
|
+
script:
|
|
44
|
+
- flutter pub get
|
|
45
|
+
- flutter build apk --debug
|
|
46
|
+
artifacts:
|
|
47
|
+
paths:
|
|
48
|
+
- build/app/outputs/flutter-apk/app-debug.apk
|
|
49
|
+
expire_in: 1 week
|
|
50
|
+
only:
|
|
51
|
+
- main
|
|
52
|
+
- develop
|
|
53
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{{#ifEquals modules.cicd.provider "bitbucket"}}
|
|
2
|
+
image: ghcr.io/cirruslabs/flutter:stable
|
|
3
|
+
|
|
4
|
+
pipelines:
|
|
5
|
+
default:
|
|
6
|
+
- step:
|
|
7
|
+
name: Validate & Test
|
|
8
|
+
caches:
|
|
9
|
+
- gradle
|
|
10
|
+
script:
|
|
11
|
+
- flutter pub get
|
|
12
|
+
- dart format --output=none --set-exit-if-changed .
|
|
13
|
+
- flutter analyze --fatal-infos
|
|
14
|
+
- flutter test --coverage
|
|
15
|
+
|
|
16
|
+
branches:
|
|
17
|
+
main:
|
|
18
|
+
- step:
|
|
19
|
+
name: Validate & Test
|
|
20
|
+
script:
|
|
21
|
+
- flutter pub get
|
|
22
|
+
- flutter analyze --fatal-infos
|
|
23
|
+
- flutter test --coverage
|
|
24
|
+
- step:
|
|
25
|
+
name: Build Android APK
|
|
26
|
+
script:
|
|
27
|
+
- flutter pub get
|
|
28
|
+
- flutter build apk --debug
|
|
29
|
+
artifacts:
|
|
30
|
+
- build/app/outputs/flutter-apk/*.apk
|
|
31
|
+
|
|
32
|
+
develop:
|
|
33
|
+
- step:
|
|
34
|
+
name: Validate & Test
|
|
35
|
+
script:
|
|
36
|
+
- flutter pub get
|
|
37
|
+
- flutter analyze --fatal-infos
|
|
38
|
+
- flutter test --coverage
|
|
39
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# CI/CD module has no pubspec dependencies
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{{#ifEquals modules.database.engine "drift"}}
|
|
2
|
+
import 'dart:io';
|
|
3
|
+
|
|
4
|
+
import 'package:drift/drift.dart';
|
|
5
|
+
import 'package:drift/native.dart';
|
|
6
|
+
import 'package:path/path.dart' as p;
|
|
7
|
+
import 'package:path_provider/path_provider.dart';
|
|
8
|
+
|
|
9
|
+
part 'database_datasource.g.dart';
|
|
10
|
+
|
|
11
|
+
@DriftDatabase(tables: [])
|
|
12
|
+
class AppDatabase extends _$AppDatabase {
|
|
13
|
+
AppDatabase() : super(_openConnection());
|
|
14
|
+
|
|
15
|
+
@override
|
|
16
|
+
int get schemaVersion => 1;
|
|
17
|
+
|
|
18
|
+
@override
|
|
19
|
+
MigrationStrategy get migration => MigrationStrategy(
|
|
20
|
+
onCreate: (m) async {
|
|
21
|
+
await m.createAll();
|
|
22
|
+
},
|
|
23
|
+
onUpgrade: (m, from, to) async {
|
|
24
|
+
// Add migration steps here as the schema evolves.
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
static QueryExecutor _openConnection() {
|
|
29
|
+
return LazyDatabase(() async {
|
|
30
|
+
final dir = await getApplicationDocumentsDirectory();
|
|
31
|
+
final file = File(p.join(dir.path, '{{project.name}}.db'));
|
|
32
|
+
return NativeDatabase.createInBackground(file);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Future<void> clearAll() async {
|
|
37
|
+
// Delete all rows from each table.
|
|
38
|
+
// Add table.deleteAll() calls here for each table you define.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
{{/ifEquals}}
|
|
42
|
+
{{#ifEquals modules.database.engine "hive"}}
|
|
43
|
+
import 'package:hive_ce_flutter/hive_flutter.dart';
|
|
44
|
+
|
|
45
|
+
abstract class HiveDatabaseDataSource {
|
|
46
|
+
Future<void> initialize();
|
|
47
|
+
Future<void> close();
|
|
48
|
+
Future<void> clearAll();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class HiveDatabaseDataSourceImpl implements HiveDatabaseDataSource {
|
|
52
|
+
// Register adapters and open boxes here as you add domain models.
|
|
53
|
+
// Example:
|
|
54
|
+
// Hive.registerAdapter(MyModelAdapter());
|
|
55
|
+
// await Hive.openBox<MyModel>('myModels');
|
|
56
|
+
|
|
57
|
+
@override
|
|
58
|
+
Future<void> initialize() async {
|
|
59
|
+
await Hive.initFlutter();
|
|
60
|
+
// TODO: register adapters and open boxes
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@override
|
|
64
|
+
Future<void> close() async {
|
|
65
|
+
await Hive.close();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@override
|
|
69
|
+
Future<void> clearAll() async {
|
|
70
|
+
// Delete all boxes to reset local state.
|
|
71
|
+
await Hive.deleteFromDisk();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
{{/ifEquals}}
|
|
75
|
+
{{#ifEquals modules.database.engine "isar"}}
|
|
76
|
+
import 'package:isar/isar.dart';
|
|
77
|
+
import 'package:path_provider/path_provider.dart';
|
|
78
|
+
|
|
79
|
+
abstract class IsarDatabaseDataSource {
|
|
80
|
+
Future<void> initialize();
|
|
81
|
+
Future<void> close();
|
|
82
|
+
Future<void> clearAll();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
class IsarDatabaseDataSourceImpl implements IsarDatabaseDataSource {
|
|
86
|
+
late Isar _isar;
|
|
87
|
+
|
|
88
|
+
Isar get isar => _isar;
|
|
89
|
+
|
|
90
|
+
// Add your collection schemas to the list below as you define them.
|
|
91
|
+
// Example: schemas: [MyModelSchema]
|
|
92
|
+
static const List<CollectionSchema<dynamic>> _schemas = [];
|
|
93
|
+
|
|
94
|
+
@override
|
|
95
|
+
Future<void> initialize() async {
|
|
96
|
+
final dir = await getApplicationDocumentsDirectory();
|
|
97
|
+
_isar = await Isar.open(
|
|
98
|
+
_schemas,
|
|
99
|
+
directory: dir.path,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@override
|
|
104
|
+
Future<void> close() async {
|
|
105
|
+
await _isar.close();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@override
|
|
109
|
+
Future<void> clearAll() async {
|
|
110
|
+
await _isar.writeTxn(() async {
|
|
111
|
+
await _isar.clear();
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import '../../domain/repositories/database_repository.dart';
|
|
2
|
+
{{#ifEquals modules.database.engine "drift"}}
|
|
3
|
+
import '../datasources/database_datasource.dart';
|
|
4
|
+
|
|
5
|
+
class DatabaseRepositoryImpl implements DatabaseRepository {
|
|
6
|
+
final AppDatabase _db;
|
|
7
|
+
|
|
8
|
+
const DatabaseRepositoryImpl(this._db);
|
|
9
|
+
|
|
10
|
+
@override
|
|
11
|
+
Future<void> initialize() async {
|
|
12
|
+
// Drift opens the database lazily on first query; no explicit init needed.
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@override
|
|
16
|
+
Future<void> close() async {
|
|
17
|
+
await _db.close();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@override
|
|
21
|
+
Future<void> clearAll() async {
|
|
22
|
+
await _db.clearAll();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
{{/ifEquals}}
|
|
26
|
+
{{#ifEquals modules.database.engine "hive"}}
|
|
27
|
+
import '../datasources/database_datasource.dart';
|
|
28
|
+
|
|
29
|
+
class DatabaseRepositoryImpl implements DatabaseRepository {
|
|
30
|
+
final HiveDatabaseDataSource _dataSource;
|
|
31
|
+
|
|
32
|
+
const DatabaseRepositoryImpl(this._dataSource);
|
|
33
|
+
|
|
34
|
+
@override
|
|
35
|
+
Future<void> initialize() async {
|
|
36
|
+
await _dataSource.initialize();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
Future<void> close() async {
|
|
41
|
+
await _dataSource.close();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@override
|
|
45
|
+
Future<void> clearAll() async {
|
|
46
|
+
await _dataSource.clearAll();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
{{/ifEquals}}
|
|
50
|
+
{{#ifEquals modules.database.engine "isar"}}
|
|
51
|
+
import '../datasources/database_datasource.dart';
|
|
52
|
+
|
|
53
|
+
class DatabaseRepositoryImpl implements DatabaseRepository {
|
|
54
|
+
final IsarDatabaseDataSource _dataSource;
|
|
55
|
+
|
|
56
|
+
const DatabaseRepositoryImpl(this._dataSource);
|
|
57
|
+
|
|
58
|
+
@override
|
|
59
|
+
Future<void> initialize() async {
|
|
60
|
+
await _dataSource.initialize();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@override
|
|
64
|
+
Future<void> close() async {
|
|
65
|
+
await _dataSource.close();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@override
|
|
69
|
+
Future<void> clearAll() async {
|
|
70
|
+
await _dataSource.clearAll();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
abstract class DatabaseRepository {
|
|
2
|
+
/// Initialize the database connection and run any pending migrations.
|
|
3
|
+
Future<void> initialize();
|
|
4
|
+
|
|
5
|
+
/// Close the database connection and release resources.
|
|
6
|
+
Future<void> close();
|
|
7
|
+
|
|
8
|
+
/// Delete all data from the database (useful for logout/reset flows).
|
|
9
|
+
Future<void> clearAll();
|
|
10
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
2
|
+
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
3
|
+
import '../../data/datasources/database_datasource.dart';
|
|
4
|
+
import '../../data/repositories/database_repository_impl.dart';
|
|
5
|
+
import '../../domain/repositories/database_repository.dart';
|
|
6
|
+
|
|
7
|
+
part 'database_provider.g.dart';
|
|
8
|
+
|
|
9
|
+
{{#ifEquals modules.database.engine "drift"}}
|
|
10
|
+
@Riverpod(keepAlive: true)
|
|
11
|
+
AppDatabase appDatabase(Ref ref) {
|
|
12
|
+
final db = AppDatabase();
|
|
13
|
+
ref.onDispose(db.close);
|
|
14
|
+
return db;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@Riverpod(keepAlive: true)
|
|
18
|
+
DatabaseRepository databaseRepository(Ref ref) {
|
|
19
|
+
return DatabaseRepositoryImpl(ref.watch(appDatabaseProvider));
|
|
20
|
+
}
|
|
21
|
+
{{/ifEquals}}
|
|
22
|
+
{{#ifEquals modules.database.engine "hive"}}
|
|
23
|
+
@Riverpod(keepAlive: true)
|
|
24
|
+
HiveDatabaseDataSource hiveDatabaseDataSource(Ref ref) {
|
|
25
|
+
return HiveDatabaseDataSourceImpl();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Riverpod(keepAlive: true)
|
|
29
|
+
DatabaseRepository databaseRepository(Ref ref) {
|
|
30
|
+
return DatabaseRepositoryImpl(ref.watch(hiveDatabaseDataSourceProvider));
|
|
31
|
+
}
|
|
32
|
+
{{/ifEquals}}
|
|
33
|
+
{{#ifEquals modules.database.engine "isar"}}
|
|
34
|
+
@Riverpod(keepAlive: true)
|
|
35
|
+
IsarDatabaseDataSource isarDatabaseDataSource(Ref ref) {
|
|
36
|
+
return IsarDatabaseDataSourceImpl();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Riverpod(keepAlive: true)
|
|
40
|
+
DatabaseRepository databaseRepository(Ref ref) {
|
|
41
|
+
return DatabaseRepositoryImpl(ref.watch(isarDatabaseDataSourceProvider));
|
|
42
|
+
}
|
|
43
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{{#ifEquals modules.database.engine "drift"}}
|
|
2
|
+
dependencies:
|
|
3
|
+
drift: ^2.22.1
|
|
4
|
+
sqlite3_flutter_libs: ^0.5.28
|
|
5
|
+
path_provider: ^2.1.5
|
|
6
|
+
path: ^1.9.0
|
|
7
|
+
dev_dependencies:
|
|
8
|
+
drift_dev: ^2.22.1
|
|
9
|
+
build_runner: ^2.4.13
|
|
10
|
+
{{/ifEquals}}
|
|
11
|
+
{{#ifEquals modules.database.engine "hive"}}
|
|
12
|
+
dependencies:
|
|
13
|
+
hive_ce_flutter: ^2.8.0
|
|
14
|
+
path_provider: ^2.1.5
|
|
15
|
+
dev_dependencies:
|
|
16
|
+
hive_ce_generator: ^1.8.3
|
|
17
|
+
build_runner: ^2.4.13
|
|
18
|
+
{{/ifEquals}}
|
|
19
|
+
{{#ifEquals modules.database.engine "isar"}}
|
|
20
|
+
dependencies:
|
|
21
|
+
isar: ^3.1.0+1
|
|
22
|
+
isar_flutter_libs: ^3.1.0+1
|
|
23
|
+
path_provider: ^2.1.5
|
|
24
|
+
dev_dependencies:
|
|
25
|
+
isar_generator: ^3.1.0+1
|
|
26
|
+
build_runner: ^2.4.13
|
|
27
|
+
{{/ifEquals}}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import 'package:app_links/app_links.dart';
|
|
2
|
+
|
|
3
|
+
abstract class DeepLinkDataSource {
|
|
4
|
+
Stream<Uri> get onDeepLink;
|
|
5
|
+
Future<Uri?> getInitialLink();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class AppLinksDataSource implements DeepLinkDataSource {
|
|
9
|
+
final AppLinks _appLinks;
|
|
10
|
+
|
|
11
|
+
AppLinksDataSource({AppLinks? appLinks}) : _appLinks = appLinks ?? AppLinks();
|
|
12
|
+
|
|
13
|
+
@override
|
|
14
|
+
Stream<Uri> get onDeepLink => _appLinks.uriLinkStream;
|
|
15
|
+
|
|
16
|
+
@override
|
|
17
|
+
Future<Uri?> getInitialLink() => _appLinks.getInitialLink();
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import '../../domain/repositories/deep_link_repository.dart';
|
|
2
|
+
import '../datasources/deep_link_datasource.dart';
|
|
3
|
+
|
|
4
|
+
class DeepLinkRepositoryImpl implements DeepLinkRepository {
|
|
5
|
+
final DeepLinkDataSource _dataSource;
|
|
6
|
+
|
|
7
|
+
DeepLinkRepositoryImpl(this._dataSource);
|
|
8
|
+
|
|
9
|
+
@override
|
|
10
|
+
Stream<Uri> get onDeepLink => _dataSource.onDeepLink;
|
|
11
|
+
|
|
12
|
+
@override
|
|
13
|
+
Future<Uri?> getInitialLink() => _dataSource.getInitialLink();
|
|
14
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
2
|
+
import 'package:go_router/go_router.dart';
|
|
3
|
+
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
4
|
+
import '../../data/datasources/deep_link_datasource.dart';
|
|
5
|
+
import '../../data/repositories/deep_link_repository_impl.dart';
|
|
6
|
+
import '../../domain/repositories/deep_link_repository.dart';
|
|
7
|
+
|
|
8
|
+
part 'deep_link_provider.g.dart';
|
|
9
|
+
|
|
10
|
+
@riverpod
|
|
11
|
+
DeepLinkDataSource deepLinkDataSource(Ref ref) {
|
|
12
|
+
return AppLinksDataSource();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@riverpod
|
|
16
|
+
DeepLinkRepository deepLinkRepository(Ref ref) {
|
|
17
|
+
return DeepLinkRepositoryImpl(ref.watch(deepLinkDataSourceProvider));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// Handles incoming deep links by navigating with go_router.
|
|
21
|
+
/// Call this provider in your app's root widget to activate deep link handling.
|
|
22
|
+
@riverpod
|
|
23
|
+
Stream<Uri> deepLinkStream(Ref ref) {
|
|
24
|
+
return ref.watch(deepLinkRepositoryProvider).onDeepLink;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// Notifier that sets up deep link handling with go_router.
|
|
28
|
+
@riverpod
|
|
29
|
+
class DeepLinkHandler extends _$DeepLinkHandler {
|
|
30
|
+
@override
|
|
31
|
+
Future<void> build() async {
|
|
32
|
+
final repo = ref.watch(deepLinkRepositoryProvider);
|
|
33
|
+
|
|
34
|
+
// Handle the initial link that launched the app
|
|
35
|
+
final initialLink = await repo.getInitialLink();
|
|
36
|
+
if (initialLink != null) {
|
|
37
|
+
_navigate(initialLink);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Listen for incoming links while app is running
|
|
41
|
+
final subscription = repo.onDeepLink.listen(_navigate);
|
|
42
|
+
ref.onDispose(subscription.cancel);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void _navigate(Uri uri) {
|
|
46
|
+
// The router will handle the navigation based on go_router config.
|
|
47
|
+
// Scheme: {{modules.deepLinking.scheme}}, Host: {{modules.deepLinking.host}}
|
|
48
|
+
final router = ref.read(routerProvider);
|
|
49
|
+
router.go(uri.path, extra: uri.queryParameters);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Provide the router instance — override this in your app's provider scope.
|
|
54
|
+
@riverpod
|
|
55
|
+
GoRouter router(Ref ref) {
|
|
56
|
+
throw UnimplementedError('Override routerProvider with your GoRouter instance');
|
|
57
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
3
|
+
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
4
|
+
|
|
5
|
+
export 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
6
|
+
|
|
7
|
+
/// Localization configuration for the application.
|
|
8
|
+
///
|
|
9
|
+
/// Provides [localizationsDelegates] and [supportedLocales] to be passed
|
|
10
|
+
/// to [MaterialApp] or [CupertinoApp].
|
|
11
|
+
class L10nConfig {
|
|
12
|
+
const L10nConfig._();
|
|
13
|
+
|
|
14
|
+
/// Delegates required by [MaterialApp.localizationsDelegates].
|
|
15
|
+
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates = [
|
|
16
|
+
AppLocalizations.delegate,
|
|
17
|
+
GlobalMaterialLocalizations.delegate,
|
|
18
|
+
GlobalWidgetsLocalizations.delegate,
|
|
19
|
+
GlobalCupertinoLocalizations.delegate,
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
/// The list of locales supported by this application.
|
|
23
|
+
static const List<Locale> supportedLocales = AppLocalizations.supportedLocales;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Extension on [BuildContext] to conveniently access [AppLocalizations].
|
|
27
|
+
extension L10nExtension on BuildContext {
|
|
28
|
+
AppLocalizations get l10n => AppLocalizations.of(this)!;
|
|
29
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import 'package:flutter/material.dart';
|
|
2
|
+
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
3
|
+
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
4
|
+
|
|
5
|
+
part 'l10n_provider.g.dart';
|
|
6
|
+
|
|
7
|
+
/// Notifier that manages the current [Locale] for the application.
|
|
8
|
+
/// Use [localeProvider] to watch the locale and [LocaleNotifier.setLocale]
|
|
9
|
+
/// to change it at runtime.
|
|
10
|
+
@riverpod
|
|
11
|
+
class LocaleNotifier extends _$LocaleNotifier {
|
|
12
|
+
@override
|
|
13
|
+
Locale build() => const Locale('{{modules.i18n.defaultLocale}}');
|
|
14
|
+
|
|
15
|
+
/// Sets the active locale.
|
|
16
|
+
void setLocale(Locale locale) => state = locale;
|
|
17
|
+
|
|
18
|
+
/// Resets to the default locale.
|
|
19
|
+
void resetToDefault() => state = const Locale('{{modules.i18n.defaultLocale}}');
|
|
20
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@@locale": "de",
|
|
3
|
+
"appTitle": "{{project.name}}",
|
|
4
|
+
"@appTitle": {
|
|
5
|
+
"description": "Der Titel der Anwendung"
|
|
6
|
+
},
|
|
7
|
+
"welcomeMessage": "Willkommen bei {{project.name}}",
|
|
8
|
+
"@welcomeMessage": {
|
|
9
|
+
"description": "Willkommensnachricht auf dem Startbildschirm"
|
|
10
|
+
},
|
|
11
|
+
"errorGeneric": "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
|
|
12
|
+
"@errorGeneric": {
|
|
13
|
+
"description": "Allgemeine Fehlermeldung"
|
|
14
|
+
},
|
|
15
|
+
"retry": "Wiederholen",
|
|
16
|
+
"@retry": {
|
|
17
|
+
"description": "Beschriftung für den Wiederholen-Button"
|
|
18
|
+
},
|
|
19
|
+
"cancel": "Abbrechen",
|
|
20
|
+
"@cancel": {
|
|
21
|
+
"description": "Beschriftung für den Abbrechen-Button"
|
|
22
|
+
},
|
|
23
|
+
"ok": "OK",
|
|
24
|
+
"@ok": {
|
|
25
|
+
"description": "Beschriftung für den OK-Button"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@@locale": "en",
|
|
3
|
+
"appTitle": "{{project.name}}",
|
|
4
|
+
"@appTitle": {
|
|
5
|
+
"description": "The title of the application"
|
|
6
|
+
},
|
|
7
|
+
"welcomeMessage": "Welcome to {{project.name}}",
|
|
8
|
+
"@welcomeMessage": {
|
|
9
|
+
"description": "Welcome message shown on the home screen"
|
|
10
|
+
},
|
|
11
|
+
"errorGeneric": "Something went wrong. Please try again.",
|
|
12
|
+
"@errorGeneric": {
|
|
13
|
+
"description": "Generic error message"
|
|
14
|
+
},
|
|
15
|
+
"retry": "Retry",
|
|
16
|
+
"@retry": {
|
|
17
|
+
"description": "Label for retry button"
|
|
18
|
+
},
|
|
19
|
+
"cancel": "Cancel",
|
|
20
|
+
"@cancel": {
|
|
21
|
+
"description": "Label for cancel button"
|
|
22
|
+
},
|
|
23
|
+
"ok": "OK",
|
|
24
|
+
"@ok": {
|
|
25
|
+
"description": "Label for OK button"
|
|
26
|
+
}
|
|
27
|
+
}
|