kasy-cli 1.38.0 → 1.39.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/lib/scaffold/CHANGELOG.json +14 -0
- package/lib/scaffold/backends/api/patch/README.md +15 -0
- package/lib/scaffold/backends/api/patch/lib/features/notifications/api/device_api.dart +11 -6
- package/lib/scaffold/backends/api/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +9 -1
- package/lib/scaffold/backends/api/pubspec.yaml.tpl +1 -0
- package/lib/scaffold/backends/patch-base-hashes.json +6 -6
- package/lib/scaffold/backends/supabase/edge-functions/admin-list-users/index.ts +3 -1
- package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/index.ts +3 -0
- package/lib/scaffold/backends/supabase/migrations/20240101000012_welcome_decouple_from_push.sql +62 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/device_api.dart +11 -6
- package/lib/scaffold/backends/supabase/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +7 -0
- package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +1 -0
- package/lib/scaffold/shared/generator-utils.js +12 -6
- package/package.json +1 -1
- package/templates/firebase/.firebase/hosting.YnVpbGQvd2Vi.cache +23 -23
- package/templates/firebase/DESIGN_SYSTEM.md +22 -8
- package/templates/firebase/assets/icons/apple_black.svg +3 -0
- package/templates/firebase/assets/icons/apple_white.svg +4 -0
- package/templates/firebase/assets/icons/facebook.svg +49 -0
- package/templates/firebase/assets/icons/google.svg +1 -0
- package/templates/firebase/functions/src/admin/functions.ts +2 -0
- package/templates/firebase/functions/src/authentication/functions.ts +13 -7
- package/templates/firebase/functions/src/notifications/triggers.ts +6 -2
- package/templates/firebase/lib/components/components.dart +1 -1
- package/templates/firebase/lib/components/kasy_app_bar.dart +314 -14
- package/templates/firebase/lib/components/kasy_card.dart +4 -0
- package/templates/firebase/lib/components/kasy_drop_down.dart +584 -0
- package/templates/firebase/lib/components/kasy_sidebar.dart +18 -6
- package/templates/firebase/lib/components/kasy_tabs.dart +31 -10
- package/templates/firebase/lib/components/kasy_text_field.dart +29 -7
- package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +27 -18
- package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +12 -10
- package/templates/firebase/lib/core/chrome/app_bar_config.dart +214 -0
- package/templates/firebase/lib/core/chrome/app_bar_scope.dart +102 -0
- package/templates/firebase/lib/core/data/api/user_api.dart +11 -0
- package/templates/firebase/lib/core/dev_inspector/dev_inspector_service.dart +55 -15
- package/templates/firebase/lib/core/rating/widgets/review_popup.dart +18 -35
- package/templates/firebase/lib/core/shared_preferences/shared_preferences.dart +11 -0
- package/templates/firebase/lib/core/states/logout_action.dart +11 -1
- package/templates/firebase/lib/core/states/user_state_notifier.dart +28 -1
- package/templates/firebase/lib/core/theme/texts.dart +21 -6
- package/templates/firebase/lib/core/theme/type_scale.dart +34 -15
- package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +51 -19
- package/templates/firebase/lib/core/web_viewport_scale.dart +64 -35
- package/templates/firebase/lib/core/widgets/kasy_pressable_depth.dart +14 -3
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_composer.dart +1 -1
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_conversation_view.dart +52 -35
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +1 -1
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +18 -8
- package/templates/firebase/lib/features/authentication/ui/signin_page.dart +11 -61
- package/templates/firebase/lib/features/authentication/ui/signup_page.dart +11 -61
- package/templates/firebase/lib/features/authentication/ui/widgets/auth_card_scaffold.dart +7 -5
- package/templates/firebase/lib/features/authentication/ui/widgets/social_auth_tile.dart +83 -0
- package/templates/firebase/lib/features/feedbacks/ui/widgets/feature_card.dart +4 -4
- package/templates/firebase/lib/features/home/home_components_page.dart +253 -125
- package/templates/firebase/lib/features/home/home_components_preview_registry.dart +231 -57
- package/templates/firebase/lib/features/home/home_feed.dart +2 -2
- package/templates/firebase/lib/features/home/home_image_grid.dart +3 -3
- package/templates/firebase/lib/features/local_reminders/providers/reminder_notifier.dart +8 -1
- package/templates/firebase/lib/features/local_reminders/ui/reminder_page.dart +111 -57
- package/templates/firebase/lib/features/notifications/api/device_api.dart +11 -3
- package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +16 -4
- package/templates/firebase/lib/features/notifications/ui/widgets/empty_notifications.dart +7 -56
- package/templates/firebase/lib/features/notifications/ui/widgets/notification_tile.dart +5 -5
- package/templates/firebase/lib/features/notifications/ui/widgets/push_permission_banner.dart +163 -0
- package/templates/firebase/lib/features/notifications/ui/widgets/web_notifications_bell.dart +2 -2
- package/templates/firebase/lib/features/onboarding/providers/onboarding_model.dart +9 -0
- package/templates/firebase/lib/features/onboarding/providers/onboarding_provider.dart +28 -0
- package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +51 -12
- package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +90 -32
- package/templates/firebase/lib/features/settings/settings_page.dart +53 -32
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +895 -111
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_api.dart +7 -0
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_tab.dart +445 -233
- package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +171 -41
- package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +1 -1
- package/templates/firebase/lib/features/settings/ui/components/delete_user_component.dart +9 -1
- package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +48 -47
- package/templates/firebase/lib/features/settings/ui/widgets/settings_bottom_sheet_option_tile.dart +21 -18
- package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +25 -10
- package/templates/firebase/lib/i18n/en.i18n.json +749 -712
- package/templates/firebase/lib/i18n/es.i18n.json +749 -712
- package/templates/firebase/lib/i18n/pt.i18n.json +749 -712
- package/templates/firebase/lib/main.dart +20 -7
- package/templates/firebase/lib/router.dart +32 -26
- package/templates/firebase/pubspec.yaml +2 -1
- package/templates/firebase/test/admin_shell_chrome_test.dart +11 -5
- package/templates/firebase/test/components/kasy_text_field_height_test.dart +77 -0
- package/templates/firebase/test/core/web_viewport_scale_test.dart +23 -16
- package/templates/firebase/tool/design_check.dart +9 -0
- package/templates/firebase/assets/icons/apple.png +0 -0
- package/templates/firebase/assets/icons/facebook.png +0 -0
- package/templates/firebase/assets/icons/google.png +0 -0
- package/templates/firebase/assets/icons/google_play_games.png +0 -0
- package/templates/firebase/lib/components/kasy_web_header.dart +0 -218
- package/templates/firebase/lib/core/chrome/web_header_scope.dart +0 -20
- package/templates/firebase/lib/features/authentication/ui/components/apple_signin.dart +0 -19
- package/templates/firebase/lib/features/authentication/ui/components/google_signin.dart +0 -32
- package/templates/firebase/lib/features/authentication/ui/widgets/round_signin.dart +0 -73
- package/templates/firebase/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -66
- package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart +0 -179
- package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +0 -106
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:kasy_kit/core/haptics/kasy_haptics.dart';
|
|
3
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
4
|
-
|
|
5
|
-
typedef SocialSigninCallback = void Function();
|
|
6
|
-
|
|
7
|
-
class SocialSigninButton extends StatelessWidget {
|
|
8
|
-
final Image iconImage;
|
|
9
|
-
final SocialSigninCallback? onPressed;
|
|
10
|
-
|
|
11
|
-
const SocialSigninButton({
|
|
12
|
-
super.key,
|
|
13
|
-
required this.iconImage,
|
|
14
|
-
required this.onPressed,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
factory SocialSigninButton.google(SocialSigninCallback onPressed) {
|
|
18
|
-
return SocialSigninButton(
|
|
19
|
-
iconImage: Image.asset("assets/icons/google.png", width: 24),
|
|
20
|
-
onPressed: onPressed,
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
factory SocialSigninButton.googlePlayGames(SocialSigninCallback onPressed) {
|
|
25
|
-
return SocialSigninButton(
|
|
26
|
-
iconImage: Image.asset("assets/icons/google_play_games.png", width: 24),
|
|
27
|
-
onPressed: onPressed,
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
factory SocialSigninButton.facebook(SocialSigninCallback onPressed) {
|
|
32
|
-
return SocialSigninButton(
|
|
33
|
-
iconImage: Image.asset("assets/icons/facebook.png", width: 24),
|
|
34
|
-
onPressed: onPressed,
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
factory SocialSigninButton.apple(SocialSigninCallback onPressed) {
|
|
39
|
-
return SocialSigninButton(
|
|
40
|
-
iconImage: Image.asset("assets/icons/apple.png", width: 24),
|
|
41
|
-
onPressed: onPressed,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@override
|
|
46
|
-
Widget build(BuildContext context) {
|
|
47
|
-
return Container(
|
|
48
|
-
width: 56,
|
|
49
|
-
decoration: BoxDecoration(
|
|
50
|
-
border: Border.all(color: context.colors.outline),
|
|
51
|
-
shape: BoxShape.circle,
|
|
52
|
-
),
|
|
53
|
-
child: RawMaterialButton(
|
|
54
|
-
elevation: 0,
|
|
55
|
-
focusElevation: 0,
|
|
56
|
-
hoverElevation: 0,
|
|
57
|
-
highlightElevation: 0,
|
|
58
|
-
splashColor: Colors.transparent,
|
|
59
|
-
highlightColor: Colors.transparent,
|
|
60
|
-
hoverColor: Colors.transparent,
|
|
61
|
-
focusColor: Colors.transparent,
|
|
62
|
-
onPressed: () {
|
|
63
|
-
KasyHaptics.medium(context);
|
|
64
|
-
onPressed?.call();
|
|
65
|
-
},
|
|
66
|
-
shape: const CircleBorder(),
|
|
67
|
-
fillColor: Colors.transparent,
|
|
68
|
-
padding: const EdgeInsets.all(KasySpacing.md),
|
|
69
|
-
child: iconImage,
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
3
|
-
import 'package:kasy_kit/core/widgets/kasy_hover.dart';
|
|
4
|
-
|
|
5
|
-
class AddFeatureButton extends StatelessWidget {
|
|
6
|
-
final String title;
|
|
7
|
-
final String description;
|
|
8
|
-
final VoidCallback onPressed;
|
|
9
|
-
|
|
10
|
-
const AddFeatureButton({
|
|
11
|
-
super.key,
|
|
12
|
-
required this.title,
|
|
13
|
-
required this.description,
|
|
14
|
-
required this.onPressed,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
@override
|
|
18
|
-
Widget build(BuildContext context) {
|
|
19
|
-
return KasyHover(
|
|
20
|
-
onTap: onPressed,
|
|
21
|
-
borderRadius: KasyRadius.mdBorderRadius,
|
|
22
|
-
pressColor: context.colors.onPrimary,
|
|
23
|
-
focusable: true,
|
|
24
|
-
child: Container(
|
|
25
|
-
padding: const EdgeInsets.symmetric(
|
|
26
|
-
horizontal: KasySpacing.lg,
|
|
27
|
-
vertical: KasySpacing.smd,
|
|
28
|
-
),
|
|
29
|
-
decoration: BoxDecoration(
|
|
30
|
-
color: context.colors.primary,
|
|
31
|
-
borderRadius: KasyRadius.mdBorderRadius,
|
|
32
|
-
),
|
|
33
|
-
child: Row(
|
|
34
|
-
children: [
|
|
35
|
-
Expanded(
|
|
36
|
-
child: Column(
|
|
37
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
38
|
-
spacing: KasySpacing.xs,
|
|
39
|
-
children: [
|
|
40
|
-
Text(
|
|
41
|
-
title,
|
|
42
|
-
style: context.textTheme.titleMedium?.copyWith(
|
|
43
|
-
color: context.colors.onPrimary,
|
|
44
|
-
),
|
|
45
|
-
),
|
|
46
|
-
Text(
|
|
47
|
-
description,
|
|
48
|
-
style: context.textTheme.bodySmall?.copyWith(
|
|
49
|
-
color: context.colors.onPrimary.withValues(alpha: 0.72),
|
|
50
|
-
),
|
|
51
|
-
),
|
|
52
|
-
],
|
|
53
|
-
),
|
|
54
|
-
),
|
|
55
|
-
const SizedBox(width: KasySpacing.smd),
|
|
56
|
-
Icon(
|
|
57
|
-
KasyIcons.northEast,
|
|
58
|
-
size: KasyIconSize.rowTrailing,
|
|
59
|
-
color: context.colors.onPrimary.withValues(alpha: 0.55),
|
|
60
|
-
),
|
|
61
|
-
],
|
|
62
|
-
),
|
|
63
|
-
),
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
}
|
package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
3
|
-
import 'package:kasy_kit/components/kasy_bottom_sheet.dart';
|
|
4
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
5
|
-
import 'package:kasy_kit/features/notifications/providers/models/notification.dart';
|
|
6
|
-
import 'package:kasy_kit/features/notifications/providers/notifications_provider.dart';
|
|
7
|
-
import 'package:kasy_kit/features/notifications/repositories/notifications_repository.dart';
|
|
8
|
-
import 'package:kasy_kit/features/settings/ui/widgets/settings_tile.dart';
|
|
9
|
-
import 'package:kasy_kit/i18n/translations.g.dart';
|
|
10
|
-
|
|
11
|
-
void showNotificationSettingsSheet(BuildContext context) {
|
|
12
|
-
showKasyBottomSheet<void>(
|
|
13
|
-
context: context,
|
|
14
|
-
isScrollControlled: true,
|
|
15
|
-
builder: (_) => const _NotificationSettingsSheet(),
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
class _NotificationSettingsSheet extends ConsumerStatefulWidget {
|
|
20
|
-
const _NotificationSettingsSheet();
|
|
21
|
-
|
|
22
|
-
@override
|
|
23
|
-
ConsumerState<_NotificationSettingsSheet> createState() =>
|
|
24
|
-
_NotificationSettingsSheetState();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class _NotificationSettingsSheetState
|
|
28
|
-
extends ConsumerState<_NotificationSettingsSheet> {
|
|
29
|
-
NotificationPermission? _permission;
|
|
30
|
-
bool _toggling = false;
|
|
31
|
-
|
|
32
|
-
@override
|
|
33
|
-
void initState() {
|
|
34
|
-
super.initState();
|
|
35
|
-
_loadPermission();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
Future<void> _loadPermission() async {
|
|
39
|
-
final p =
|
|
40
|
-
await ref.read(notificationRepositoryProvider).getPermissionStatus();
|
|
41
|
-
if (mounted) setState(() => _permission = p);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
bool get _isEnabled => _permission is NotificationPermissionGranted;
|
|
45
|
-
|
|
46
|
-
String _subtitle(BuildContext context) {
|
|
47
|
-
final tr = context.t.notifications;
|
|
48
|
-
return switch (_permission) {
|
|
49
|
-
NotificationPermissionGranted() => tr.push_subtitle_enabled,
|
|
50
|
-
NotificationPermissionDenied() => tr.push_subtitle_disabled,
|
|
51
|
-
_ => tr.push_subtitle_waiting,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
Future<void> _onToggle(bool value) async {
|
|
56
|
-
if (_toggling || _permission == null) return;
|
|
57
|
-
setState(() => _toggling = true);
|
|
58
|
-
await _permission!.maybeAsk();
|
|
59
|
-
await _loadPermission();
|
|
60
|
-
if (mounted) setState(() => _toggling = false);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
Future<void> _markAllRead() async {
|
|
64
|
-
await ref.read(notificationsProvider.notifier).readAll();
|
|
65
|
-
if (mounted) Navigator.of(context).pop();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@override
|
|
69
|
-
Widget build(BuildContext context) {
|
|
70
|
-
final tr = context.t.notifications;
|
|
71
|
-
final notificationsState = ref.watch(notificationsProvider);
|
|
72
|
-
final hasUnread =
|
|
73
|
-
notificationsState.value?.data.any((n) => !n.seen) ?? false;
|
|
74
|
-
|
|
75
|
-
final bool floating = kasySheetIsFloating(context);
|
|
76
|
-
|
|
77
|
-
final Widget card = Container(
|
|
78
|
-
margin: floating
|
|
79
|
-
? EdgeInsets.zero
|
|
80
|
-
: EdgeInsets.only(
|
|
81
|
-
left: KasySpacing.sm,
|
|
82
|
-
right: KasySpacing.sm,
|
|
83
|
-
bottom: MediaQuery.of(context).viewInsets.bottom +
|
|
84
|
-
MediaQuery.of(context).padding.bottom +
|
|
85
|
-
KasySpacing.sm,
|
|
86
|
-
),
|
|
87
|
-
decoration: BoxDecoration(
|
|
88
|
-
color: context.colors.background,
|
|
89
|
-
borderRadius: KasyRadius.lgBorderRadius,
|
|
90
|
-
border: Border.all(
|
|
91
|
-
color: context.colors.outline.withValues(alpha: 0.5),
|
|
92
|
-
),
|
|
93
|
-
),
|
|
94
|
-
child: Column(
|
|
95
|
-
mainAxisSize: MainAxisSize.min,
|
|
96
|
-
children: [
|
|
97
|
-
// drag handle (bottom-sheet form only)
|
|
98
|
-
if (!floating)
|
|
99
|
-
Padding(
|
|
100
|
-
padding: const EdgeInsets.only(top: KasySpacing.smd),
|
|
101
|
-
child: Container(
|
|
102
|
-
width: 36,
|
|
103
|
-
height: 4,
|
|
104
|
-
decoration: BoxDecoration(
|
|
105
|
-
color: context.colors.onSurface.withValues(alpha: 0.14),
|
|
106
|
-
borderRadius: KasyRadius.fullBorderRadius,
|
|
107
|
-
),
|
|
108
|
-
),
|
|
109
|
-
),
|
|
110
|
-
Padding(
|
|
111
|
-
padding: const EdgeInsets.fromLTRB(
|
|
112
|
-
KasySpacing.md,
|
|
113
|
-
KasySpacing.md,
|
|
114
|
-
KasySpacing.md,
|
|
115
|
-
KasySpacing.smd,
|
|
116
|
-
),
|
|
117
|
-
child: Column(
|
|
118
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
119
|
-
children: [
|
|
120
|
-
// Push toggle row
|
|
121
|
-
SettingsSwitchTile(
|
|
122
|
-
icon: _isEnabled
|
|
123
|
-
? KasyIcons.notificationActive
|
|
124
|
-
: KasyIcons.notification,
|
|
125
|
-
title: tr.push_title,
|
|
126
|
-
value: _isEnabled,
|
|
127
|
-
iconBackgroundColor: _isEnabled
|
|
128
|
-
? const Color(0xFFFF6B35) // design-check: ignore — category accent
|
|
129
|
-
: const Color(0xFF78909C), // design-check: ignore — category accent
|
|
130
|
-
onChanged: _toggling ? (_) {} : _onToggle,
|
|
131
|
-
),
|
|
132
|
-
// subtitle below
|
|
133
|
-
Padding(
|
|
134
|
-
padding: const EdgeInsets.only(
|
|
135
|
-
left: 32 + KasySpacing.sm,
|
|
136
|
-
bottom: KasySpacing.xs,
|
|
137
|
-
),
|
|
138
|
-
child: _permission == null
|
|
139
|
-
? SizedBox(
|
|
140
|
-
height: 13,
|
|
141
|
-
width: 140,
|
|
142
|
-
child: LinearProgressIndicator(
|
|
143
|
-
borderRadius: BorderRadius.circular(4),
|
|
144
|
-
color: context.colors.primary.withValues(alpha: 0.25),
|
|
145
|
-
backgroundColor: context.colors.onSurface
|
|
146
|
-
.withValues(alpha: 0.06),
|
|
147
|
-
),
|
|
148
|
-
)
|
|
149
|
-
: Text(
|
|
150
|
-
_subtitle(context),
|
|
151
|
-
style: context.textTheme.bodySmall?.copyWith(
|
|
152
|
-
color: context.colors.muted,
|
|
153
|
-
),
|
|
154
|
-
),
|
|
155
|
-
),
|
|
156
|
-
if (hasUnread) ...[
|
|
157
|
-
const SettingsDivider(),
|
|
158
|
-
const SizedBox(height: KasySpacing.xs),
|
|
159
|
-
SettingsTile(
|
|
160
|
-
icon: KasyIcons.checkCircle,
|
|
161
|
-
title: tr.mark_all_read,
|
|
162
|
-
iconBackgroundColor: context.colors.primary,
|
|
163
|
-
onTap: _markAllRead,
|
|
164
|
-
),
|
|
165
|
-
],
|
|
166
|
-
],
|
|
167
|
-
),
|
|
168
|
-
),
|
|
169
|
-
],
|
|
170
|
-
),
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
if (!floating) return card;
|
|
174
|
-
return ConstrainedBox(
|
|
175
|
-
constraints: const BoxConstraints(maxWidth: 420),
|
|
176
|
-
child: card,
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
}
|
package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import 'package:flutter/material.dart';
|
|
2
|
-
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
3
|
-
import 'package:kasy_kit/core/theme/theme.dart';
|
|
4
|
-
import 'package:kasy_kit/features/notifications/providers/models/notification.dart';
|
|
5
|
-
import 'package:kasy_kit/features/notifications/repositories/notifications_repository.dart';
|
|
6
|
-
import 'package:kasy_kit/features/settings/ui/widgets/settings_tile.dart';
|
|
7
|
-
import 'package:kasy_kit/i18n/translations.g.dart';
|
|
8
|
-
|
|
9
|
-
class PushNotificationSwitcher extends ConsumerStatefulWidget {
|
|
10
|
-
const PushNotificationSwitcher({super.key});
|
|
11
|
-
|
|
12
|
-
@override
|
|
13
|
-
ConsumerState<PushNotificationSwitcher> createState() =>
|
|
14
|
-
_PushNotificationSwitcherState();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class _PushNotificationSwitcherState
|
|
18
|
-
extends ConsumerState<PushNotificationSwitcher> {
|
|
19
|
-
NotificationPermission? _permission;
|
|
20
|
-
bool _loading = false;
|
|
21
|
-
|
|
22
|
-
@override
|
|
23
|
-
void initState() {
|
|
24
|
-
super.initState();
|
|
25
|
-
_loadPermission();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
Future<void> _loadPermission() async {
|
|
29
|
-
final p =
|
|
30
|
-
await ref.read(notificationRepositoryProvider).getPermissionStatus();
|
|
31
|
-
if (mounted) setState(() => _permission = p);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
bool get _isEnabled => _permission is NotificationPermissionGranted;
|
|
35
|
-
|
|
36
|
-
String _subtitle(BuildContext context) {
|
|
37
|
-
final tr = context.t.notifications;
|
|
38
|
-
return switch (_permission) {
|
|
39
|
-
NotificationPermissionGranted() => tr.push_subtitle_enabled,
|
|
40
|
-
NotificationPermissionDenied() => tr.push_subtitle_disabled,
|
|
41
|
-
_ => tr.push_subtitle_waiting,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
Future<void> _onChanged(bool value) async {
|
|
46
|
-
if (_loading || _permission == null) return;
|
|
47
|
-
setState(() => _loading = true);
|
|
48
|
-
await _permission!.maybeAsk();
|
|
49
|
-
await _loadPermission();
|
|
50
|
-
if (mounted) setState(() => _loading = false);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@override
|
|
54
|
-
Widget build(BuildContext context) {
|
|
55
|
-
final tr = context.t.notifications;
|
|
56
|
-
return Container(
|
|
57
|
-
padding: const EdgeInsets.symmetric(
|
|
58
|
-
vertical: KasySpacing.smd,
|
|
59
|
-
horizontal: KasySpacing.md,
|
|
60
|
-
),
|
|
61
|
-
decoration: BoxDecoration(
|
|
62
|
-
borderRadius: KasyRadius.smBorderRadius,
|
|
63
|
-
color: context.colors.surface,
|
|
64
|
-
),
|
|
65
|
-
child: Column(
|
|
66
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
67
|
-
children: [
|
|
68
|
-
SettingsSwitchTile(
|
|
69
|
-
icon: _isEnabled
|
|
70
|
-
? KasyIcons.notificationActive
|
|
71
|
-
: KasyIcons.notification,
|
|
72
|
-
title: tr.push_title,
|
|
73
|
-
value: _isEnabled,
|
|
74
|
-
iconBackgroundColor: _isEnabled
|
|
75
|
-
? const Color(0xFFFF6B35) // design-check: ignore — category accent
|
|
76
|
-
: const Color(0xFF78909C), // design-check: ignore — category accent
|
|
77
|
-
onChanged: _loading ? (_) {} : _onChanged,
|
|
78
|
-
),
|
|
79
|
-
Padding(
|
|
80
|
-
padding: const EdgeInsets.only(
|
|
81
|
-
left: 32 + KasySpacing.sm,
|
|
82
|
-
bottom: KasySpacing.xs,
|
|
83
|
-
),
|
|
84
|
-
child: _permission == null
|
|
85
|
-
? SizedBox(
|
|
86
|
-
height: 14,
|
|
87
|
-
width: 120,
|
|
88
|
-
child: LinearProgressIndicator(
|
|
89
|
-
borderRadius: BorderRadius.circular(4),
|
|
90
|
-
color: context.colors.primary.withValues(alpha: 0.3),
|
|
91
|
-
backgroundColor:
|
|
92
|
-
context.colors.onSurface.withValues(alpha: 0.06),
|
|
93
|
-
),
|
|
94
|
-
)
|
|
95
|
-
: Text(
|
|
96
|
-
_subtitle(context),
|
|
97
|
-
style: context.textTheme.bodySmall?.copyWith(
|
|
98
|
-
color: context.colors.muted,
|
|
99
|
-
),
|
|
100
|
-
),
|
|
101
|
-
),
|
|
102
|
-
],
|
|
103
|
-
),
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
}
|