@@ -106,6 +106,8 @@ class _EmailPasswordLoginPageState extends State<EmailPasswordLoginPage> {
106
106
});
107
107
}
108
108
109
+ bool _inProgress = false ;
110
+
109
111
Future <int > _getUserId (FetchApiKeyResult fetchApiKeyResult) async {
110
112
final FetchApiKeyResult (: email, : apiKey) = fetchApiKeyResult;
111
113
final auth = Auth (
@@ -125,50 +127,63 @@ class _EmailPasswordLoginPageState extends State<EmailPasswordLoginPage> {
125
127
}
126
128
// TODO(#35): validate email is in the shape of an email
127
129
128
- final FetchApiKeyResult result;
130
+ setState (() {
131
+ _inProgress = true ;
132
+ });
129
133
try {
130
- result = await fetchApiKey (
131
- realmUrl: realmUrl, username: email, password: password);
132
- } on Exception catch (e) { // TODO(#37): distinguish API exceptions
133
- // TODO(#35): give feedback to user on failed login
134
- debugPrint (e.toString ());
135
- return ;
136
- }
137
-
138
- // TODO(server-7): Rely on user_id from fetchApiKey.
139
- final int userId = result.userId ?? await _getUserId (result);
140
- if (context.mounted) {} // https://github.com/dart-lang/linter/issues/4007
141
- else {
142
- return ;
143
- }
134
+ final FetchApiKeyResult result;
135
+ try {
136
+ result = await fetchApiKey (
137
+ realmUrl: realmUrl, username: email, password: password);
138
+ } on Exception catch (e) { // TODO(#37): distinguish API exceptions
139
+ // TODO(#35): give feedback to user on failed login
140
+ debugPrint (e.toString ());
141
+ return ;
142
+ }
144
143
145
- final globalStore = GlobalStoreWidget .of (context);
146
- // TODO(#35): give feedback to user on SQL exception, like dupe realm+user
147
- final accountId = await globalStore.insertAccount (AccountsCompanion .insert (
148
- realmUrl: realmUrl,
149
- email: result.email,
150
- apiKey: result.apiKey,
151
- userId: userId,
152
- zulipFeatureLevel: widget.serverSettings.zulipFeatureLevel,
153
- zulipVersion: widget.serverSettings.zulipVersion,
154
- zulipMergeBase: Value (widget.serverSettings.zulipMergeBase),
155
- ));
156
- if (context.mounted) {} // https://github.com/dart-lang/linter/issues/4007
157
- else {
158
- return ;
144
+ // TODO(server-7): Rely on user_id from fetchApiKey.
145
+ final int userId = result.userId ?? await _getUserId (result);
146
+ if (context.mounted) {} // https://github.com/dart-lang/linter/issues/4007
147
+ else {
148
+ return ;
149
+ }
150
+
151
+ final globalStore = GlobalStoreWidget .of (context);
152
+ // TODO(#35): give feedback to user on SQL exception, like dupe realm+user
153
+ final accountId = await globalStore.insertAccount (AccountsCompanion .insert (
154
+ realmUrl: realmUrl,
155
+ email: result.email,
156
+ apiKey: result.apiKey,
157
+ userId: userId,
158
+ zulipFeatureLevel: widget.serverSettings.zulipFeatureLevel,
159
+ zulipVersion: widget.serverSettings.zulipVersion,
160
+ zulipMergeBase: Value (widget.serverSettings.zulipMergeBase),
161
+ ));
162
+ if (context.mounted) {} // https://github.com/dart-lang/linter/issues/4007
163
+ else {
164
+ return ;
165
+ }
166
+
167
+ await Navigator .of (context).pushAndRemoveUntil (
168
+ HomePage .buildRoute (accountId: accountId),
169
+ (route) => (route is ! _LoginSequenceRoute ),
170
+ );
171
+ } finally {
172
+ setState (() {
173
+ _inProgress = false ;
174
+ });
159
175
}
160
-
161
- Navigator .of (context).pushAndRemoveUntil (
162
- HomePage .buildRoute (accountId: accountId),
163
- (route) => (route is ! _LoginSequenceRoute ),
164
- );
165
176
}
166
177
167
178
@override
168
179
Widget build (BuildContext context) {
169
180
assert (! PerAccountStoreWidget .debugExistsOf (context));
170
181
return Scaffold (
171
- appBar: AppBar (title: const Text ('Log in' )),
182
+ appBar: AppBar (title: const Text ('Log in' ),
183
+ bottom: _inProgress
184
+ ? const PreferredSize (preferredSize: Size .fromHeight (4 ),
185
+ child: LinearProgressIndicator (minHeight: 4 )) // 4 restates default
186
+ : null ),
172
187
body: SafeArea (
173
188
minimum: const EdgeInsets .all (8 ),
174
189
child: Center (
@@ -197,7 +212,7 @@ class _EmailPasswordLoginPageState extends State<EmailPasswordLoginPage> {
197
212
icon: _obscurePassword ? const Icon (Icons .visibility_off) : const Icon (Icons .visibility))))),
198
213
const SizedBox (height: 8 ),
199
214
ElevatedButton (
200
- onPressed: _submit,
215
+ onPressed: _inProgress ? null : _submit,
201
216
child: const Text ('Log in' )),
202
217
])))))));
203
218
}
0 commit comments