1
1
import 'package:flutter/material.dart' ;
2
+ import 'package:flutter/services.dart' ;
2
3
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
3
4
4
5
import '../api/exception.dart' ;
5
6
import '../api/route/account.dart' ;
6
7
import '../api/route/realm.dart' ;
7
8
import '../api/route/users.dart' ;
9
+ import '../model/binding.dart' ;
8
10
import '../model/store.dart' ;
9
11
import 'app.dart' ;
10
12
import 'dialog.dart' ;
@@ -101,6 +103,8 @@ class ServerUrlTextEditingController extends TextEditingController {
101
103
class AddAccountPage extends StatefulWidget {
102
104
const AddAccountPage ({super .key});
103
105
106
+ static const String serverUrlHelpUrl = 'https://zulip.com/help/logging-in#find-the-zulip-log-in-url' ;
107
+
104
108
static Route <void > buildRoute () {
105
109
return _LoginSequenceRoute (page: const AddAccountPage ());
106
110
}
@@ -207,7 +211,6 @@ class _AddAccountPageState extends State<AddAccountPage> {
207
211
child: ConstrainedBox (
208
212
constraints: const BoxConstraints (maxWidth: 400 ),
209
213
child: Column (mainAxisAlignment: MainAxisAlignment .center, children: [
210
- // TODO(#109) Link to doc about what a "server URL" is and how to find it
211
214
// TODO(#111) Perhaps give tappable realm URL suggestions based on text typed so far
212
215
TextField (
213
216
controller: _controller,
@@ -223,7 +226,14 @@ class _AddAccountPageState extends State<AddAccountPage> {
223
226
decoration: InputDecoration (
224
227
labelText: zulipLocalizations.loginServerUrlInputLabel,
225
228
errorText: errorText,
226
- helperText: kLayoutPinningHelperText,
229
+ helper: GestureDetector (
230
+ onTap: () {
231
+ _launchUrl (context);
232
+ },
233
+ child: Text (
234
+ zulipLocalizations.serverUrlDocLinkLabel,
235
+ style: Theme .of (context).textTheme.bodySmall!
236
+ .apply (color: const HSLColor .fromAHSL (1 , 200 , 1 , 0.4 ).toColor ()))),
227
237
hintText: 'your-org.zulipchat.com' )),
228
238
const SizedBox (height: 8 ),
229
239
ElevatedButton (
@@ -235,6 +245,30 @@ class _AddAccountPageState extends State<AddAccountPage> {
235
245
}
236
246
}
237
247
248
+ void _launchUrl (BuildContext context) async {
249
+ Future <void > showError (BuildContext context, String ? message) {
250
+ return showErrorDialog (
251
+ context: context,
252
+ title: ZulipLocalizations .of (context).errorUnableToOpenLinkTitle,
253
+ message: [
254
+ ZulipLocalizations .of (context).errorLinkCouldNotBeOpened (AddAccountPage .serverUrlHelpUrl),
255
+ if (message != null ) message,
256
+ ].join ("\n\n " ));
257
+ }
258
+
259
+ bool launched = false ;
260
+ String ? errorMessage;
261
+ try {
262
+ launched = await ZulipBinding .instance.launchUrl (Uri .parse (AddAccountPage .serverUrlHelpUrl));
263
+ } on PlatformException catch (e) {
264
+ errorMessage = e.message;
265
+ }
266
+ if (! launched) {
267
+ if (! context.mounted) return ;
268
+ await showError (context, errorMessage);
269
+ }
270
+ }
271
+
238
272
class PasswordLoginPage extends StatefulWidget {
239
273
const PasswordLoginPage ({super .key, required this .serverSettings});
240
274
0 commit comments