kasy-cli 1.12.1 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/kasy.js +21 -0
- package/lib/commands/splash.js +220 -0
- package/lib/scaffold/CHANGELOG.json +9 -0
- package/lib/scaffold/backends/api/patch/lib/main.dart +29 -10
- package/lib/scaffold/backends/supabase/patch/lib/main.dart +29 -10
- package/lib/scaffold/features/README.md +15 -139
- package/lib/scaffold/shared/generator-utils.js +16 -15
- package/lib/utils/i18n.js +78 -0
- package/package.json +2 -2
- package/templates/firebase/android/app/src/main/res/drawable-hdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-mdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night/launch_background.xml +9 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-v21/launch_background.xml +9 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +2 -1
- package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -0
- package/templates/firebase/assets/images/splash_logo_dark.png +0 -0
- package/templates/firebase/assets/images/splash_logo_light.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json +9 -8
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +33 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png +0 -0
- package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +1 -1
- package/templates/firebase/lib/core/theme/providers/theme_provider.dart +48 -24
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +4 -0
- package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +1 -0
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +13 -0
- package/templates/firebase/lib/features/settings/settings_page.dart +158 -18
- package/templates/firebase/lib/i18n/en.i18n.json +6 -2
- package/templates/firebase/lib/i18n/es.i18n.json +6 -2
- package/templates/firebase/lib/i18n/pt.i18n.json +6 -2
- package/templates/firebase/lib/main.dart +29 -10
- package/templates/firebase/pubspec.yaml +4 -5
- package/templates/firebase/test/core/data/repositories/user_repository_test.dart +1 -1
- package/templates/firebase/web/index.html +47 -39
- package/templates/firebase/web/splash/img/dark-1x.png +0 -0
- package/templates/firebase/web/splash/img/dark-2x.png +0 -0
- package/templates/firebase/web/splash/img/dark-3x.png +0 -0
- package/templates/firebase/web/splash/img/dark-4x.png +0 -0
- package/templates/firebase/web/splash/img/light-1x.png +0 -0
- package/templates/firebase/web/splash/img/light-2x.png +0 -0
- package/templates/firebase/web/splash/img/light-3x.png +0 -0
- package/templates/firebase/web/splash/img/light-4x.png +0 -0
- package/lib/scaffold/features/analytics/lib/core/data/api/analytics_api.dart +0 -124
- package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.es.md +0 -35
- package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.md +0 -35
- package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.pt.md +0 -35
- package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.es.md +0 -12
- package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.md +0 -12
- package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.pt.md +0 -12
- package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.es.md +0 -17
- package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.md +0 -17
- package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.pt.md +0 -17
- package/lib/scaffold/features/ci/.github/dependabot.yml +0 -16
- package/lib/scaffold/features/ci/.github/workflows/app.yml +0 -20
- package/lib/scaffold/features/ci/.gitlab/templates/deploy.yaml +0 -14
- package/lib/scaffold/features/ci/.gitlab/templates/dropbox.yaml +0 -19
- package/lib/scaffold/features/ci/.gitlab/templates/flutter.yaml +0 -163
- package/lib/scaffold/features/ci/.gitlab/templates/mailgun.yaml +0 -28
- package/lib/scaffold/features/ci/.gitlab-ci.yml +0 -37
- package/lib/scaffold/features/ci/codemagic.yaml +0 -157
- package/lib/scaffold/features/facebook/lib/core/data/api/tracking_api.dart +0 -111
- package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_request_entity.dart +0 -27
- package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_vote_entity.dart +0 -27
- package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_request_api.dart +0 -50
- package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_vote_api.dart +0 -79
- package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feature_requests.dart +0 -48
- package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feedback_state.dart +0 -42
- package/lib/scaffold/features/feedback/lib/features/feedbacks/providers/feedback_page_notifier.dart +0 -147
- package/lib/scaffold/features/feedback/lib/features/feedbacks/repositories/feature_request_repository.dart +0 -95
- package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/component/add_feature_form.dart +0 -199
- package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/feedback_page.dart +0 -175
- package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -76
- package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/feature_card.dart +0 -279
- package/lib/scaffold/features/ios-release/.kasy/apple.env.example +0 -8
- package/lib/scaffold/features/ios-release/.kasy/codemagic.env.example +0 -7
- package/lib/scaffold/features/ios-release/docs/codemagic-release.en.md +0 -50
- package/lib/scaffold/features/ios-release/docs/codemagic-release.es.md +0 -50
- package/lib/scaffold/features/ios-release/docs/codemagic-release.pt.md +0 -50
- package/lib/scaffold/features/ios-release/docs/ios-release.en.md +0 -41
- package/lib/scaffold/features/ios-release/docs/ios-release.es.md +0 -41
- package/lib/scaffold/features/ios-release/docs/ios-release.pt.md +0 -41
- package/lib/scaffold/features/ios-release/scripts/bump-ios-version.js +0 -38
- package/lib/scaffold/features/ios-release/scripts/release-ios.sh +0 -137
- package/lib/scaffold/features/llm_chat/lib/features/llm_chat/llm_chat_page.dart +0 -301
- package/lib/scaffold/features/local_notifications/lib/features/local_reminder/providers/reminder_notifier.dart +0 -81
- package/lib/scaffold/features/local_notifications/lib/features/local_reminder/repositories/reminder_preferences.dart +0 -76
- package/lib/scaffold/features/local_notifications/lib/features/local_reminder/ui/reminder_page.dart +0 -282
- package/lib/scaffold/features/onboarding/lib/features/onboarding/api/entities/user_info_entity.dart +0 -24
- package/lib/scaffold/features/onboarding/lib/features/onboarding/api/user_infos_api.dart +0 -71
- package/lib/scaffold/features/onboarding/lib/features/onboarding/models/user_info.dart +0 -92
- package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_model.dart +0 -15
- package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_provider.dart +0 -78
- package/lib/scaffold/features/onboarding/lib/features/onboarding/repositories/user_infos_repository.dart +0 -29
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/animations/page_transitions.dart +0 -30
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_att_setup.dart +0 -66
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_features.dart +0 -72
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_loader.dart +0 -92
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +0 -73
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_questions.dart +0 -89
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/onboarding_page.dart +0 -94
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_background.dart +0 -80
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_feature.dart +0 -139
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +0 -110
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_progress.dart +0 -84
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +0 -173
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_reassurance.dart +0 -45
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +0 -77
- package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +0 -392
- package/lib/scaffold/features/revenuecat/lib/core/data/api/tracking_api.dart +0 -116
- package/lib/scaffold/features/revenuecat/lib/core/data/models/subscription.dart +0 -322
- package/lib/scaffold/features/revenuecat/lib/core/home_widgets/home_widget_background_task.dart +0 -41
- package/lib/scaffold/features/revenuecat/lib/core/states/user_state_notifier.dart +0 -305
- package/templates/firebase/assets/images/splashscreen.png +0 -0
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
3
|
-
import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_progress.dart';
|
|
4
|
-
import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_sticky_footer.dart';
|
|
5
|
-
|
|
6
|
-
/// Layout compartilhado para passos de onboarding com ilustração e ações no rodapé.
|
|
7
|
-
///
|
|
8
|
-
/// Evita buracos grandes de [Expanded] + [Spacer] com imagens [BoxFit.contain].
|
|
9
|
-
class OnboardingIllustrationScaffold extends StatelessWidget {
|
|
10
|
-
const OnboardingIllustrationScaffold({
|
|
11
|
-
super.key,
|
|
12
|
-
required this.progress,
|
|
13
|
-
required this.title,
|
|
14
|
-
required this.description,
|
|
15
|
-
required this.footerActions,
|
|
16
|
-
this.imageAsset,
|
|
17
|
-
this.image,
|
|
18
|
-
this.imageMaxHeight = 280,
|
|
19
|
-
this.titleWidget,
|
|
20
|
-
this.descriptionWidget,
|
|
21
|
-
this.footerAnimationDelayMs = 400,
|
|
22
|
-
this.animateFooter = true,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
final double progress;
|
|
26
|
-
final String title;
|
|
27
|
-
final String description;
|
|
28
|
-
final String? imageAsset;
|
|
29
|
-
final Widget? image;
|
|
30
|
-
final List<Widget> footerActions;
|
|
31
|
-
final double imageMaxHeight;
|
|
32
|
-
final Widget? titleWidget;
|
|
33
|
-
final Widget? descriptionWidget;
|
|
34
|
-
final int footerAnimationDelayMs;
|
|
35
|
-
final bool animateFooter;
|
|
36
|
-
|
|
37
|
-
@override
|
|
38
|
-
Widget build(BuildContext context) {
|
|
39
|
-
final Widget? illustration = image ??
|
|
40
|
-
(imageAsset != null && imageAsset!.isNotEmpty
|
|
41
|
-
? Image.asset(imageAsset!, fit: BoxFit.contain)
|
|
42
|
-
: null);
|
|
43
|
-
|
|
44
|
-
return Column(
|
|
45
|
-
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
46
|
-
children: [
|
|
47
|
-
Expanded(
|
|
48
|
-
child: SafeArea(
|
|
49
|
-
bottom: false,
|
|
50
|
-
child: Column(
|
|
51
|
-
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
52
|
-
children: [
|
|
53
|
-
OnboardingProgress(value: progress),
|
|
54
|
-
Expanded(
|
|
55
|
-
child: SingleChildScrollView(
|
|
56
|
-
padding: const EdgeInsets.fromLTRB(
|
|
57
|
-
KasySpacing.xl,
|
|
58
|
-
KasySpacing.lg,
|
|
59
|
-
KasySpacing.xl,
|
|
60
|
-
KasySpacing.md,
|
|
61
|
-
),
|
|
62
|
-
child: Column(
|
|
63
|
-
children: [
|
|
64
|
-
titleWidget ??
|
|
65
|
-
Text(
|
|
66
|
-
title,
|
|
67
|
-
textAlign: TextAlign.center,
|
|
68
|
-
style:
|
|
69
|
-
context.textTheme.headlineMedium?.copyWith(
|
|
70
|
-
color: context.colors.onBackground,
|
|
71
|
-
fontWeight: FontWeight.w600,
|
|
72
|
-
),
|
|
73
|
-
),
|
|
74
|
-
const SizedBox(height: KasySpacing.smd),
|
|
75
|
-
descriptionWidget ??
|
|
76
|
-
Text(
|
|
77
|
-
description,
|
|
78
|
-
textAlign: TextAlign.center,
|
|
79
|
-
style: context.textTheme.bodyLarge?.copyWith(
|
|
80
|
-
color: context.colors.onBackground.withValues(
|
|
81
|
-
alpha: 0.6,
|
|
82
|
-
),
|
|
83
|
-
),
|
|
84
|
-
),
|
|
85
|
-
if (illustration != null) ...[
|
|
86
|
-
const SizedBox(height: KasySpacing.xl),
|
|
87
|
-
ConstrainedBox(
|
|
88
|
-
constraints:
|
|
89
|
-
BoxConstraints(maxHeight: imageMaxHeight),
|
|
90
|
-
child: illustration,
|
|
91
|
-
),
|
|
92
|
-
],
|
|
93
|
-
],
|
|
94
|
-
),
|
|
95
|
-
),
|
|
96
|
-
),
|
|
97
|
-
],
|
|
98
|
-
),
|
|
99
|
-
),
|
|
100
|
-
),
|
|
101
|
-
OnboardingStickyFooter(
|
|
102
|
-
animate: animateFooter,
|
|
103
|
-
animationDelayMs: footerAnimationDelayMs,
|
|
104
|
-
horizontalPadding: KasySpacing.xl,
|
|
105
|
-
children: footerActions,
|
|
106
|
-
),
|
|
107
|
-
],
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
}
|
package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_progress.dart
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
3
|
-
|
|
4
|
-
class OnboardingProgress extends StatefulWidget {
|
|
5
|
-
final double value;
|
|
6
|
-
|
|
7
|
-
const OnboardingProgress({super.key, required this.value});
|
|
8
|
-
|
|
9
|
-
@override
|
|
10
|
-
State<OnboardingProgress> createState() => _OnboardingProgressState();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
class _OnboardingProgressState extends State<OnboardingProgress>
|
|
14
|
-
with SingleTickerProviderStateMixin {
|
|
15
|
-
late final AnimationController animationController;
|
|
16
|
-
|
|
17
|
-
late Animation<double> _progressAnimation;
|
|
18
|
-
|
|
19
|
-
@override
|
|
20
|
-
void initState() {
|
|
21
|
-
super.initState();
|
|
22
|
-
|
|
23
|
-
animationController = AnimationController(
|
|
24
|
-
vsync: this,
|
|
25
|
-
duration: const Duration(milliseconds: 1500),
|
|
26
|
-
);
|
|
27
|
-
_setProgressValueAndStart();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@override
|
|
31
|
-
void didUpdateWidget(OnboardingProgress oldWidget) {
|
|
32
|
-
super.didUpdateWidget(oldWidget);
|
|
33
|
-
if (oldWidget.value != widget.value) {
|
|
34
|
-
_setProgressValueAndStart();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@override
|
|
39
|
-
void dispose() {
|
|
40
|
-
animationController.dispose();
|
|
41
|
-
super.dispose();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
void _setProgressValueAndStart() {
|
|
45
|
-
var start = 0.0;
|
|
46
|
-
if (widget.value > 0) {
|
|
47
|
-
start = widget.value - 0.1;
|
|
48
|
-
}
|
|
49
|
-
_progressAnimation = Tween<double>(
|
|
50
|
-
begin: start,
|
|
51
|
-
end: widget.value,
|
|
52
|
-
).animate(
|
|
53
|
-
CurvedAnimation(
|
|
54
|
-
parent: animationController,
|
|
55
|
-
curve: Curves.ease,
|
|
56
|
-
),
|
|
57
|
-
);
|
|
58
|
-
animationController.forward(from: 0);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
@override
|
|
62
|
-
Widget build(BuildContext context) {
|
|
63
|
-
return AnimatedBuilder(
|
|
64
|
-
animation: _progressAnimation,
|
|
65
|
-
builder: (context, child) {
|
|
66
|
-
return Padding(
|
|
67
|
-
// Intentionally narrow (80px lateral) — visual design choice for progress bar
|
|
68
|
-
padding: const EdgeInsets.fromLTRB(80, KasySpacing.md, 80, 0),
|
|
69
|
-
child: ClipRRect(
|
|
70
|
-
borderRadius: KasyRadius.fullBorderRadius,
|
|
71
|
-
child: LinearProgressIndicator(
|
|
72
|
-
value: _progressAnimation.value,
|
|
73
|
-
minHeight: 16,
|
|
74
|
-
valueColor: AlwaysStoppedAnimation<Color>(
|
|
75
|
-
context.colors.primary,
|
|
76
|
-
),
|
|
77
|
-
backgroundColor: context.colors.primary.withValues(alpha: 0.1),
|
|
78
|
-
),
|
|
79
|
-
),
|
|
80
|
-
);
|
|
81
|
-
},
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:flutter_animate/flutter_animate.dart';
|
|
3
|
-
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
4
|
-
import 'package:kasy_kit/components/components.dart';
|
|
5
|
-
import 'package:kasy_kit/core/animations/movefade_anim.dart';
|
|
6
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
7
|
-
import 'package:kasy_kit/core/widgets/responsive_layout.dart';
|
|
8
|
-
import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_background.dart';
|
|
9
|
-
import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_progress.dart';
|
|
10
|
-
import 'package:kasy_kit/features/onboarding/ui/widgets/onboarding_sticky_footer.dart';
|
|
11
|
-
import 'package:kasy_kit/features/onboarding/ui/widgets/selectable_row_tile.dart';
|
|
12
|
-
|
|
13
|
-
typedef OptionBuilder = Widget Function(String key, bool selected);
|
|
14
|
-
|
|
15
|
-
typedef ReassuranceBuilder = Widget? Function(String key);
|
|
16
|
-
|
|
17
|
-
typedef OnOptionIdSelected = void Function(String id);
|
|
18
|
-
|
|
19
|
-
typedef OnValidate = void Function(String? key);
|
|
20
|
-
|
|
21
|
-
/// Single choice question with radio buttons
|
|
22
|
-
class OnboardingRadioQuestion extends ConsumerStatefulWidget {
|
|
23
|
-
final double? progress;
|
|
24
|
-
final String title;
|
|
25
|
-
final String description;
|
|
26
|
-
final String btnText;
|
|
27
|
-
final List<String> optionIds;
|
|
28
|
-
final OptionBuilder optionBuilder;
|
|
29
|
-
final ReassuranceBuilder? reassuranceBuilder;
|
|
30
|
-
final OnOptionIdSelected? onOptionIdSelected;
|
|
31
|
-
final OnValidate? onValidate;
|
|
32
|
-
|
|
33
|
-
const OnboardingRadioQuestion({
|
|
34
|
-
super.key,
|
|
35
|
-
required this.title,
|
|
36
|
-
required this.description,
|
|
37
|
-
required this.btnText,
|
|
38
|
-
required this.optionIds,
|
|
39
|
-
required this.optionBuilder,
|
|
40
|
-
this.progress,
|
|
41
|
-
this.onOptionIdSelected,
|
|
42
|
-
this.onValidate,
|
|
43
|
-
this.reassuranceBuilder,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
@override
|
|
47
|
-
ConsumerState<OnboardingRadioQuestion> createState() =>
|
|
48
|
-
_OnboardingRadioQuestionState();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
class _OnboardingRadioQuestionState
|
|
52
|
-
extends ConsumerState<OnboardingRadioQuestion> {
|
|
53
|
-
String? selectedChoiceId;
|
|
54
|
-
|
|
55
|
-
@override
|
|
56
|
-
Widget build(BuildContext context) {
|
|
57
|
-
final scrollBody = Column(
|
|
58
|
-
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
59
|
-
children: [
|
|
60
|
-
if (widget.progress != null)
|
|
61
|
-
OnboardingProgress(value: widget.progress!),
|
|
62
|
-
Padding(
|
|
63
|
-
padding: const EdgeInsets.fromLTRB(
|
|
64
|
-
KasySpacing.md,
|
|
65
|
-
KasySpacing.xl,
|
|
66
|
-
KasySpacing.md,
|
|
67
|
-
0,
|
|
68
|
-
),
|
|
69
|
-
child: MoveFadeAnim(
|
|
70
|
-
delayInMs: 100,
|
|
71
|
-
child: Text(
|
|
72
|
-
widget.title,
|
|
73
|
-
textAlign: TextAlign.center,
|
|
74
|
-
style: context.textTheme.headlineLarge?.copyWith(
|
|
75
|
-
color: context.colors.onBackground,
|
|
76
|
-
),
|
|
77
|
-
),
|
|
78
|
-
),
|
|
79
|
-
),
|
|
80
|
-
Padding(
|
|
81
|
-
padding: const EdgeInsets.fromLTRB(
|
|
82
|
-
KasySpacing.lg,
|
|
83
|
-
KasySpacing.md,
|
|
84
|
-
KasySpacing.lg,
|
|
85
|
-
KasySpacing.xl,
|
|
86
|
-
),
|
|
87
|
-
child: MoveFadeAnim(
|
|
88
|
-
delayInMs: 200,
|
|
89
|
-
child: Text(
|
|
90
|
-
widget.description,
|
|
91
|
-
textAlign: TextAlign.center,
|
|
92
|
-
style: context.textTheme.bodyLarge?.copyWith(
|
|
93
|
-
color: context.colors.onBackground.withValues(alpha: 0.6),
|
|
94
|
-
),
|
|
95
|
-
),
|
|
96
|
-
),
|
|
97
|
-
),
|
|
98
|
-
Padding(
|
|
99
|
-
padding: const EdgeInsets.symmetric(horizontal: KasySpacing.md),
|
|
100
|
-
child: OnboardingSelectableRowGroup(
|
|
101
|
-
physics: const NeverScrollableScrollPhysics(),
|
|
102
|
-
options: widget.optionIds
|
|
103
|
-
.map(
|
|
104
|
-
(e) {
|
|
105
|
-
final index = widget.optionIds.indexOf(e);
|
|
106
|
-
return Animate(
|
|
107
|
-
effects: [
|
|
108
|
-
FadeEffect(
|
|
109
|
-
delay: Duration(milliseconds: 300 + index * 100),
|
|
110
|
-
duration: const Duration(milliseconds: 550),
|
|
111
|
-
curve: Curves.easeInOut,
|
|
112
|
-
),
|
|
113
|
-
],
|
|
114
|
-
child: widget.optionBuilder(e, e == selectedChoiceId),
|
|
115
|
-
);
|
|
116
|
-
},
|
|
117
|
-
).toList(),
|
|
118
|
-
onSelect: (index, selected) {
|
|
119
|
-
widget.onOptionIdSelected?.call(widget.optionIds[index]);
|
|
120
|
-
setState(() {
|
|
121
|
-
selectedChoiceId = widget.optionIds[index];
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
onSelectInfoWidget: widget.optionIds
|
|
125
|
-
.map((el) => widget.reassuranceBuilder?.call(el))
|
|
126
|
-
.toList(),
|
|
127
|
-
),
|
|
128
|
-
),
|
|
129
|
-
const SizedBox(height: KasySpacing.xl),
|
|
130
|
-
],
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
return OnboardingBackground(
|
|
134
|
-
child: Column(
|
|
135
|
-
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
136
|
-
children: [
|
|
137
|
-
Expanded(
|
|
138
|
-
child: SafeArea(
|
|
139
|
-
bottom: false,
|
|
140
|
-
child: SingleChildScrollView(
|
|
141
|
-
padding: const EdgeInsets.only(bottom: KasySpacing.md),
|
|
142
|
-
child: ResponsiveBuilder(
|
|
143
|
-
small: scrollBody,
|
|
144
|
-
medium: Center(
|
|
145
|
-
child: ConstrainedBox(
|
|
146
|
-
constraints: const BoxConstraints(maxWidth: 600),
|
|
147
|
-
child: scrollBody,
|
|
148
|
-
),
|
|
149
|
-
),
|
|
150
|
-
),
|
|
151
|
-
),
|
|
152
|
-
),
|
|
153
|
-
),
|
|
154
|
-
DeviceSizeBuilder(
|
|
155
|
-
builder: (device) => OnboardingStickyFooter(
|
|
156
|
-
maxContentWidth:
|
|
157
|
-
device == DeviceType.small ? null : 600,
|
|
158
|
-
children: [
|
|
159
|
-
KasyButton(
|
|
160
|
-
label: widget.btnText,
|
|
161
|
-
expand: true,
|
|
162
|
-
onPressed: selectedChoiceId == null
|
|
163
|
-
? null
|
|
164
|
-
: () => widget.onValidate?.call(selectedChoiceId),
|
|
165
|
-
),
|
|
166
|
-
],
|
|
167
|
-
),
|
|
168
|
-
),
|
|
169
|
-
],
|
|
170
|
-
),
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:flutter_animate/flutter_animate.dart';
|
|
3
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
4
|
-
|
|
5
|
-
class CheckedReassurance extends StatelessWidget {
|
|
6
|
-
final String text;
|
|
7
|
-
|
|
8
|
-
const CheckedReassurance({super.key, required this.text});
|
|
9
|
-
|
|
10
|
-
@override
|
|
11
|
-
Widget build(BuildContext context) {
|
|
12
|
-
return Animate(
|
|
13
|
-
effects: const [
|
|
14
|
-
FadeEffect(
|
|
15
|
-
duration: Duration(milliseconds: 300),
|
|
16
|
-
curve: Curves.easeInOut,
|
|
17
|
-
),
|
|
18
|
-
MoveEffect(
|
|
19
|
-
duration: Duration(milliseconds: 250),
|
|
20
|
-
curve: Curves.easeInOut,
|
|
21
|
-
begin: Offset(0, -20),
|
|
22
|
-
end: Offset.zero,
|
|
23
|
-
),
|
|
24
|
-
],
|
|
25
|
-
child: Container(
|
|
26
|
-
padding: const EdgeInsets.all(KasySpacing.lg),
|
|
27
|
-
decoration: BoxDecoration(
|
|
28
|
-
color: context.colors.success.withValues(alpha: 0.05),
|
|
29
|
-
borderRadius: KasyRadius.smBorderRadius,
|
|
30
|
-
border: Border.all(
|
|
31
|
-
color: context.colors.muted,
|
|
32
|
-
),
|
|
33
|
-
),
|
|
34
|
-
child: Text(
|
|
35
|
-
text,
|
|
36
|
-
textAlign: TextAlign.left,
|
|
37
|
-
style: context.textTheme.bodyLarge?.copyWith(
|
|
38
|
-
color: context.colors.muted,
|
|
39
|
-
fontWeight: FontWeight.w900,
|
|
40
|
-
),
|
|
41
|
-
),
|
|
42
|
-
),
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/foundation.dart';
|
|
2
|
-
import 'package:flutter/material.dart';
|
|
3
|
-
import 'package:kasy_kit/core/animations/movefade_anim.dart';
|
|
4
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
5
|
-
|
|
6
|
-
/// Rodapé fixo do onboarding: fundo até a borda inferior + animação de entrada.
|
|
7
|
-
class OnboardingStickyFooter extends StatelessWidget {
|
|
8
|
-
const OnboardingStickyFooter({
|
|
9
|
-
super.key,
|
|
10
|
-
required this.children,
|
|
11
|
-
this.animate = true,
|
|
12
|
-
this.animationDelayMs = 400,
|
|
13
|
-
this.horizontalPadding = KasySpacing.lg,
|
|
14
|
-
this.maxContentWidth,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
final List<Widget> children;
|
|
18
|
-
final bool animate;
|
|
19
|
-
final int animationDelayMs;
|
|
20
|
-
final double horizontalPadding;
|
|
21
|
-
|
|
22
|
-
/// Largura máxima do conteúdo (ex.: 600 em telas médias).
|
|
23
|
-
final double? maxContentWidth;
|
|
24
|
-
|
|
25
|
-
@override
|
|
26
|
-
Widget build(BuildContext context) {
|
|
27
|
-
final bottomInset = MediaQuery.viewPaddingOf(context).bottom;
|
|
28
|
-
|
|
29
|
-
Widget content = Column(
|
|
30
|
-
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
31
|
-
children: children,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
if (maxContentWidth != null) {
|
|
35
|
-
content = Center(
|
|
36
|
-
child: ConstrainedBox(
|
|
37
|
-
constraints: BoxConstraints(maxWidth: maxContentWidth!),
|
|
38
|
-
child: content,
|
|
39
|
-
),
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
Widget footer = Container(
|
|
44
|
-
width: double.infinity,
|
|
45
|
-
decoration: BoxDecoration(
|
|
46
|
-
color: context.colors.background,
|
|
47
|
-
boxShadow: [
|
|
48
|
-
BoxShadow(
|
|
49
|
-
color: context.colors.onBackground.withValues(alpha: 0.06),
|
|
50
|
-
blurRadius: 16,
|
|
51
|
-
offset: const Offset(0, -4),
|
|
52
|
-
),
|
|
53
|
-
],
|
|
54
|
-
),
|
|
55
|
-
padding: EdgeInsets.fromLTRB(
|
|
56
|
-
horizontalPadding,
|
|
57
|
-
KasySpacing.md,
|
|
58
|
-
horizontalPadding,
|
|
59
|
-
KasySpacing.md +
|
|
60
|
-
bottomInset +
|
|
61
|
-
(defaultTargetPlatform == TargetPlatform.android
|
|
62
|
-
? KasySpacing.sm
|
|
63
|
-
: 0),
|
|
64
|
-
),
|
|
65
|
-
child: content,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
if (animate) {
|
|
69
|
-
footer = MoveFadeAnim(
|
|
70
|
-
delayInMs: animationDelayMs,
|
|
71
|
-
child: footer,
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return footer;
|
|
76
|
-
}
|
|
77
|
-
}
|