@@ -100,18 +100,24 @@ class SessionRefreshManager extends Notifier<SessionRefreshState> {
100100 SessionRefreshState build () {
101101 ref.listen (storedSessionProvider, (_, _) {
102102 if (ref.mounted) {
103- state = .idle ;
103+ state = const SessionRefreshStateIdle () ;
104104 }
105105 });
106- return .idle ;
106+ return const SessionRefreshStateIdle () ;
107107 }
108108
109109 /// Refreshes the session.
110110 Future <Result > refresh ({Session ? session}) async {
111- if (! ref.mounted || state == .inProgress || state == .invalidSession) {
112- return const ResultCancelled ();
111+ Result result = const ResultCancelled ();
112+ if (! ref.mounted || state is SessionRefreshStateInvalidSession ) {
113+ return result;
114+ }
115+ if (state is SessionRefreshStateInProgress ) {
116+ return await (state as SessionRefreshStateInProgress )._pendingRefresh.future;
113117 }
114- state = .inProgress;
118+
119+ Completer <Result >? pendingRefresh = Completer ();
120+ state = SessionRefreshStateInProgress (pendingRefresh: pendingRefresh);
115121 try {
116122 BackendClient backend = await ref.read (backendClientProvider.notifier);
117123 Result <Session > result = await _sendRefreshRequest (backend, session: session);
@@ -122,11 +128,10 @@ class SessionRefreshManager extends Notifier<SessionRefreshState> {
122128 return result;
123129 }
124130 await ref.read (storedSessionProvider.notifier).storeAndUse (result.value);
125- if (! ref.mounted) {
126- return const ResultCancelled ();
131+ if (ref.mounted) {
132+ state = const SessionRefreshStateSuccess ();
133+ result = const ResultSuccess ();
127134 }
128- state = .success;
129- return const ResultSuccess ();
130135 } catch (ex, stackTrace) {
131136 List <String > invalidSessionCodes = [
132137 InvalidPayloadError .kErrorCode,
@@ -135,13 +140,15 @@ class SessionRefreshManager extends Notifier<SessionRefreshState> {
135140 ExpiredSessionError .kErrorCode,
136141 ];
137142 if (ex is BackendRequestError && invalidSessionCodes.contains (ex.code) && ref.mounted) {
138- state = .invalidSession ;
143+ state = const SessionRefreshStateInvalidSession () ;
139144 }
140- return ResultError (
145+ result = ResultError (
141146 exception: ex,
142147 stackTrace: stackTrace,
143148 );
144149 }
150+ pendingRefresh.complete (result);
151+ return result;
145152 }
146153
147154 /// Sends a refresh request.
@@ -177,16 +184,36 @@ class NoSessionException extends LocalizableException {
177184}
178185
179186/// The session refresh state.
180- enum SessionRefreshState {
181- /// The session refresh state is idle.
182- idle,
187+ sealed class SessionRefreshState {
188+ /// Creates a new session refresh state instance.
189+ const SessionRefreshState ();
190+ }
183191
184- /// The session refresh state is in progress.
185- inProgress,
192+ /// The session refresh state is idle.
193+ class SessionRefreshStateIdle extends SessionRefreshState {
194+ /// Creates a new idle session refresh state instance.
195+ const SessionRefreshStateIdle ();
196+ }
197+
198+ /// The session refresh state is in progress.
199+ class SessionRefreshStateInProgress extends SessionRefreshState {
200+ /// The pending refresh completer.
201+ final Completer <Result > _pendingRefresh;
186202
187- /// The session refresh state is success.
188- success,
203+ /// Creates a new in progress session refresh state instance.
204+ SessionRefreshStateInProgress ({
205+ required Completer <Result > pendingRefresh,
206+ }) : _pendingRefresh = pendingRefresh;
207+ }
208+
209+ /// The session refresh state is success.
210+ class SessionRefreshStateSuccess extends SessionRefreshState {
211+ /// Creates a new success session refresh state instance.
212+ const SessionRefreshStateSuccess ();
213+ }
189214
190- /// The session refresh state is invalid.
191- invalidSession,
215+ /// The session refresh state is invalid.
216+ class SessionRefreshStateInvalidSession extends SessionRefreshState {
217+ /// Creates a new invalid session refresh state instance.
218+ const SessionRefreshStateInvalidSession ();
192219}
0 commit comments