shlink-manager/lib/views/settings_view.dart

292 lines
12 KiB
Dart
Raw Normal View History

2023-07-10 17:32:14 +02:00
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
2024-01-27 23:07:06 +01:00
import 'package:shlink_app/API/server_manager.dart';
import 'package:shlink_app/views/login_view.dart';
import 'package:shlink_app/views/opensource_licenses_view.dart';
2023-07-10 17:32:14 +02:00
import 'package:url_launcher/url_launcher.dart';
2024-01-27 23:07:06 +01:00
import '../globals.dart' as globals;
2023-07-10 17:32:14 +02:00
class SettingsView extends StatefulWidget {
const SettingsView({super.key});
@override
State<SettingsView> createState() => _SettingsViewState();
}
2024-01-28 00:32:09 +01:00
enum ServerStatus { connected, connecting, disconnected }
2023-07-10 17:32:14 +02:00
class _SettingsViewState extends State<SettingsView> {
2024-01-27 23:07:06 +01:00
var _serverVersion = "---";
ServerStatus _serverStatus = ServerStatus.connecting;
2024-01-28 00:32:09 +01:00
PackageInfo packageInfo =
PackageInfo(appName: "", packageName: "", version: "", buildNumber: "");
2023-07-10 17:32:14 +02:00
@override
void initState() {
// TODO: implement initState
super.initState();
2024-01-28 00:32:09 +01:00
WidgetsBinding.instance.addPostFrameCallback((_) => getServerHealth());
2023-07-10 17:32:14 +02:00
}
void getServerHealth() async {
2024-01-27 23:07:06 +01:00
var packageInfo = await PackageInfo.fromPlatform();
setState(() {
2024-03-31 21:08:41 +02:00
this.packageInfo = packageInfo;
});
2023-07-10 17:32:14 +02:00
final response = await globals.serverManager.getServerHealth();
response.fold((l) {
setState(() {
2024-01-27 23:07:06 +01:00
_serverVersion = l.version;
_serverStatus = ServerStatus.connected;
2023-07-10 17:32:14 +02:00
});
}, (r) {
setState(() {
2024-01-27 23:07:06 +01:00
_serverStatus = ServerStatus.disconnected;
2023-07-10 17:32:14 +02:00
});
var text = "";
if (r is RequestFailure) {
text = r.description;
2024-01-28 00:32:09 +01:00
} else {
2023-07-10 17:32:14 +02:00
text = (r as ApiFailure).detail;
}
2024-01-28 00:32:09 +01:00
final snackBar = SnackBar(
content: Text(text),
backgroundColor: Colors.red[400],
behavior: SnackBarBehavior.floating);
2023-07-10 17:32:14 +02:00
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
2024-01-28 00:32:09 +01:00
body: CustomScrollView(
slivers: [
SliverAppBar.medium(
expandedHeight: 120,
title: const Text(
"Settings",
style: TextStyle(fontWeight: FontWeight.bold),
2023-07-10 17:32:14 +02:00
),
2024-01-28 00:32:09 +01:00
actions: [
PopupMenuButton(
itemBuilder: (context) {
return [
const PopupMenuItem(
value: 0,
2024-03-31 21:58:31 +02:00
child: Text("Log out", style: TextStyle(color: Colors.red)),
2024-01-28 00:32:09 +01:00
)
];
},
onSelected: (value) {
if (value == 0) {
globals.serverManager.logOut().then((value) =>
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const LoginView())));
}
},
)
],
),
SliverToBoxAdapter(
child: Padding(
2023-07-10 17:32:14 +02:00
padding: const EdgeInsets.all(12.0),
child: Column(
children: [
Container(
2024-01-28 00:32:09 +01:00
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).brightness == Brightness.light
? Colors.grey[100]
: Colors.grey[900],
),
2023-07-10 17:32:14 +02:00
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
children: [
2024-01-28 00:32:09 +01:00
Icon(Icons.dns_outlined,
color: (() {
switch (_serverStatus) {
case ServerStatus.connected:
return Colors.green;
case ServerStatus.connecting:
return Colors.orange;
case ServerStatus.disconnected:
return Colors.red;
}
}())),
2024-01-27 23:07:06 +01:00
const SizedBox(width: 8),
2023-07-10 17:32:14 +02:00
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
2024-01-28 00:32:09 +01:00
const Text("Connected to",
style: TextStyle(color: Colors.grey)),
Text(globals.serverManager.getServerUrl(),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16)),
2023-07-10 17:32:14 +02:00
Row(
children: [
2024-01-28 00:32:09 +01:00
const Text("API Version: ",
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.w600)),
Text(globals.serverManager.getApiVersion(),
style:
const TextStyle(color: Colors.grey)),
2024-01-27 23:07:06 +01:00
const SizedBox(width: 16),
2024-01-28 00:32:09 +01:00
const Text("Server Version: ",
style: TextStyle(
color: Colors.grey,
fontWeight: FontWeight.w600)),
Text(_serverVersion,
style:
const TextStyle(color: Colors.grey))
2023-07-10 17:32:14 +02:00
],
),
],
)
],
),
),
),
2024-01-27 23:07:06 +01:00
const SizedBox(height: 8),
const Divider(),
const SizedBox(height: 8),
2023-07-10 17:32:14 +02:00
GestureDetector(
onTap: () {
2024-01-28 00:32:09 +01:00
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const OpenSourceLicensesView()));
2023-07-10 17:32:14 +02:00
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
2024-01-28 00:32:09 +01:00
color: Theme.of(context).brightness == Brightness.light
? Colors.grey[100]
: Colors.grey[900],
2023-07-10 17:32:14 +02:00
),
2024-01-27 23:07:06 +01:00
child: const Padding(
2024-01-28 00:32:09 +01:00
padding: EdgeInsets.only(
left: 12, right: 12, top: 20, bottom: 20),
2023-07-10 17:32:14 +02:00
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.policy_outlined),
SizedBox(width: 8),
2024-01-28 00:32:09 +01:00
Text("Open Source Licenses",
style: TextStyle(
fontWeight: FontWeight.w500)),
2023-07-10 17:32:14 +02:00
],
),
Icon(Icons.chevron_right)
2024-01-28 00:32:09 +01:00
]),
2023-07-10 17:32:14 +02:00
),
),
),
2024-01-27 23:07:06 +01:00
const SizedBox(height: 16),
2023-07-10 17:32:14 +02:00
GestureDetector(
onTap: () async {
2024-01-28 00:32:09 +01:00
var url = Uri.parse(
"https://github.com/rainloreley/shlink-mobile-app");
2023-07-10 17:32:14 +02:00
if (await canLaunchUrl(url)) {
2024-01-28 00:32:09 +01:00
launchUrl(url, mode: LaunchMode.externalApplication);
2023-07-10 17:32:14 +02:00
}
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
2024-01-28 00:32:09 +01:00
color: Theme.of(context).brightness == Brightness.light
? Colors.grey[100]
: Colors.grey[900],
2023-07-10 17:32:14 +02:00
),
2024-01-27 23:07:06 +01:00
child: const Padding(
2024-01-28 00:32:09 +01:00
padding: EdgeInsets.only(
left: 12, right: 12, top: 20, bottom: 20),
2023-07-10 17:32:14 +02:00
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.code),
SizedBox(width: 8),
2024-01-28 00:32:09 +01:00
Text("GitHub",
style: TextStyle(
fontWeight: FontWeight.w500)),
2023-07-10 17:32:14 +02:00
],
),
Icon(Icons.chevron_right)
2024-01-28 00:32:09 +01:00
]),
2023-07-10 17:32:14 +02:00
),
),
),
2024-01-27 23:07:06 +01:00
const SizedBox(height: 16),
GestureDetector(
onTap: () async {
2024-01-28 00:32:09 +01:00
var url = Uri.parse(
2024-02-23 16:33:00 +01:00
"https://wiki.abmgrt.dev/de/projects/shlink-manager/privacy");
if (await canLaunchUrl(url)) {
launchUrl(url, mode: LaunchMode.externalApplication);
}
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
2024-01-28 00:32:09 +01:00
color: Theme.of(context).brightness == Brightness.light
? Colors.grey[100]
: Colors.grey[900],
),
2024-01-27 23:07:06 +01:00
child: const Padding(
2024-01-28 00:32:09 +01:00
padding: EdgeInsets.only(
left: 12, right: 12, top: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.lock),
SizedBox(width: 8),
2024-01-28 00:32:09 +01:00
Text("Privacy Policy",
style: TextStyle(
fontWeight: FontWeight.w500)),
],
),
Icon(Icons.chevron_right)
2024-01-28 00:32:09 +01:00
]),
),
),
),
2024-01-27 23:07:06 +01:00
const SizedBox(height: 16),
if (packageInfo.appName != "")
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
2024-03-31 21:08:41 +02:00
Container(
padding: const EdgeInsets.only(
2024-03-31 21:58:31 +02:00
left: 8, right: 8, top: 4, bottom: 4),
2024-03-31 21:08:41 +02:00
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
2024-03-31 21:58:31 +02:00
color:
Theme.of(context).brightness == Brightness.light
? Colors.grey[100]
: Colors.grey[900],
2024-03-31 21:08:41 +02:00
),
child: Text(
"${packageInfo.appName}, v${packageInfo.version} (${packageInfo.buildNumber})",
style: const TextStyle(color: Colors.grey),
),
)
2024-01-28 00:32:09 +01:00
],
)
2023-07-10 17:32:14 +02:00
],
2024-01-28 00:32:09 +01:00
)),
)
],
));
2023-07-10 17:32:14 +02:00
}
}