Skip to content

Commit 0cd718a

Browse files
authored
Merge pull request #142 from MostroP2P/implement-walkthrough
feat: Implement walkthrough screen
2 parents a98e498 + d35a848 commit 0cd718a

File tree

16 files changed

+313
-70
lines changed

16 files changed

+313
-70
lines changed

assets/images/wt-1.png

352 KB
Loading

assets/images/wt-2.png

500 KB
Loading

assets/images/wt-3.png

351 KB
Loading

assets/images/wt-4.png

298 KB
Loading

assets/images/wt-5.png

515 KB
Loading

assets/images/wt-6.png

348 KB
Loading

lib/core/app.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:mostro_mobile/services/lifecycle_manager.dart';
1212
import 'package:mostro_mobile/shared/providers/app_init_provider.dart';
1313
import 'package:mostro_mobile/features/settings/settings_provider.dart';
1414
import 'package:mostro_mobile/shared/notifiers/locale_notifier.dart';
15+
import 'package:mostro_mobile/features/walkthrough/providers/first_run_provider.dart';
1516

1617
class MostroApp extends ConsumerStatefulWidget {
1718
const MostroApp({super.key});
@@ -36,6 +37,9 @@ class _MostroAppState extends ConsumerState<MostroApp> {
3637

3738
return initAsyncValue.when(
3839
data: (_) {
40+
// Initialize first run provider
41+
ref.watch(firstRunProvider);
42+
3943
ref.listen<AuthState>(authNotifierProvider, (previous, state) {
4044
WidgetsBinding.instance.addPostFrameCallback((_) {
4145
if (!context.mounted) return;
@@ -57,7 +61,7 @@ class _MostroAppState extends ConsumerState<MostroApp> {
5761
title: 'Mostro',
5862
theme: AppTheme.theme,
5963
darkTheme: AppTheme.theme,
60-
routerConfig: goRouter,
64+
routerConfig: createRouter(ref),
6165
// Use language override from settings if available, otherwise let callback handle detection
6266
locale: settings.selectedLanguage != null
6367
? Locale(settings.selectedLanguage!)

lib/core/app_routes.dart

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:flutter/material.dart';
22
import 'package:go_router/go_router.dart';
3+
import 'package:flutter_riverpod/flutter_riverpod.dart';
34
import 'package:mostro_mobile/data/models/enums/order_type.dart';
45
import 'package:mostro_mobile/features/chat/screens/chat_room_screen.dart';
56
import 'package:mostro_mobile/features/order/screens/add_order_screen.dart';
@@ -19,12 +20,28 @@ import 'package:mostro_mobile/features/order/screens/pay_lightning_invoice_scree
1920
import 'package:mostro_mobile/features/order/screens/take_order_screen.dart';
2021
import 'package:mostro_mobile/features/auth/screens/register_screen.dart';
2122
import 'package:mostro_mobile/features/walkthrough/screens/walkthrough_screen.dart';
23+
import 'package:mostro_mobile/features/walkthrough/providers/first_run_provider.dart';
2224
import 'package:mostro_mobile/shared/widgets/navigation_listener_widget.dart';
2325
import 'package:mostro_mobile/shared/widgets/notification_listener_widget.dart';
2426

25-
final goRouter = GoRouter(
26-
navigatorKey: GlobalKey<NavigatorState>(),
27-
routes: [
27+
GoRouter createRouter(WidgetRef ref) {
28+
return GoRouter(
29+
navigatorKey: GlobalKey<NavigatorState>(),
30+
redirect: (context, state) {
31+
final firstRunState = ref.read(firstRunProvider);
32+
33+
return firstRunState.when(
34+
data: (isFirstRun) {
35+
if (isFirstRun && state.matchedLocation != '/walkthrough') {
36+
return '/walkthrough';
37+
}
38+
return null;
39+
},
40+
loading: () => null,
41+
error: (_, __) => null,
42+
);
43+
},
44+
routes: [
2845
ShellRoute(
2946
builder: (BuildContext context, GoRouterState state, Widget child) {
3047
return NotificationListenerWidget(
@@ -198,6 +215,7 @@ final goRouter = GoRouter(
198215
body: Center(child: Text(state.error.toString())),
199216
),
200217
);
218+
}
201219

202220
CustomTransitionPage buildPageWithDefaultTransition<T>({
203221
required BuildContext context,

lib/data/models/enums/storage_keys.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
enum SharedPreferencesKeys {
22
appSettings('mostro_settings'),
33
keyIndex('key_index'),
4-
fullPrivacy('full_privacy');
4+
fullPrivacy('full_privacy'),
5+
firstRunComplete('first_run_complete');
56

67
final String value;
78

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import 'package:flutter_riverpod/flutter_riverpod.dart';
2+
import 'package:shared_preferences/shared_preferences.dart';
3+
import 'package:mostro_mobile/data/models/enums/storage_keys.dart';
4+
import 'package:mostro_mobile/shared/providers/storage_providers.dart';
5+
6+
class FirstRunNotifier extends StateNotifier<AsyncValue<bool>> {
7+
FirstRunNotifier(this._sharedPreferences) : super(const AsyncValue.loading()) {
8+
_init();
9+
}
10+
11+
final SharedPreferencesAsync _sharedPreferences;
12+
13+
Future<void> _init() async {
14+
try {
15+
final isFirstRun = await _checkIfFirstRun();
16+
state = AsyncValue.data(isFirstRun);
17+
} catch (error, stackTrace) {
18+
state = AsyncValue.error(error, stackTrace);
19+
}
20+
}
21+
22+
Future<bool> _checkIfFirstRun() async {
23+
final firstRunComplete = await _sharedPreferences.getBool(
24+
SharedPreferencesKeys.firstRunComplete.value,
25+
);
26+
return firstRunComplete != true;
27+
}
28+
29+
Future<void> markFirstRunComplete() async {
30+
try {
31+
await _sharedPreferences.setBool(
32+
SharedPreferencesKeys.firstRunComplete.value,
33+
true,
34+
);
35+
state = const AsyncValue.data(false);
36+
} catch (error, stackTrace) {
37+
state = AsyncValue.error(error, stackTrace);
38+
}
39+
}
40+
41+
Future<void> resetFirstRun() async {
42+
try {
43+
await _sharedPreferences.remove(
44+
SharedPreferencesKeys.firstRunComplete.value,
45+
);
46+
state = const AsyncValue.data(true);
47+
} catch (error, stackTrace) {
48+
state = AsyncValue.error(error, stackTrace);
49+
}
50+
}
51+
}
52+
53+
final firstRunProvider = StateNotifierProvider<FirstRunNotifier, AsyncValue<bool>>((ref) {
54+
final sharedPreferences = ref.read(sharedPreferencesProvider);
55+
return FirstRunNotifier(sharedPreferences);
56+
});

0 commit comments

Comments
 (0)