kasy-cli 1.32.0 → 1.34.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 +42 -0
- package/lib/commands/apple-web.js +222 -0
- package/lib/commands/configure.js +3 -91
- package/lib/commands/doctor.js +20 -0
- package/lib/commands/facebook.js +189 -0
- package/lib/commands/new.js +50 -2
- package/lib/scaffold/CHANGELOG.json +18 -0
- package/lib/scaffold/backends/firebase/setup-from-scratch.js +164 -0
- package/lib/scaffold/backends/supabase/deploy.js +92 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +10 -0
- package/lib/scaffold/shared/generator-utils.js +18 -6
- package/lib/utils/apple-web.js +147 -0
- package/lib/utils/facebook.js +162 -0
- package/lib/utils/i18n/messages-en.js +62 -0
- package/lib/utils/i18n/messages-es.js +62 -0
- package/lib/utils/i18n/messages-pt.js +62 -0
- package/package.json +2 -2
- package/templates/firebase/AGENTS.md +87 -0
- package/templates/firebase/CLAUDE.md +16 -0
- package/templates/firebase/DESIGN_SYSTEM.md +234 -0
- package/templates/firebase/docs/auth-setup.en.md +2 -2
- package/templates/firebase/docs/auth-setup.es.md +2 -2
- package/templates/firebase/docs/auth-setup.pt.md +2 -2
- package/templates/firebase/lib/components/components.dart +1 -0
- package/templates/firebase/lib/components/kasy_app_bar.dart +4 -1
- package/templates/firebase/lib/components/kasy_screen.dart +114 -0
- package/templates/firebase/lib/components/kasy_toast.dart +39 -70
- package/templates/firebase/lib/core/chrome/chrome_visibility.dart +22 -0
- package/templates/firebase/lib/core/config/features.dart +5 -0
- package/templates/firebase/lib/core/rating/widgets/review_popup.dart +46 -124
- package/templates/firebase/lib/core/widgets/update_bottom_sheet.dart +29 -126
- package/templates/firebase/lib/features/ai_chat/ai_chat_page.dart +11 -7
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_composer.dart +21 -0
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +1 -1
- package/templates/firebase/lib/features/authentication/api/authentication_api.dart +61 -0
- package/templates/firebase/lib/features/authentication/ui/signin_page.dart +21 -15
- package/templates/firebase/lib/features/authentication/ui/signup_page.dart +20 -14
- package/templates/firebase/lib/features/feedbacks/ui/widgets/feature_card.dart +1 -2
- package/templates/firebase/lib/features/home/home_components_page.dart +7 -1
- package/templates/firebase/lib/features/home/home_components_preview_registry.dart +32 -0
- package/templates/firebase/lib/features/local_reminders/ui/reminder_page.dart +165 -209
- package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart +2 -2
- package/templates/firebase/lib/features/notifications/ui/components/notification_tile.dart +21 -8
- package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +2 -2
- package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +3 -6
- package/templates/firebase/lib/features/notifications/ui/widgets/notification_tile.dart +77 -126
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +3 -4
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +2 -4
- package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +2 -1
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +17 -8
- package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +2 -2
- package/templates/firebase/lib/i18n/en.i18n.json +5 -4
- package/templates/firebase/lib/i18n/es.i18n.json +5 -4
- package/templates/firebase/lib/i18n/pt.i18n.json +5 -4
- package/templates/firebase/lib/router.dart +2 -0
- package/templates/firebase/pubspec.yaml +1 -1
- package/templates/firebase/tool/design_check.dart +152 -0
- package/templates/firebase/assets/images/review.png +0 -0
- package/templates/firebase/assets/images/update.png +0 -0
- package/templates/firebase/lib/features/notifications/ui/components/notifications_header.dart +0 -32
|
@@ -9,8 +9,13 @@ import 'package:kasy_kit/features/notifications/providers/models/notification.da
|
|
|
9
9
|
typedef OnTapNotification = void Function(app.Notification notification);
|
|
10
10
|
|
|
11
11
|
/// A tile for the [NotificationsPage] widget.
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
///
|
|
13
|
+
/// Renders only the row content (icon + title / body / date + unread dot). The
|
|
14
|
+
/// card surface (elevated [KasyCard]) and the tap/hover feedback live in
|
|
15
|
+
/// [NotificationTileComponent], so a notification reads exactly like a Settings
|
|
16
|
+
/// card. Unread vs read is signalled by the trailing dot and text strength, not
|
|
17
|
+
/// by a tinted background.
|
|
18
|
+
class NotificationTile extends StatelessWidget {
|
|
14
19
|
final double titleOpacity;
|
|
15
20
|
final Color titleColor;
|
|
16
21
|
final Color descriptionColor;
|
|
@@ -24,7 +29,6 @@ class NotificationTile extends StatefulWidget {
|
|
|
24
29
|
|
|
25
30
|
const NotificationTile({
|
|
26
31
|
super.key,
|
|
27
|
-
required this.bgOpacity,
|
|
28
32
|
required this.titleOpacity,
|
|
29
33
|
required this.icon,
|
|
30
34
|
required this.date,
|
|
@@ -47,7 +51,6 @@ class NotificationTile extends StatefulWidget {
|
|
|
47
51
|
Key? key,
|
|
48
52
|
}) => NotificationTile(
|
|
49
53
|
key: key,
|
|
50
|
-
bgOpacity: .08,
|
|
51
54
|
titleOpacity: 1,
|
|
52
55
|
showUnreadDot: true,
|
|
53
56
|
icon: imageUrl != null
|
|
@@ -72,7 +75,6 @@ class NotificationTile extends StatefulWidget {
|
|
|
72
75
|
Key? key,
|
|
73
76
|
}) => NotificationTile(
|
|
74
77
|
key: key,
|
|
75
|
-
bgOpacity: 0,
|
|
76
78
|
titleOpacity: .6,
|
|
77
79
|
icon: imageUrl != null
|
|
78
80
|
? TileNotificationImage(url: imageUrl)
|
|
@@ -111,124 +113,66 @@ class NotificationTile extends StatefulWidget {
|
|
|
111
113
|
onTap: onTap,
|
|
112
114
|
);
|
|
113
115
|
|
|
114
|
-
@override
|
|
115
|
-
State<NotificationTile> createState() => _NotificationTileState();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
class _NotificationTileState extends State<NotificationTile>
|
|
119
|
-
with SingleTickerProviderStateMixin {
|
|
120
|
-
late final AnimationController _controller;
|
|
121
|
-
late Animation<double> _opacityAnimation;
|
|
122
|
-
|
|
123
|
-
@override
|
|
124
|
-
void initState() {
|
|
125
|
-
super.initState();
|
|
126
|
-
_controller = AnimationController(
|
|
127
|
-
duration: const Duration(milliseconds: 500),
|
|
128
|
-
vsync: this,
|
|
129
|
-
);
|
|
130
|
-
_opacityAnimation = Tween(
|
|
131
|
-
begin: 0.0,
|
|
132
|
-
end: widget.bgOpacity,
|
|
133
|
-
).animate(CurvedAnimation(parent: _controller, curve: Curves.decelerate));
|
|
134
|
-
_controller.forward();
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
@override
|
|
138
|
-
void didUpdateWidget(covariant NotificationTile oldWidget) {
|
|
139
|
-
super.didUpdateWidget(oldWidget);
|
|
140
|
-
if (oldWidget.bgOpacity != widget.bgOpacity) {
|
|
141
|
-
_opacityAnimation = Tween(
|
|
142
|
-
begin: oldWidget.bgOpacity,
|
|
143
|
-
end: widget.bgOpacity,
|
|
144
|
-
).animate(CurvedAnimation(parent: _controller, curve: Curves.ease));
|
|
145
|
-
_controller.forward(from: 0);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
@override
|
|
150
|
-
void dispose() {
|
|
151
|
-
_controller.dispose();
|
|
152
|
-
super.dispose();
|
|
153
|
-
}
|
|
154
|
-
|
|
155
116
|
@override
|
|
156
117
|
Widget build(BuildContext context) {
|
|
157
|
-
return
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
Flexible(
|
|
181
|
-
flex: 0,
|
|
182
|
-
child: Text(
|
|
183
|
-
widget.title,
|
|
184
|
-
style: context.textTheme.labelLarge?.copyWith(
|
|
185
|
-
color: widget.titleColor,
|
|
186
|
-
),
|
|
187
|
-
overflow: TextOverflow.clip,
|
|
188
|
-
maxLines: 2,
|
|
189
|
-
),
|
|
190
|
-
),
|
|
191
|
-
const SizedBox(height: KasySpacing.xs),
|
|
192
|
-
Flexible(
|
|
193
|
-
flex: 0,
|
|
194
|
-
child: Text(
|
|
195
|
-
widget.description,
|
|
196
|
-
style: context.textTheme.bodyMedium?.copyWith(
|
|
197
|
-
color: widget.descriptionColor,
|
|
118
|
+
return Row(
|
|
119
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
120
|
+
children: [
|
|
121
|
+
icon,
|
|
122
|
+
const SizedBox(width: KasySpacing.sm),
|
|
123
|
+
Expanded(
|
|
124
|
+
child: Column(
|
|
125
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
126
|
+
children: [
|
|
127
|
+
// Headline row: bold title on the left, timestamp (and the
|
|
128
|
+
// unread dot) pinned to the right — the compact, professional
|
|
129
|
+
// notification layout (Linear / Gmail).
|
|
130
|
+
Row(
|
|
131
|
+
children: [
|
|
132
|
+
Expanded(
|
|
133
|
+
child: Text(
|
|
134
|
+
title,
|
|
135
|
+
style: context.textTheme.titleSmall?.copyWith(
|
|
136
|
+
color: titleColor,
|
|
137
|
+
fontWeight: FontWeight.w700,
|
|
138
|
+
),
|
|
139
|
+
overflow: TextOverflow.ellipsis,
|
|
140
|
+
maxLines: 1,
|
|
198
141
|
),
|
|
199
|
-
overflow: TextOverflow.ellipsis,
|
|
200
|
-
maxLines: 3,
|
|
201
142
|
),
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
flex: 0,
|
|
206
|
-
child: Text(
|
|
207
|
-
Jiffy.parseFromDateTime(widget.date).fromNow(),
|
|
143
|
+
const SizedBox(width: KasySpacing.sm),
|
|
144
|
+
Text(
|
|
145
|
+
Jiffy.parseFromDateTime(date).fromNow(),
|
|
208
146
|
style: context.textTheme.bodySmall?.copyWith(
|
|
209
|
-
color:
|
|
147
|
+
color: dateColor,
|
|
210
148
|
),
|
|
211
149
|
),
|
|
150
|
+
if (showUnreadDot) ...[
|
|
151
|
+
const SizedBox(width: KasySpacing.sm),
|
|
152
|
+
Container(
|
|
153
|
+
width: 6,
|
|
154
|
+
height: 6,
|
|
155
|
+
decoration: BoxDecoration(
|
|
156
|
+
shape: BoxShape.circle,
|
|
157
|
+
color: context.colors.primary,
|
|
158
|
+
),
|
|
159
|
+
),
|
|
160
|
+
],
|
|
161
|
+
],
|
|
162
|
+
),
|
|
163
|
+
const SizedBox(height: KasySpacing.xs),
|
|
164
|
+
Text(
|
|
165
|
+
description,
|
|
166
|
+
style: context.textTheme.bodyMedium?.copyWith(
|
|
167
|
+
color: descriptionColor,
|
|
212
168
|
),
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
),
|
|
216
|
-
if (widget.showUnreadDot) ...[
|
|
217
|
-
const SizedBox(width: KasySpacing.sm),
|
|
218
|
-
Padding(
|
|
219
|
-
padding: const EdgeInsets.only(top: 3),
|
|
220
|
-
child: Container(
|
|
221
|
-
width: 8,
|
|
222
|
-
height: 8,
|
|
223
|
-
decoration: BoxDecoration(
|
|
224
|
-
shape: BoxShape.circle,
|
|
225
|
-
color: context.colors.primary,
|
|
226
|
-
),
|
|
169
|
+
overflow: TextOverflow.ellipsis,
|
|
170
|
+
maxLines: 2,
|
|
227
171
|
),
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
172
|
+
],
|
|
173
|
+
),
|
|
174
|
+
),
|
|
175
|
+
],
|
|
232
176
|
);
|
|
233
177
|
}
|
|
234
178
|
}
|
|
@@ -269,8 +213,8 @@ class TileNotificationImage extends StatelessWidget {
|
|
|
269
213
|
borderRadius: BorderRadius.circular(8),
|
|
270
214
|
child: Image.network(
|
|
271
215
|
url,
|
|
272
|
-
width:
|
|
273
|
-
height:
|
|
216
|
+
width: 36,
|
|
217
|
+
height: 36,
|
|
274
218
|
fit: BoxFit.cover,
|
|
275
219
|
errorBuilder: (context, error, stack) =>
|
|
276
220
|
const TileNotificationIcon(active: false),
|
|
@@ -297,8 +241,8 @@ class TileNotificationIcon extends StatelessWidget {
|
|
|
297
241
|
? context.colors.primary
|
|
298
242
|
: context.colors.onSurface.withValues(alpha: 0.35);
|
|
299
243
|
return Container(
|
|
300
|
-
width:
|
|
301
|
-
height:
|
|
244
|
+
width: 36,
|
|
245
|
+
height: 36,
|
|
302
246
|
decoration: BoxDecoration(
|
|
303
247
|
color: active
|
|
304
248
|
? context.colors.primary.withValues(alpha: 0.12)
|
|
@@ -307,7 +251,7 @@ class TileNotificationIcon extends StatelessWidget {
|
|
|
307
251
|
),
|
|
308
252
|
child: Icon(
|
|
309
253
|
active ? KasyIcons.notificationActive : KasyIcons.notification,
|
|
310
|
-
size: KasyIconSize.
|
|
254
|
+
size: KasyIconSize.sm,
|
|
311
255
|
color: color,
|
|
312
256
|
),
|
|
313
257
|
);
|
|
@@ -326,27 +270,34 @@ class NotificationSkeletonTile extends StatelessWidget {
|
|
|
326
270
|
padding: EdgeInsets.only(top: KasySpacing.sm),
|
|
327
271
|
child: KasySkeletonGroup(
|
|
328
272
|
child: Padding(
|
|
329
|
-
padding: EdgeInsets.
|
|
273
|
+
padding: EdgeInsets.symmetric(
|
|
274
|
+
horizontal: KasySpacing.md,
|
|
275
|
+
vertical: KasySpacing.smd,
|
|
276
|
+
),
|
|
330
277
|
child: Row(
|
|
331
278
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
332
279
|
children: [
|
|
333
280
|
KasySkeleton(
|
|
334
|
-
width:
|
|
335
|
-
height:
|
|
281
|
+
width: 36,
|
|
282
|
+
height: 36,
|
|
336
283
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
|
337
284
|
),
|
|
338
|
-
SizedBox(width: KasySpacing.
|
|
285
|
+
SizedBox(width: KasySpacing.sm),
|
|
339
286
|
Expanded(
|
|
340
287
|
child: Column(
|
|
341
288
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
342
289
|
children: [
|
|
343
|
-
|
|
290
|
+
Row(
|
|
291
|
+
children: [
|
|
292
|
+
Expanded(child: KasySkeleton(width: 150, height: 13)),
|
|
293
|
+
SizedBox(width: KasySpacing.sm),
|
|
294
|
+
KasySkeleton(width: 44, height: 10),
|
|
295
|
+
],
|
|
296
|
+
),
|
|
344
297
|
SizedBox(height: KasySpacing.sm),
|
|
345
298
|
KasySkeleton(width: double.infinity, height: 11),
|
|
346
299
|
SizedBox(height: KasySpacing.xs),
|
|
347
300
|
KasySkeleton(width: 210, height: 11),
|
|
348
|
-
SizedBox(height: KasySpacing.smd),
|
|
349
|
-
KasySkeleton(width: 70, height: 10),
|
|
350
301
|
],
|
|
351
302
|
),
|
|
352
303
|
),
|
package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart
CHANGED
|
@@ -93,12 +93,11 @@ class OnboardingIllustrationScaffold extends StatelessWidget {
|
|
|
93
93
|
child: Text(
|
|
94
94
|
title,
|
|
95
95
|
textAlign: TextAlign.start,
|
|
96
|
+
// Design-system page-title scale (headlineMedium = 24/w700).
|
|
97
|
+
// Previously bumped to 28 with custom tracking, which read as
|
|
98
|
+
// oversized next to the rest of the app.
|
|
96
99
|
style: context.textTheme.headlineMedium?.copyWith(
|
|
97
100
|
color: colors.onBackground,
|
|
98
|
-
fontSize: 28,
|
|
99
|
-
fontWeight: FontWeight.w700,
|
|
100
|
-
letterSpacing: -0.3,
|
|
101
|
-
height: 1.2,
|
|
102
101
|
),
|
|
103
102
|
),
|
|
104
103
|
),
|
package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart
CHANGED
|
@@ -71,12 +71,10 @@ class _OnboardingRadioQuestionState
|
|
|
71
71
|
child: Text(
|
|
72
72
|
widget.title,
|
|
73
73
|
textAlign: TextAlign.start,
|
|
74
|
+
// Design-system page-title scale (headlineMedium = 24/w700),
|
|
75
|
+
// matching the illustration steps instead of a bespoke 26px size.
|
|
74
76
|
style: context.textTheme.headlineMedium?.copyWith(
|
|
75
77
|
color: context.colors.onBackground,
|
|
76
|
-
fontSize: 26,
|
|
77
|
-
fontWeight: FontWeight.w700,
|
|
78
|
-
letterSpacing: -0.2,
|
|
79
|
-
height: 1.2,
|
|
80
78
|
),
|
|
81
79
|
),
|
|
82
80
|
),
|
|
@@ -283,7 +283,8 @@ class _SelectableRowTileState extends State<SelectableRowTile>
|
|
|
283
283
|
padding: const EdgeInsets.only(right: KasySpacing.md),
|
|
284
284
|
child: Text(
|
|
285
285
|
widget.emoj!,
|
|
286
|
-
style: context.textTheme.titleMedium
|
|
286
|
+
style: context.textTheme.titleMedium
|
|
287
|
+
?.copyWith(fontSize: 28), // design-check: ignore — emoji glyph
|
|
287
288
|
),
|
|
288
289
|
),
|
|
289
290
|
),
|
|
@@ -1098,13 +1098,12 @@ class _ToolsTab extends ConsumerWidget {
|
|
|
1098
1098
|
_ActionCard(
|
|
1099
1099
|
icon: KasyIcons.note,
|
|
1100
1100
|
title: admin.update_bottom_sheet,
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
},
|
|
1101
|
+
// Preview the sheet over the current screen; dismissing (tap-outside /
|
|
1102
|
+
// Continue) just closes it and returns here, without navigating away.
|
|
1103
|
+
onTap: () => showUpdateBottomSheet(
|
|
1104
|
+
context: navigatorKey.currentContext!,
|
|
1105
|
+
version: '0.0.0',
|
|
1106
|
+
),
|
|
1108
1107
|
),
|
|
1109
1108
|
_ActionCard(
|
|
1110
1109
|
icon: KasyIcons.payment,
|
|
@@ -1148,6 +1147,10 @@ class _ToolsTab extends ConsumerWidget {
|
|
|
1148
1147
|
icon: KasyIcons.notification,
|
|
1149
1148
|
title: admin.copy_fcm_token,
|
|
1150
1149
|
onTap: () async {
|
|
1150
|
+
if (kIsWeb) {
|
|
1151
|
+
ref.read(toastProvider).alert(title: '', text: admin.native_only);
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1151
1154
|
final token = await FirebaseMessaging.instance.getToken();
|
|
1152
1155
|
if (token == null) {
|
|
1153
1156
|
ref.read(toastProvider).alert(
|
|
@@ -1163,7 +1166,13 @@ class _ToolsTab extends ConsumerWidget {
|
|
|
1163
1166
|
_ActionCard(
|
|
1164
1167
|
icon: KasyIcons.notificationActive,
|
|
1165
1168
|
title: admin.ask_notification,
|
|
1166
|
-
onTap: ()
|
|
1169
|
+
onTap: () {
|
|
1170
|
+
if (kIsWeb) {
|
|
1171
|
+
ref.read(toastProvider).alert(title: '', text: admin.native_only);
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
ref.read(notificationsSettingsProvider).askPermission();
|
|
1175
|
+
},
|
|
1167
1176
|
),
|
|
1168
1177
|
];
|
|
1169
1178
|
|
|
@@ -97,8 +97,8 @@ class _EditableUserAvatarState extends ConsumerState<EditableUserAvatar> {
|
|
|
97
97
|
child: Container(
|
|
98
98
|
width: 22,
|
|
99
99
|
height: 22,
|
|
100
|
-
decoration:
|
|
101
|
-
color:
|
|
100
|
+
decoration: BoxDecoration(
|
|
101
|
+
color: Colors.black.withValues(alpha: 0.6),
|
|
102
102
|
shape: BoxShape.circle,
|
|
103
103
|
),
|
|
104
104
|
child: const Icon(
|
|
@@ -402,8 +402,8 @@
|
|
|
402
402
|
"cancel_button": "Cancel"
|
|
403
403
|
},
|
|
404
404
|
"review_popup": {
|
|
405
|
-
"title": "Your
|
|
406
|
-
"description": "
|
|
405
|
+
"title": "Your feedback matters",
|
|
406
|
+
"description": "If the app has been helpful, a quick review goes a long way. Got ideas to improve it? We'd love to hear them.",
|
|
407
407
|
"cancel_button": "Suggest improvements",
|
|
408
408
|
"rate_button": "Write a review"
|
|
409
409
|
},
|
|
@@ -517,7 +517,7 @@
|
|
|
517
517
|
"error": "Something went wrong. Please try again."
|
|
518
518
|
},
|
|
519
519
|
"admin": {
|
|
520
|
-
"update_bottom_sheet": "
|
|
520
|
+
"update_bottom_sheet": "Preview what's new",
|
|
521
521
|
"paywalls": "Paywalls",
|
|
522
522
|
"test_onboarding": "Test onboarding",
|
|
523
523
|
"copy_user_id": "Copy user id",
|
|
@@ -526,12 +526,13 @@
|
|
|
526
526
|
"fcm_token_copied": "FCM Token copied to clipboard",
|
|
527
527
|
"fcm_token_unavailable": "Token unavailable (notifications disabled?)",
|
|
528
528
|
"ask_notification": "Ask for notification",
|
|
529
|
+
"native_only": "Available only in the native app (iOS / Android)",
|
|
529
530
|
"ask_review": "Ask for review",
|
|
530
531
|
"home_widgets_panel": "Home Widgets panel",
|
|
531
532
|
"home_widgets_title": "Home Widgets Panel",
|
|
532
533
|
"inspector_fab_title": "Widget inspector",
|
|
533
534
|
"inspector_fab_subtitle_prefix": "Global shortcut:",
|
|
534
|
-
"update_mywidget_title": "
|
|
535
|
+
"update_mywidget_title": "Update MyWidget Widget",
|
|
535
536
|
"update_mywidget_desc": "Call manual update for MyWidget widget",
|
|
536
537
|
"paywalls_title": "Paywalls Admin Panel",
|
|
537
538
|
"send_push_title": "Send notification",
|
|
@@ -402,8 +402,8 @@
|
|
|
402
402
|
"cancel_button": "Cancelar"
|
|
403
403
|
},
|
|
404
404
|
"review_popup": {
|
|
405
|
-
"title": "
|
|
406
|
-
"description": "
|
|
405
|
+
"title": "Tu opinión importa",
|
|
406
|
+
"description": "Si la app te ha sido útil, una reseña rápida marca la diferencia. ¿Tienes ideas para mejorarla? Nos encantaría escucharlas.",
|
|
407
407
|
"cancel_button": "Sugerir mejoras",
|
|
408
408
|
"rate_button": "Escribir una reseña"
|
|
409
409
|
},
|
|
@@ -517,7 +517,7 @@
|
|
|
517
517
|
"error": "Algo salió mal. Por favor, inténtalo de nuevo."
|
|
518
518
|
},
|
|
519
519
|
"admin": {
|
|
520
|
-
"update_bottom_sheet": "
|
|
520
|
+
"update_bottom_sheet": "Previsualizar novedades",
|
|
521
521
|
"paywalls": "Paywalls",
|
|
522
522
|
"test_onboarding": "Probar onboarding",
|
|
523
523
|
"copy_user_id": "Copiar ID de usuario",
|
|
@@ -526,12 +526,13 @@
|
|
|
526
526
|
"fcm_token_copied": "FCM Token copiado al portapapeles",
|
|
527
527
|
"fcm_token_unavailable": "Token no disponible (¿notificaciones desactivadas?)",
|
|
528
528
|
"ask_notification": "Pedir permiso de notificación",
|
|
529
|
+
"native_only": "Disponible solo en la app nativa (iOS / Android)",
|
|
529
530
|
"ask_review": "Pedir evaluación",
|
|
530
531
|
"home_widgets_panel": "Panel de Home Widgets",
|
|
531
532
|
"home_widgets_title": "Panel de Home Widgets",
|
|
532
533
|
"inspector_fab_title": "Inspector de widgets",
|
|
533
534
|
"inspector_fab_subtitle_prefix": "Atajo global:",
|
|
534
|
-
"update_mywidget_title": "
|
|
535
|
+
"update_mywidget_title": "Actualizar Widget MyWidget",
|
|
535
536
|
"update_mywidget_desc": "Llamar a la actualización manual para el widget MyWidget",
|
|
536
537
|
"paywalls_title": "Panel de Admin de Paywalls",
|
|
537
538
|
"send_push_title": "Enviar notificación",
|
|
@@ -402,8 +402,8 @@
|
|
|
402
402
|
"cancel_button": "Cancelar"
|
|
403
403
|
},
|
|
404
404
|
"review_popup": {
|
|
405
|
-
"title": "Sua opinião importa
|
|
406
|
-
"description": "
|
|
405
|
+
"title": "Sua opinião importa",
|
|
406
|
+
"description": "Se o app tem te ajudado, uma avaliação rápida faz toda a diferença. Prefere sugerir melhorias? A gente quer ouvir.",
|
|
407
407
|
"cancel_button": "Sugerir melhorias",
|
|
408
408
|
"rate_button": "Escrever uma avaliação"
|
|
409
409
|
},
|
|
@@ -517,7 +517,7 @@
|
|
|
517
517
|
"error": "Algo deu errado. Por favor, tente novamente."
|
|
518
518
|
},
|
|
519
519
|
"admin": {
|
|
520
|
-
"update_bottom_sheet": "
|
|
520
|
+
"update_bottom_sheet": "Pré-visualizar novidades",
|
|
521
521
|
"paywalls": "Paywalls",
|
|
522
522
|
"test_onboarding": "Testar onboarding",
|
|
523
523
|
"copy_user_id": "Copiar ID do usuário",
|
|
@@ -526,12 +526,13 @@
|
|
|
526
526
|
"fcm_token_copied": "FCM Token copiado para a área de transferência",
|
|
527
527
|
"fcm_token_unavailable": "Token não disponível (notificações desativadas?)",
|
|
528
528
|
"ask_notification": "Pedir permissão de notificação",
|
|
529
|
+
"native_only": "Disponível apenas no app nativo (iOS / Android)",
|
|
529
530
|
"ask_review": "Pedir avaliação",
|
|
530
531
|
"home_widgets_panel": "Painel de Home Widgets",
|
|
531
532
|
"home_widgets_title": "Painel de Home Widgets",
|
|
532
533
|
"inspector_fab_title": "Inspector de widgets",
|
|
533
534
|
"inspector_fab_subtitle_prefix": "Atalho global:",
|
|
534
|
-
"update_mywidget_title": "
|
|
535
|
+
"update_mywidget_title": "Atualizar Widget MyWidget",
|
|
535
536
|
"update_mywidget_desc": "Chamar atualização manual para o widget MyWidget",
|
|
536
537
|
"paywalls_title": "Painel Admin de Paywalls",
|
|
537
538
|
"send_push_title": "Enviar notificação",
|
|
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|
|
3
3
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
4
4
|
import 'package:go_router/go_router.dart';
|
|
5
5
|
import 'package:kasy_kit/core/bottom_menu/bottom_menu.dart';
|
|
6
|
+
import 'package:kasy_kit/core/chrome/chrome_visibility.dart';
|
|
6
7
|
import 'package:kasy_kit/core/config/features.dart';
|
|
7
8
|
import 'package:kasy_kit/core/data/api/analytics_api.dart';
|
|
8
9
|
import 'package:kasy_kit/core/guards/user_info_guard.dart';
|
|
@@ -62,6 +63,7 @@ GoRouter generateRouter({
|
|
|
62
63
|
},
|
|
63
64
|
observers: [
|
|
64
65
|
AnalyticsObserver(analyticsApi: MixpanelAnalyticsApi.instance()),
|
|
66
|
+
KasyChromeVisibilityObserver(),
|
|
65
67
|
|
|
66
68
|
...?observers,
|
|
67
69
|
],
|
|
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|
|
16
16
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
|
17
17
|
# In Windows, build-name is used as the major, minor, and patch parts
|
|
18
18
|
# of the product and file versions while build-number is used as the build suffix.
|
|
19
|
-
version: 1.0.0+
|
|
19
|
+
version: 1.0.0+39
|
|
20
20
|
|
|
21
21
|
environment:
|
|
22
22
|
sdk: ^3.11.0
|