lemmur-app-android/lib/pages/settings/add_instance_page.dart

141 lines
4.3 KiB
Dart
Raw Normal View History

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
2021-04-05 20:14:39 +02:00
import 'package:lemmy_api_client/v3.dart';
2021-09-14 23:45:26 +02:00
import '../../hooks/debounce.dart';
import '../../hooks/stores.dart';
import '../../util/cleanup_url.dart';
import '../../widgets/cached_network_image.dart';
2021-09-14 23:45:26 +02:00
import '../../widgets/fullscreenable_image.dart';
2020-09-24 15:50:52 +02:00
/// A page that let's user add a new instance. Pops a url of the added instance
class AddInstancePage extends HookWidget {
2021-03-10 08:34:30 +01:00
const AddInstancePage();
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final instanceController = useTextEditingController();
useValueListenable(instanceController);
final accountsStore = useAccountsStore();
final isSite = useState<bool?>(null);
final icon = useState<String?>(null);
2020-09-23 23:23:38 +02:00
final prevInput = usePrevious(instanceController.text);
final debounce = useDebounce(() async {
if (prevInput == instanceController.text) return;
2020-09-24 15:38:54 +02:00
2021-04-06 10:56:21 +02:00
final inst = normalizeInstanceHost(instanceController.text);
2020-09-24 15:38:54 +02:00
if (inst.isEmpty) {
isSite.value = null;
return;
}
try {
2021-02-24 20:52:18 +01:00
icon.value =
(await LemmyApiV3(inst).run(const GetSite())).siteView?.site.icon;
isSite.value = true;
} catch (e) {
isSite.value = false;
}
});
2020-09-23 23:31:34 +02:00
useEffect(() {
instanceController.addListener(debounce);
return () {
instanceController.removeListener(debounce);
};
2020-09-23 23:31:34 +02:00
}, []);
2021-04-11 17:19:44 +02:00
2021-04-06 10:56:21 +02:00
final inst = normalizeInstanceHost(instanceController.text);
2021-04-11 17:19:44 +02:00
handleOnAdd() async {
try {
2020-09-24 15:50:52 +02:00
await accountsStore.addInstance(inst, assumeValid: true);
Navigator.of(context).pop(inst);
} on Exception catch (err) {
2021-03-10 08:34:30 +01:00
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(err.toString()),
));
}
}
2021-04-11 17:19:44 +02:00
final handleAdd = isSite.value == true ? handleOnAdd : null;
return Scaffold(
appBar: AppBar(
2021-01-03 19:43:39 +01:00
leading: const CloseButton(),
title: const Text('Add instance'),
),
body: ListView(
children: [
2021-01-24 20:01:55 +01:00
if (isSite.value == true && icon.value != null)
SizedBox(
height: 150,
child: FullscreenableImage(
url: icon.value!,
2020-09-21 23:49:46 +02:00
child: CachedNetworkImage(
imageUrl: icon.value!,
2021-10-21 14:40:28 +02:00
errorBuilder: (_, ___) => const SizedBox.shrink(),
2020-09-21 23:49:46 +02:00
),
))
else if (isSite.value == false)
SizedBox(
height: 150,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
2021-01-03 19:43:39 +01:00
children: const [
Icon(Icons.close, color: Colors.red),
Text('instance not found')
],
),
)
else
2021-01-03 19:43:39 +01:00
const SizedBox(height: 150),
const SizedBox(height: 15),
SizedBox(
height: 40,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: TextField(
autofocus: true,
controller: instanceController,
2021-04-11 17:19:44 +02:00
autofillHints: const [AutofillHints.url],
keyboardType: TextInputType.url,
onSubmitted: (_) => handleAdd?.call(),
autocorrect: false,
2021-02-09 15:12:13 +01:00
decoration: const InputDecoration(labelText: 'instance url'),
),
),
),
2021-01-03 19:43:39 +01:00
const SizedBox(height: 5),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: SizedBox(
height: 40,
2021-02-09 15:12:13 +01:00
child: ElevatedButton(
2021-04-11 17:19:44 +02:00
onPressed: handleAdd,
child: !debounce.loading
2021-01-03 19:43:39 +01:00
? const Text('Add')
2020-09-20 01:09:09 +02:00
: SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(theme.canvasColor),
),
2020-09-20 01:09:09 +02:00
),
),
),
),
],
),
);
}
static Route<String> route() => MaterialPageRoute(
builder: (context) => const AddInstancePage(),
fullscreenDialog: true,
);
}