1+ import 'dart:async' ;
2+
13import 'package:flutter/material.dart' ;
2- import 'package:flutter/scheduler.dart' ;
34import 'package:flutter_riverpod/flutter_riverpod.dart' ;
45import 'package:freedium_mobile/core/constants/app_constants.dart' ;
56import 'package:freedium_mobile/core/services/intent_service.dart' ;
67import 'package:freedium_mobile/core/theme/theme_provider.dart' ;
78import 'package:freedium_mobile/features/home/presentation/home_screen.dart' ;
9+ import 'package:freedium_mobile/features/onboarding/application/onboarding_provider.dart' ;
10+ import 'package:freedium_mobile/features/onboarding/presentation/onboarding_screen.dart' ;
811import 'package:freedium_mobile/features/webview/presentation/webview_screen.dart' ;
912import 'package:listen_sharing_intent/listen_sharing_intent.dart' ;
1013
@@ -24,6 +27,24 @@ final initialIntentHandledProvider =
2427 InitialIntentHandledNotifier .new ,
2528 );
2629
30+ class PendingIntentUrlNotifier extends Notifier <String ?> {
31+ @override
32+ String ? build () => null ;
33+
34+ void stash (String url) {
35+ state = url;
36+ }
37+
38+ void clear () {
39+ state = null ;
40+ }
41+ }
42+
43+ final pendingIntentUrlProvider =
44+ NotifierProvider <PendingIntentUrlNotifier , String ?>(
45+ PendingIntentUrlNotifier .new ,
46+ );
47+
2748class App extends ConsumerWidget {
2849 const App ({super .key});
2950
@@ -46,46 +67,59 @@ class App extends ConsumerWidget {
4667 }
4768 }
4869
70+ void _handleIncomingIntent (WidgetRef ref, String url) {
71+ if (url.isEmpty) return ;
72+
73+ final onboarding = ref.read (onboardingProvider);
74+ if (onboarding.isLoading || ! onboarding.hasSeenOnboarding) {
75+ ref.read (pendingIntentUrlProvider.notifier).stash (url);
76+ return ;
77+ }
78+
79+ _navigateToWebview (url);
80+ ReceiveSharingIntent .instance.reset ();
81+ }
82+
83+ Future <void > _processInitialIntent (WidgetRef ref) async {
84+ await Future <void >.delayed (const Duration (milliseconds: 400 ));
85+ final value = await ref.read (intentServiceProvider).getInitialIntent ();
86+ if (value.isEmpty) return ;
87+
88+ final url = value.first.path;
89+ if (url.isEmpty) return ;
90+
91+ _handleIncomingIntent (ref, url);
92+ }
93+
4994 @override
5095 Widget build (BuildContext context, WidgetRef ref) {
5196 final themeAsync = ref.watch (dynamicThemeProvider);
5297 final themeMode = ref.watch (themeModeProvider);
5398 final hasHandledInitialIntent = ref.watch (initialIntentHandledProvider);
99+ final onboarding = ref.watch (onboardingProvider);
100+ final hasSeenOnboarding = onboarding.hasSeenOnboarding;
101+
102+ ref.listen <OnboardingState >(onboardingProvider, (previous, next) {
103+ if (next.isLoading || ! next.hasSeenOnboarding) return ;
104+
105+ final pendingUrl = ref.read (pendingIntentUrlProvider);
106+ if (pendingUrl == null || pendingUrl.isEmpty) return ;
107+
108+ ref.read (pendingIntentUrlProvider.notifier).clear ();
109+ _navigateToWebview (pendingUrl);
110+ ReceiveSharingIntent .instance.reset ();
111+ });
54112
55113 ref.listen <AsyncValue <String >>(intentStreamProvider, (previous, next) {
56114 next.whenData ((url) {
57- if (url.isNotEmpty) {
58- final navigator = navigatorKey.currentState;
59- if (navigator != null && navigator.context.mounted) {
60- final currentRoute = ModalRoute .of (navigator.context);
61- final isCurrentlyOnWebview =
62- currentRoute? .settings.name? .startsWith ('/webview/' ) ?? false ;
63-
64- if (! isCurrentlyOnWebview) {
65- _navigateToWebview (url);
66- ReceiveSharingIntent .instance.reset ();
67- }
68- }
69- }
115+ _handleIncomingIntent (ref, url);
70116 });
71117 });
72118
73119 if (! hasHandledInitialIntent) {
74120 WidgetsBinding .instance.addPostFrameCallback ((_) {
75121 ref.read (initialIntentHandledProvider.notifier).setHandled ();
76- ref.read (intentServiceProvider).getInitialIntent ().then ((value) {
77- if (value.isNotEmpty) {
78- final url = value.first.path;
79- if (url.isNotEmpty) {
80- SchedulerBinding .instance.addPostFrameCallback ((_) {
81- Future .delayed (const Duration (milliseconds: 200 ), () {
82- _navigateToWebview (url);
83- ReceiveSharingIntent .instance.reset ();
84- });
85- });
86- }
87- }
88- });
122+ unawaited (_processInitialIntent (ref));
89123 });
90124 }
91125
@@ -96,7 +130,11 @@ class App extends ConsumerWidget {
96130 theme: theme.lightTheme,
97131 darkTheme: theme.darkTheme,
98132 themeMode: themeMode,
99- home: const HomeScreen (),
133+ home: onboarding.isLoading
134+ ? const Scaffold (body: Center (child: CircularProgressIndicator ()))
135+ : hasSeenOnboarding
136+ ? const HomeScreen ()
137+ : const OnboardingScreen (),
100138 ),
101139 loading: () => const MaterialApp (
102140 home: Scaffold (body: Center (child: CircularProgressIndicator ())),
0 commit comments