lemmur-app-android/lib/pages/add_instance.dart

162 lines
4.8 KiB
Dart
Raw Normal View History

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:lemmy_api_client/lemmy_api_client.dart';
import '../hooks/debounce.dart';
import '../hooks/stores.dart';
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 {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
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
final inst = _fixInstanceUrl(instanceController.text);
if (inst.isEmpty) {
isSite.value = null;
return;
}
try {
2020-09-24 15:38:54 +02:00
icon.value = (await LemmyApi(inst).v1.getSite()).site.icon;
isSite.value = true;
2020-09-23 18:03:47 +02:00
// ignore: avoid_catches_without_on_clauses
} 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
}, []);
2020-09-24 15:50:52 +02:00
final inst = _fixInstanceUrl(instanceController.text);
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) {
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(err.toString()),
));
}
}
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
backgroundColor: theme.scaffoldBackgroundColor,
brightness: theme.brightness,
shadowColor: Colors.transparent,
iconTheme: theme.iconTheme,
centerTitle: true,
leading: CloseButton(),
actionsIconTheme: theme.iconTheme,
textTheme: theme.textTheme,
title: Text('Add instance'),
),
body: ListView(
children: [
if (isSite.value == true)
SizedBox(
height: 150,
child: FullscreenableImage(
2020-09-21 23:49:46 +02:00
child: CachedNetworkImage(
imageUrl: icon.value,
errorWidget: (_, __, ___) => Container(),
),
url: icon.value,
))
else if (isSite.value == false)
SizedBox(
height: 150,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.close, color: Colors.red),
Text('instance not found')
],
),
)
else
SizedBox(height: 150),
SizedBox(height: 15),
SizedBox(
height: 40,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: TextField(
autofocus: true,
controller: instanceController,
autocorrect: false,
decoration: InputDecoration(
isDense: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
labelText: 'instance url',
),
),
),
),
SizedBox(height: 5),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: SizedBox(
height: 40,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
color: theme.accentColor,
child: !debounce.loading
2020-09-20 01:09:09 +02:00
? Text('Add')
: SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<Color>(theme.canvasColor),
),
2020-09-20 01:09:09 +02:00
),
onPressed: isSite.value == true ? handleOnAdd : null,
),
),
),
],
),
);
}
}
2020-09-24 15:38:54 +02:00
String _fixInstanceUrl(String inst) {
if (inst.startsWith('https://')) {
inst = inst.substring(8);
}
if (inst.startsWith('http://')) {
inst = inst.substring(7);
}
if (inst.endsWith('/')) inst = inst.substring(0, inst.length - 1);
return inst;
}