kasy-cli 1.37.1 → 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 +23 -0
- package/lib/scaffold/backends/api/patch/README.md +15 -0
- package/lib/scaffold/backends/api/patch/lib/core/data/api/user_api.dart +18 -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/core/data/api/user_api.dart +8 -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/AGENTS.md +7 -1
- package/templates/firebase/DESIGN_SYSTEM.md +35 -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 +361 -20
- package/templates/firebase/lib/components/kasy_bottom_sheet.dart +283 -66
- package/templates/firebase/lib/components/kasy_card.dart +4 -0
- package/templates/firebase/lib/components/kasy_date_picker.dart +61 -46
- package/templates/firebase/lib/components/kasy_drop_down.dart +584 -0
- package/templates/firebase/lib/components/kasy_sidebar.dart +412 -31
- 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 +29 -231
- package/templates/firebase/lib/core/bottom_menu/sidebar_focus.dart +224 -0
- package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +19 -9
- 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 +15 -0
- package/templates/firebase/lib/core/data/repositories/user_repository.dart +5 -0
- package/templates/firebase/lib/core/dev_inspector/dev_inspector.dart +525 -65
- package/templates/firebase/lib/core/dev_inspector/dev_inspector_info.dart +47 -0
- package/templates/firebase/lib/core/dev_inspector/dev_inspector_service.dart +55 -15
- package/templates/firebase/lib/core/icons/kasy_icons.dart +16 -1
- 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 +69 -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/theme/universal_theme.dart +9 -0
- package/templates/firebase/lib/core/web_device_preview/png_clipboard.dart +14 -0
- package/templates/firebase/lib/core/web_device_preview/png_clipboard_io.dart +9 -0
- package/templates/firebase/lib/core/web_device_preview/png_clipboard_web.dart +36 -0
- package/templates/firebase/lib/core/web_device_preview/png_export_result.dart +2 -0
- package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +547 -483
- 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/core/widgets/responsive_layout.dart +8 -0
- 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 +264 -126
- 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 +118 -57
- package/templates/firebase/lib/features/notifications/api/device_api.dart +11 -3
- package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +19 -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 +262 -0
- 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 +99 -65
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +1379 -422
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_routes.dart +14 -4
- 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 +404 -149
- package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +24 -31
- 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 +77 -95
- 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 -698
- package/templates/firebase/lib/i18n/es.i18n.json +749 -698
- package/templates/firebase/lib/i18n/pt.i18n.json +749 -698
- package/templates/firebase/lib/main.dart +20 -7
- package/templates/firebase/lib/router.dart +70 -46
- package/templates/firebase/pubspec.yaml +2 -1
- package/templates/firebase/test/admin_shell_chrome_test.dart +110 -0
- 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/test/features/authentication/data/api/user_api_fake.dart +3 -0
- 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 -210
- 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 -169
- package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +0 -106
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_paywalls.dart +0 -53
|
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
|
|
5
5
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
6
6
|
import 'package:image_picker/image_picker.dart';
|
|
7
7
|
import 'package:kasy_kit/components/kasy_avatar.dart';
|
|
8
|
+
import 'package:kasy_kit/components/kasy_bottom_sheet.dart';
|
|
8
9
|
import 'package:kasy_kit/core/data/entities/upload_result.dart';
|
|
9
10
|
import 'package:kasy_kit/core/data/models/user.dart';
|
|
10
11
|
import 'package:kasy_kit/core/data/repositories/user_repository.dart';
|
|
@@ -12,6 +13,7 @@ import 'package:kasy_kit/core/states/models/user_state.dart';
|
|
|
12
13
|
import 'package:kasy_kit/core/states/user_state_notifier.dart';
|
|
13
14
|
import 'package:kasy_kit/core/theme/theme.dart';
|
|
14
15
|
import 'package:kasy_kit/core/widgets/kasy_focus_ring.dart';
|
|
16
|
+
import 'package:kasy_kit/core/widgets/kasy_hover.dart';
|
|
15
17
|
import 'package:kasy_kit/features/settings/ui/widgets/avatar_utils.dart';
|
|
16
18
|
import 'package:kasy_kit/features/settings/ui/widgets/round_progress.dart';
|
|
17
19
|
import 'package:kasy_kit/i18n/translations.g.dart';
|
|
@@ -65,7 +67,7 @@ class _EditableUserAvatarState extends ConsumerState<EditableUserAvatar> {
|
|
|
65
67
|
return KasyFocusRing(
|
|
66
68
|
enabled: onTapAvatar != null,
|
|
67
69
|
onActivate: onTapAvatar,
|
|
68
|
-
borderRadius: BorderRadius.circular(
|
|
70
|
+
borderRadius: BorderRadius.circular(KasyRadius.full),
|
|
69
71
|
child: GestureDetector(
|
|
70
72
|
behavior: HitTestBehavior.opaque,
|
|
71
73
|
onTap: onTapAvatar,
|
|
@@ -144,14 +146,10 @@ class _EditableUserAvatarState extends ConsumerState<EditableUserAvatar> {
|
|
|
144
146
|
BuildContext context, {
|
|
145
147
|
required bool hasAvatar,
|
|
146
148
|
}) {
|
|
147
|
-
return
|
|
149
|
+
return showKasyBottomSheet<_AvatarAction>(
|
|
148
150
|
context: context,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
shape: const RoundedRectangleBorder(
|
|
152
|
-
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
|
153
|
-
),
|
|
154
|
-
builder: (sheetContext) => SafeArea(
|
|
151
|
+
builder: (sheetContext) => KasySheetSurface(
|
|
152
|
+
showDragHandle: false,
|
|
155
153
|
child: Padding(
|
|
156
154
|
padding: const EdgeInsets.symmetric(vertical: KasySpacing.sm),
|
|
157
155
|
child: Column(
|
|
@@ -321,31 +319,26 @@ class _BottomSheetTile extends StatelessWidget {
|
|
|
321
319
|
@override
|
|
322
320
|
Widget build(BuildContext context) {
|
|
323
321
|
final Color fg = color ?? context.colors.onSurface;
|
|
324
|
-
return
|
|
325
|
-
|
|
322
|
+
return KasyHover(
|
|
323
|
+
onTap: onTap,
|
|
324
|
+
focusable: true,
|
|
325
|
+
focusGapColor: context.colors.surface,
|
|
326
326
|
borderRadius: BorderRadius.circular(KasyRadius.sm),
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const SizedBox(width: KasySpacing.sm),
|
|
341
|
-
],
|
|
342
|
-
Text(
|
|
343
|
-
label,
|
|
344
|
-
style: context.textTheme.bodyLarge?.copyWith(color: fg),
|
|
345
|
-
),
|
|
346
|
-
],
|
|
327
|
+
padding: const EdgeInsets.symmetric(
|
|
328
|
+
horizontal: KasySpacing.md,
|
|
329
|
+
vertical: KasySpacing.smd,
|
|
330
|
+
),
|
|
331
|
+
child: Row(
|
|
332
|
+
children: [
|
|
333
|
+
if (icon != null) ...[
|
|
334
|
+
Icon(icon, size: KasyIconSize.lg, color: fg),
|
|
335
|
+
const SizedBox(width: KasySpacing.sm),
|
|
336
|
+
],
|
|
337
|
+
Text(
|
|
338
|
+
label,
|
|
339
|
+
style: context.textTheme.bodyLarge?.copyWith(color: fg),
|
|
347
340
|
),
|
|
348
|
-
|
|
341
|
+
],
|
|
349
342
|
),
|
|
350
343
|
);
|
|
351
344
|
}
|
|
@@ -4,6 +4,7 @@ import 'package:kasy_kit/components/components.dart';
|
|
|
4
4
|
import 'package:kasy_kit/core/states/user_state_notifier.dart';
|
|
5
5
|
import 'package:kasy_kit/core/theme/theme.dart';
|
|
6
6
|
import 'package:kasy_kit/i18n/translations.g.dart';
|
|
7
|
+
import 'package:kasy_kit/router.dart';
|
|
7
8
|
|
|
8
9
|
class DeleteUserButton extends ConsumerWidget {
|
|
9
10
|
const DeleteUserButton({super.key});
|
|
@@ -40,7 +41,14 @@ class DeleteUserButton extends ConsumerWidget {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
},
|
|
43
|
-
)
|
|
44
|
+
).whenComplete(() {
|
|
45
|
+
// Same pageless-dialog issue as logout: on success deleteAccount flips
|
|
46
|
+
// the state to anonymous while this confirm dialog still sits on the
|
|
47
|
+
// root navigator, so the redirect to /signin can't land. Re-run it
|
|
48
|
+
// once the dialog has popped. Harmless when the user cancels or the
|
|
49
|
+
// deletion failed (still authenticated → redirect keeps them here).
|
|
50
|
+
if (context.mounted) ref.read(goRouterProvider).refresh();
|
|
51
|
+
});
|
|
44
52
|
},
|
|
45
53
|
);
|
|
46
54
|
}
|
|
@@ -2,10 +2,11 @@ import 'dart:async';
|
|
|
2
2
|
|
|
3
3
|
import 'package:flutter/material.dart';
|
|
4
4
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
5
|
+
import 'package:kasy_kit/components/kasy_bottom_sheet.dart';
|
|
5
6
|
import 'package:kasy_kit/core/home_widgets/home_widget_mywidget_service.dart';
|
|
6
7
|
import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
|
|
7
8
|
import 'package:kasy_kit/core/theme/theme.dart';
|
|
8
|
-
import 'package:kasy_kit/core/widgets/
|
|
9
|
+
import 'package:kasy_kit/core/widgets/kasy_hover.dart';
|
|
9
10
|
import 'package:kasy_kit/features/settings/ui/widgets/settings_tile.dart';
|
|
10
11
|
import 'package:kasy_kit/i18n/app_locale_display.dart';
|
|
11
12
|
import 'package:kasy_kit/i18n/translations.g.dart';
|
|
@@ -18,41 +19,41 @@ class LanguageSwitcher extends ConsumerWidget {
|
|
|
18
19
|
@override
|
|
19
20
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
20
21
|
final AppLocale current = TranslationProvider.of(context).locale;
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
return KasyHover(
|
|
23
|
+
onTap: () => _showLanguagePicker(context, ref, current),
|
|
24
|
+
focusable: true,
|
|
25
|
+
// Rectangular highlight (KasyHover default): this row lives inside a card,
|
|
26
|
+
// whose rounded corners clip the ends — a rounded fill here would float.
|
|
27
|
+
semanticLabel: context.t.settings.language_title,
|
|
28
|
+
padding: const EdgeInsets.symmetric(
|
|
29
|
+
horizontal: KasySpacing.md,
|
|
30
|
+
vertical: KasySpacing.smd,
|
|
31
|
+
),
|
|
32
|
+
child: Row(
|
|
33
|
+
children: <Widget>[
|
|
34
|
+
Icon(
|
|
35
|
+
KasyIcons.language,
|
|
36
|
+
size: KasyIconSize.rowLeading,
|
|
37
|
+
color: context.colors.onSurface,
|
|
38
|
+
),
|
|
39
|
+
const SizedBox(width: KasySpacing.sm),
|
|
40
|
+
Expanded(
|
|
41
|
+
child: Text(
|
|
42
|
+
context.t.settings.language_title,
|
|
43
|
+
style: context.kasyTextTheme.listRowTitle.copyWith(
|
|
34
44
|
color: context.colors.onSurface,
|
|
35
45
|
),
|
|
36
|
-
|
|
37
|
-
Expanded(
|
|
38
|
-
child: Text(
|
|
39
|
-
context.t.settings.language_title,
|
|
40
|
-
style: context.textTheme.titleSmall?.copyWith(
|
|
41
|
-
color: context.colors.onSurface,
|
|
42
|
-
),
|
|
43
|
-
),
|
|
44
|
-
),
|
|
45
|
-
Text(
|
|
46
|
-
current.nativeName,
|
|
47
|
-
style: context.textTheme.bodyMedium?.copyWith(
|
|
48
|
-
color: context.colors.muted,
|
|
49
|
-
),
|
|
50
|
-
),
|
|
51
|
-
const SizedBox(width: KasySpacing.xs),
|
|
52
|
-
const SettingsListChevron(),
|
|
53
|
-
],
|
|
46
|
+
),
|
|
54
47
|
),
|
|
55
|
-
|
|
48
|
+
Text(
|
|
49
|
+
current.nativeName,
|
|
50
|
+
style: context.kasyTextTheme.listRowValue.copyWith(
|
|
51
|
+
color: context.colors.muted,
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
const SizedBox(width: KasySpacing.xs),
|
|
55
|
+
const SettingsListChevron(),
|
|
56
|
+
],
|
|
56
57
|
),
|
|
57
58
|
);
|
|
58
59
|
}
|
|
@@ -63,39 +64,26 @@ class LanguageSwitcher extends ConsumerWidget {
|
|
|
63
64
|
AppLocale current,
|
|
64
65
|
) {
|
|
65
66
|
final String sheetTitle = context.t.settings.language_title;
|
|
66
|
-
|
|
67
|
+
showKasyBottomSheet<void>(
|
|
67
68
|
context: context,
|
|
68
|
-
|
|
69
|
-
backgroundColor: context.colors.surface,
|
|
70
|
-
shape: const RoundedRectangleBorder(
|
|
71
|
-
borderRadius: BorderRadius.vertical(top: Radius.circular(KasyRadius.lg)),
|
|
72
|
-
),
|
|
73
|
-
builder: (sheetContext) => SafeArea(
|
|
69
|
+
builder: (sheetContext) => KasySheetSurface(
|
|
74
70
|
child: Padding(
|
|
75
|
-
padding:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
KasySpacing.sm,
|
|
80
|
-
),
|
|
71
|
+
// No horizontal padding: option rows go full-bleed so the highlight
|
|
72
|
+
// spans the whole sheet (no inset pill). Title and rows carry their
|
|
73
|
+
// own horizontal inset instead.
|
|
74
|
+
padding: const EdgeInsets.symmetric(vertical: KasySpacing.sm),
|
|
81
75
|
child: Column(
|
|
82
76
|
mainAxisSize: MainAxisSize.min,
|
|
83
77
|
children: <Widget>[
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Align(
|
|
94
|
-
alignment: Alignment.centerLeft,
|
|
95
|
-
child: Text(
|
|
96
|
-
sheetTitle,
|
|
97
|
-
style: sheetContext.textTheme.titleMedium?.copyWith(
|
|
98
|
-
color: sheetContext.colors.onSurface,
|
|
78
|
+
Padding(
|
|
79
|
+
padding: const EdgeInsets.symmetric(horizontal: KasySpacing.md),
|
|
80
|
+
child: Align(
|
|
81
|
+
alignment: Alignment.centerLeft,
|
|
82
|
+
child: Text(
|
|
83
|
+
sheetTitle,
|
|
84
|
+
style: sheetContext.textTheme.titleMedium?.copyWith(
|
|
85
|
+
color: sheetContext.colors.onSurface,
|
|
86
|
+
),
|
|
99
87
|
),
|
|
100
88
|
),
|
|
101
89
|
),
|
|
@@ -156,42 +144,36 @@ class _LocaleOptionTile extends StatelessWidget {
|
|
|
156
144
|
final Color primary = context.colors.primary;
|
|
157
145
|
final Color fg = isSelected ? primary : context.colors.onSurface;
|
|
158
146
|
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
style: context.textTheme.bodyLarge?.copyWith(
|
|
177
|
-
color: fg,
|
|
178
|
-
fontWeight:
|
|
179
|
-
isSelected ? FontWeight.w600 : FontWeight.w400,
|
|
180
|
-
),
|
|
181
|
-
),
|
|
147
|
+
return KasyHover(
|
|
148
|
+
onTap: onTap,
|
|
149
|
+
focusable: true,
|
|
150
|
+
// Full-bleed rectangular highlight (default radius): the sheet rounds its
|
|
151
|
+
// own corners, so options span edge-to-edge like a native menu/list.
|
|
152
|
+
padding: const EdgeInsets.symmetric(
|
|
153
|
+
horizontal: KasySpacing.md,
|
|
154
|
+
vertical: KasySpacing.smd,
|
|
155
|
+
),
|
|
156
|
+
child: Row(
|
|
157
|
+
children: <Widget>[
|
|
158
|
+
Expanded(
|
|
159
|
+
child: Text(
|
|
160
|
+
locale.nativeName,
|
|
161
|
+
style: context.textTheme.bodyLarge?.copyWith(
|
|
162
|
+
color: fg,
|
|
163
|
+
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
|
|
182
164
|
),
|
|
183
|
-
|
|
184
|
-
Container(
|
|
185
|
-
width: 10,
|
|
186
|
-
height: 10,
|
|
187
|
-
decoration: BoxDecoration(
|
|
188
|
-
color: primary,
|
|
189
|
-
shape: BoxShape.circle,
|
|
190
|
-
),
|
|
191
|
-
),
|
|
192
|
-
],
|
|
165
|
+
),
|
|
193
166
|
),
|
|
194
|
-
|
|
167
|
+
if (isSelected)
|
|
168
|
+
Container(
|
|
169
|
+
width: 10,
|
|
170
|
+
height: 10,
|
|
171
|
+
decoration: BoxDecoration(
|
|
172
|
+
color: primary,
|
|
173
|
+
shape: BoxShape.circle,
|
|
174
|
+
),
|
|
175
|
+
),
|
|
176
|
+
],
|
|
195
177
|
),
|
|
196
178
|
);
|
|
197
179
|
}
|
package/templates/firebase/lib/features/settings/ui/widgets/settings_bottom_sheet_option_tile.dart
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import 'package:flutter/material.dart';
|
|
2
2
|
import 'package:kasy_kit/core/theme/theme.dart';
|
|
3
|
+
import 'package:kasy_kit/core/widgets/kasy_hover.dart';
|
|
3
4
|
|
|
4
5
|
/// Row used in settings modal bottom sheets (avatar source, language, etc.).
|
|
5
6
|
class SettingsBottomSheetOptionTile extends StatelessWidget {
|
|
@@ -26,26 +27,28 @@ class SettingsBottomSheetOptionTile extends StatelessWidget {
|
|
|
26
27
|
final TextStyle? labelStyle =
|
|
27
28
|
context.textTheme.titleMedium?.copyWith(color: fg);
|
|
28
29
|
final Text labelWidget = Text(label, style: labelStyle);
|
|
29
|
-
return
|
|
30
|
+
return KasyHover(
|
|
30
31
|
onTap: onTap,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
focusable: true,
|
|
33
|
+
semanticLabel: label,
|
|
34
|
+
// Full-bleed rectangular highlight (default radius): these rows live in a
|
|
35
|
+
// bottom sheet whose rounded corners clip the ends, like a native menu.
|
|
36
|
+
padding: const EdgeInsets.symmetric(
|
|
37
|
+
horizontal: KasySpacing.md,
|
|
38
|
+
vertical: KasySpacing.smd,
|
|
39
|
+
),
|
|
40
|
+
child: Row(
|
|
41
|
+
children: <Widget>[
|
|
42
|
+
if (leading != null) ...<Widget>[
|
|
43
|
+
leading!,
|
|
44
|
+
const SizedBox(width: KasySpacing.sm),
|
|
45
|
+
] else if (icon != null) ...<Widget>[
|
|
46
|
+
Icon(icon, size: KasyIconSize.lg, color: fg),
|
|
47
|
+
const SizedBox(width: KasySpacing.sm),
|
|
47
48
|
],
|
|
48
|
-
|
|
49
|
+
Expanded(child: labelWidget),
|
|
50
|
+
if (trailing != null) trailing!,
|
|
51
|
+
],
|
|
49
52
|
),
|
|
50
53
|
);
|
|
51
54
|
}
|
|
@@ -26,7 +26,7 @@ class SettingsIconBadge extends StatelessWidget {
|
|
|
26
26
|
height: size,
|
|
27
27
|
decoration: BoxDecoration(
|
|
28
28
|
color: color.withValues(alpha: 0.12),
|
|
29
|
-
borderRadius: BorderRadius.circular(
|
|
29
|
+
borderRadius: BorderRadius.circular(KasyRadius.sm),
|
|
30
30
|
),
|
|
31
31
|
child: Icon(
|
|
32
32
|
icon,
|
|
@@ -65,7 +65,17 @@ class SettingsDivider extends StatelessWidget {
|
|
|
65
65
|
|
|
66
66
|
@override
|
|
67
67
|
Widget build(BuildContext context) {
|
|
68
|
-
|
|
68
|
+
// Inset to align with the rows' content (which now carry the horizontal
|
|
69
|
+
// padding the card used to have), so the hairline doesn't touch the edges.
|
|
70
|
+
return Divider(
|
|
71
|
+
// Hairline only — no extra height — so rows sit close together (iOS-style
|
|
72
|
+
// contiguous list) instead of floating apart with a 16px gap.
|
|
73
|
+
height: 1,
|
|
74
|
+
thickness: 1,
|
|
75
|
+
color: context.colors.onBackground.withValues(alpha: .06),
|
|
76
|
+
indent: KasySpacing.md,
|
|
77
|
+
endIndent: KasySpacing.md,
|
|
78
|
+
);
|
|
69
79
|
}
|
|
70
80
|
}
|
|
71
81
|
|
|
@@ -91,7 +101,10 @@ class SettingsSwitchTile extends StatelessWidget {
|
|
|
91
101
|
@override
|
|
92
102
|
Widget build(BuildContext context) {
|
|
93
103
|
return Padding(
|
|
94
|
-
padding: const EdgeInsets.symmetric(
|
|
104
|
+
padding: const EdgeInsets.symmetric(
|
|
105
|
+
horizontal: KasySpacing.md,
|
|
106
|
+
vertical: KasySpacing.smd,
|
|
107
|
+
),
|
|
95
108
|
child: Row(
|
|
96
109
|
children: <Widget>[
|
|
97
110
|
if (iconBackgroundColor != null)
|
|
@@ -110,7 +123,7 @@ class SettingsSwitchTile extends StatelessWidget {
|
|
|
110
123
|
children: <Widget>[
|
|
111
124
|
Text(
|
|
112
125
|
title,
|
|
113
|
-
style: context.
|
|
126
|
+
style: context.kasyTextTheme.listRowTitle.copyWith(
|
|
114
127
|
color: context.colors.onSurface,
|
|
115
128
|
),
|
|
116
129
|
),
|
|
@@ -165,12 +178,14 @@ class SettingsTile extends StatelessWidget {
|
|
|
165
178
|
Widget build(BuildContext context) {
|
|
166
179
|
return KasyHover(
|
|
167
180
|
onTap: onTap,
|
|
168
|
-
hoverEnabled: false,
|
|
169
|
-
pressEnabled: false,
|
|
170
181
|
focusable: true,
|
|
171
|
-
|
|
182
|
+
// Rectangular highlight (default): the card clips the rounded ends, so
|
|
183
|
+
// middle rows stay square instead of showing a floating rounded pill.
|
|
172
184
|
semanticLabel: title,
|
|
173
|
-
padding: const EdgeInsets.symmetric(
|
|
185
|
+
padding: const EdgeInsets.symmetric(
|
|
186
|
+
horizontal: KasySpacing.md,
|
|
187
|
+
vertical: KasySpacing.smd,
|
|
188
|
+
),
|
|
174
189
|
child: Row(
|
|
175
190
|
children: [
|
|
176
191
|
if (iconBackgroundColor != null)
|
|
@@ -185,7 +200,7 @@ class SettingsTile extends StatelessWidget {
|
|
|
185
200
|
Expanded(
|
|
186
201
|
child: Text(
|
|
187
202
|
title,
|
|
188
|
-
style: context.
|
|
203
|
+
style: context.kasyTextTheme.listRowTitle.copyWith(
|
|
189
204
|
color: context.colors.onSurface,
|
|
190
205
|
),
|
|
191
206
|
),
|
|
@@ -193,7 +208,7 @@ class SettingsTile extends StatelessWidget {
|
|
|
193
208
|
if (trailingLabel != null) ...[
|
|
194
209
|
Text(
|
|
195
210
|
trailingLabel!,
|
|
196
|
-
style: context.
|
|
211
|
+
style: context.kasyTextTheme.listRowValue.copyWith(
|
|
197
212
|
color: context.colors.muted,
|
|
198
213
|
),
|
|
199
214
|
),
|