1
1
import 'package:flutter/material.dart' ;
2
+ import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
2
3
3
4
import '../api/core.dart' ;
4
5
import '../api/exception.dart' ;
@@ -42,17 +43,17 @@ enum ServerUrlValidationError {
42
43
}
43
44
}
44
45
45
- String message () { // TODO(i18n)
46
+ String message (ZulipLocalizations zulipLocalizations ) {
46
47
switch (this ) {
47
48
case empty:
48
- return 'Please enter a URL.' ;
49
+ return zulipLocalizations.serverUrlValidationErrorEmpty ;
49
50
case invalidUrl:
50
- return 'Please enter a valid URL.' ;
51
+ return zulipLocalizations.serverUrlValidationErrorInvalidUrl ;
51
52
case noUseEmail:
52
- return 'Please enter the server URL, not your email.' ;
53
+ return zulipLocalizations.serverUrlValidationErrorNoUseEmail ;
53
54
case unsupportedSchemeZulip:
54
55
case unsupportedSchemeOther:
55
- return 'The server URL must start with http:// or https://.' ;
56
+ return zulipLocalizations.serverUrlValidationErrorUnsupportedScheme ;
56
57
}
57
58
}
58
59
}
@@ -135,11 +136,13 @@ class _AddAccountPageState extends State<AddAccountPage> {
135
136
}
136
137
137
138
Future <void > _onSubmitted (BuildContext context) async {
139
+ final zulipLocalizations = ZulipLocalizations .of (context);
138
140
final url = _parseResult.url;
139
141
final error = _parseResult.error;
140
142
if (error != null ) {
141
143
showErrorDialog (context: context,
142
- title: 'Invalid input' , message: error.message ());
144
+ title: zulipLocalizations.errorLoginInvalidInputTitle,
145
+ message: error.message (zulipLocalizations));
143
146
return ;
144
147
}
145
148
assert (url != null );
@@ -158,7 +161,8 @@ class _AddAccountPageState extends State<AddAccountPage> {
158
161
// TODO(#105) give more helpful feedback; see `fetchServerSettings`
159
162
// in zulip-mobile's src/message/fetchActions.js.
160
163
showErrorDialog (context: context,
161
- title: 'Could not connect' , message: 'Failed to connect to server:\n $url ' );
164
+ title: zulipLocalizations.errorLoginCouldNotConnectTitle,
165
+ message: zulipLocalizations.errorLoginCouldNotConnect (url.toString ()));
162
166
return ;
163
167
}
164
168
// https://github.com/dart-lang/linter/issues/4007
@@ -180,13 +184,14 @@ class _AddAccountPageState extends State<AddAccountPage> {
180
184
@override
181
185
Widget build (BuildContext context) {
182
186
assert (! PerAccountStoreWidget .debugExistsOf (context));
187
+ final zulipLocalizations = ZulipLocalizations .of (context);
183
188
final error = _parseResult.error;
184
189
final errorText = error == null || error.shouldDeferFeedback ()
185
190
? null
186
- : error.message ();
191
+ : error.message (zulipLocalizations );
187
192
188
193
return Scaffold (
189
- appBar: AppBar (title: const Text ('Add an account' ),
194
+ appBar: AppBar (title: Text (zulipLocalizations.loginAddAnAccount ),
190
195
bottom: _inProgress
191
196
? const PreferredSize (preferredSize: Size .fromHeight (4 ),
192
197
child: LinearProgressIndicator (minHeight: 4 )) // 4 restates default
@@ -211,7 +216,7 @@ class _AddAccountPageState extends State<AddAccountPage> {
211
216
// …but leave out unfocusing the input in case more editing is needed.
212
217
},
213
218
decoration: InputDecoration (
214
- labelText: 'Your Zulip server URL' ,
219
+ labelText: zulipLocalizations.loginServerUrlInputLabel ,
215
220
errorText: errorText,
216
221
helperText: kLayoutPinningHelperText,
217
222
hintText: 'your-org.zulipchat.com' )),
@@ -220,7 +225,7 @@ class _AddAccountPageState extends State<AddAccountPage> {
220
225
onPressed: ! _inProgress && errorText == null
221
226
? () => _onSubmitted (context)
222
227
: null ,
223
- child: const Text ('Continue' )),
228
+ child: Text (zulipLocalizations.loginAddAnAccountConfirm )),
224
229
])))));
225
230
}
226
231
}
@@ -289,10 +294,13 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
289
294
// TODO(#105) give more helpful feedback. The RN app is
290
295
// unhelpful here; we should at least recognize invalid auth errors, and
291
296
// errors for deactivated user or realm (see zulip-mobile#4571).
297
+ final zulipLocalizations = ZulipLocalizations .of (context);
292
298
final message = (e is ZulipApiException )
293
- ? 'The server said: \n\n ${ e .message }'
299
+ ? zulipLocalizations. errorServerErrorMessage ( e.message)
294
300
: e.message;
295
- showErrorDialog (context: context, title: 'Login failed' , message: message);
301
+ showErrorDialog (context: context,
302
+ title: zulipLocalizations.errorLoginFailed,
303
+ message: message);
296
304
return ;
297
305
}
298
306
@@ -335,6 +343,7 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
335
343
@override
336
344
Widget build (BuildContext context) {
337
345
assert (! PerAccountStoreWidget .debugExistsOf (context));
346
+ final zulipLocalizations = ZulipLocalizations .of (context);
338
347
final requireEmailFormatUsernames = widget.serverSettings.requireEmailFormatUsernames;
339
348
340
349
final usernameField = TextFormField (
@@ -350,8 +359,8 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
350
359
validator: (value) {
351
360
if (value == null || value.trim ().isEmpty) {
352
361
return requireEmailFormatUsernames
353
- ? 'Please enter your email.'
354
- : 'Please enter your username.' ;
362
+ ? zulipLocalizations.loginValidationRequireEmail
363
+ : zulipLocalizations.loginValidationRequireUsername ;
355
364
}
356
365
if (requireEmailFormatUsernames) {
357
366
// TODO(#106): validate is in the shape of an email
@@ -360,7 +369,9 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
360
369
},
361
370
textInputAction: TextInputAction .next,
362
371
decoration: InputDecoration (
363
- labelText: requireEmailFormatUsernames ? 'Email address' : 'Username' ,
372
+ labelText: requireEmailFormatUsernames
373
+ ? zulipLocalizations.loginValidationRequireEmailLabel
374
+ : zulipLocalizations.loginValidationRequireUsernameLabel,
364
375
helperText: kLayoutPinningHelperText,
365
376
));
366
377
@@ -372,14 +383,14 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
372
383
autovalidateMode: AutovalidateMode .onUserInteraction,
373
384
validator: (value) {
374
385
if (value == null || value.isEmpty) {
375
- return 'Please enter your password.' ;
386
+ return zulipLocalizations.loginValidationPassword ;
376
387
}
377
388
return null ;
378
389
},
379
390
textInputAction: TextInputAction .go,
380
391
onFieldSubmitted: (value) => _submit (),
381
392
decoration: InputDecoration (
382
- labelText: 'Password' ,
393
+ labelText: zulipLocalizations.loginValidationPasswordLabel ,
383
394
helperText: kLayoutPinningHelperText,
384
395
// TODO(material-3): Simplify away `Semantics` by using IconButton's
385
396
// M3-only params `isSelected` / `selectedIcon`, after fixing
@@ -389,14 +400,14 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
389
400
// [ButtonStyleButton].)
390
401
suffixIcon: Semantics (toggled: _obscurePassword,
391
402
child: IconButton (
392
- tooltip: 'Hide password' ,
403
+ tooltip: zulipLocalizations.loginHidePassword ,
393
404
onPressed: _handlePasswordVisibilityPress,
394
405
icon: _obscurePassword
395
406
? const Icon (Icons .visibility_off)
396
407
: const Icon (Icons .visibility)))));
397
408
398
409
return Scaffold (
399
- appBar: AppBar (title: const Text ('Log in' ),
410
+ appBar: AppBar (title: Text (zulipLocalizations.loginPageTitle ),
400
411
bottom: _inProgress
401
412
? const PreferredSize (preferredSize: Size .fromHeight (4 ),
402
413
child: LinearProgressIndicator (minHeight: 4 )) // 4 restates default
@@ -416,7 +427,7 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
416
427
const SizedBox (height: 8 ),
417
428
ElevatedButton (
418
429
onPressed: _inProgress ? null : _submit,
419
- child: const Text ('Log in' )),
430
+ child: Text (zulipLocalizations.loginFormSubmitLabel )),
420
431
])))))));
421
432
}
422
433
}
0 commit comments