1
0
mirror of https://github.com/go-vikunja/app synced 2024-06-03 02:59:47 +00:00
app-mirror-github/lib/global.dart

279 lines
8.9 KiB
Dart
Raw Normal View History

2022-04-22 19:39:01 +00:00
import 'dart:math';
import 'dart:developer' as dev;
import 'package:flutter/material.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2022-07-15 14:25:16 +00:00
import 'package:vikunja_app/api/bucket_implementation.dart';
2018-09-22 20:56:16 +00:00
import 'package:vikunja_app/api/client.dart';
2021-06-04 09:34:25 +00:00
import 'package:vikunja_app/api/label_task.dart';
import 'package:vikunja_app/api/label_task_bulk.dart';
import 'package:vikunja_app/api/labels.dart';
2018-09-22 20:56:16 +00:00
import 'package:vikunja_app/api/list_implementation.dart';
import 'package:vikunja_app/api/namespace_implementation.dart';
import 'package:vikunja_app/api/server_implementation.dart';
2018-09-22 20:56:16 +00:00
import 'package:vikunja_app/api/task_implementation.dart';
import 'package:vikunja_app/api/user_implementation.dart';
import 'package:vikunja_app/managers/notifications.dart';
2018-09-22 20:56:16 +00:00
import 'package:vikunja_app/managers/user.dart';
import 'package:vikunja_app/models/user.dart';
import 'package:vikunja_app/service/services.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
2022-04-22 19:39:01 +00:00
import 'package:flutter_local_notifications/flutter_local_notifications.dart'as notifs;
class VikunjaGlobal extends StatefulWidget {
final Widget child;
final Widget login;
2022-08-27 21:04:43 +00:00
VikunjaGlobal({required this.child, required this.login});
@override
VikunjaGlobalState createState() => VikunjaGlobalState();
static VikunjaGlobalState of(BuildContext context) {
var widget =
context.dependOnInheritedWidgetOfExactType<_VikunjaGlobalInherited>();
2022-08-27 21:04:43 +00:00
return widget!.data;
}
}
class VikunjaGlobalState extends State<VikunjaGlobal> {
final FlutterSecureStorage _storage = new FlutterSecureStorage();
2022-08-27 21:04:43 +00:00
User? _currentUser;
bool _loading = true;
bool expired = false;
2022-08-27 21:04:43 +00:00
late Client _client;
UserService? _newUserService;
2022-08-27 21:04:43 +00:00
User? get currentUser => _currentUser;
2019-03-18 16:56:15 +00:00
Client get client => _client;
final GlobalKey<ScaffoldMessengerState> snackbarKey =
GlobalKey<ScaffoldMessengerState>();
UserManager get userManager => new UserManager(_storage);
2019-03-18 16:56:15 +00:00
2022-08-27 21:04:43 +00:00
UserService? get newUserService => _newUserService;
ServerService get serverService => new ServerAPIService(client);
2019-03-18 16:56:15 +00:00
SettingsManager get settingsManager => new SettingsManager(_storage);
NamespaceService get namespaceService => new NamespaceAPIService(client);
2019-03-18 16:56:15 +00:00
TaskService get taskService => new TaskAPIService(client);
2019-03-18 16:56:15 +00:00
2022-07-15 14:25:16 +00:00
BucketService get bucketService => new BucketAPIService(client);
ListService get listService => new ListAPIService(client, _storage);
2022-04-22 19:39:01 +00:00
notifs.FlutterLocalNotificationsPlugin get notificationsPlugin => new notifs.FlutterLocalNotificationsPlugin();
2022-04-15 18:14:04 +00:00
TaskServiceOptions get taskServiceOptions => new TaskServiceOptions();
NotificationClass get notifications => new NotificationClass();
2022-08-27 21:04:43 +00:00
notifs.NotificationAppLaunchDetails? notifLaunch;
2021-06-04 09:34:25 +00:00
LabelService get labelService => new LabelAPIService(client);
LabelTaskService get labelTaskService => new LabelTaskAPIService(client);
LabelTaskBulkAPIService get labelTaskBulkService =>
new LabelTaskBulkAPIService(client);
2022-04-22 19:39:01 +00:00
var androidSpecificsDueDate = notifs.AndroidNotificationDetails(
"Vikunja1",
2022-04-28 12:46:30 +00:00
"Due Date Notifications",
2022-04-22 19:39:01 +00:00
channelDescription: "description",
2022-04-28 12:46:30 +00:00
icon: 'ic_launcher_foreground',
2022-04-22 19:39:01 +00:00
importance: notifs.Importance.high
);
var androidSpecificsReminders = notifs.AndroidNotificationDetails(
"Vikunja2",
2022-04-28 12:46:30 +00:00
"Reminder Notifications",
2022-04-22 19:39:01 +00:00
channelDescription: "description",
2022-04-28 12:46:30 +00:00
icon: 'ic_launcher_foreground',
2022-04-22 19:39:01 +00:00
importance: notifs.Importance.high
);
2022-08-27 21:04:43 +00:00
late notifs.IOSNotificationDetails iOSSpecifics;
late notifs.NotificationDetails platformChannelSpecificsDueDate;
late notifs.NotificationDetails platformChannelSpecificsReminders;
2022-04-22 19:39:01 +00:00
2022-08-27 21:04:43 +00:00
late String currentTimeZone;
@override
void initState() {
super.initState();
_client = Client(snackbarKey);
settingsManager.getIgnoreCertificates().then((value) => value == "1" ? client.ignoreCertificates = true : client.ignoreCertificates = false);
_newUserService = UserAPIService(client);
_loadCurrentUser();
tz.initializeTimeZones();
2022-04-22 19:39:01 +00:00
iOSSpecifics = notifs.IOSNotificationDetails();
platformChannelSpecificsDueDate = notifs.NotificationDetails(
android: androidSpecificsDueDate, iOS: iOSSpecifics);
platformChannelSpecificsReminders = notifs.NotificationDetails(
android: androidSpecificsReminders, iOS: iOSSpecifics);
notificationInitializer();
}
2022-08-27 21:04:43 +00:00
void changeUser(User newUser, {String? token, String? base}) async {
setState(() {
_loading = true;
});
if (token == null) {
token = await _storage.read(key: newUser.id.toString());
} else {
// Write new token to secure storage
await _storage.write(key: newUser.id.toString(), value: token);
}
2018-09-17 13:35:57 +00:00
if (base == null) {
base = await _storage.read(key: "${newUser.id.toString()}_base");
} else {
// Write new base to secure storage
await _storage.write(key: "${newUser.id.toString()}_base", value: base);
}
// Set current user in storage
await _storage.write(key: 'currentUser', value: newUser.id.toString());
client.configure(token: token, base: base, authenticated: true);
setState(() {
_currentUser = newUser;
_loading = false;
});
}
void notificationInitializer() async {
currentTimeZone = await FlutterNativeTimezone.getLocalTimezone();
notifLaunch = await notificationsPlugin.getNotificationAppLaunchDetails();
await notifications.initNotifications(notificationsPlugin);
requestIOSPermissions(notificationsPlugin);
}
2022-09-03 15:43:16 +00:00
Future<void> scheduleDueNotifications() async {
await notificationsPlugin.cancelAll();
final tasks = await taskService.getAll();
for (final task in tasks) {
for (final reminder in task.reminderDates) {
scheduleNotification(
"Reminder",
"This is your reminder for '" + task.title + "'",
notificationsPlugin,
reminder,
currentTimeZone,
platformChannelSpecificsReminders,
id: (reminder.millisecondsSinceEpoch / 1000).floor(),
);
}
if (task.hasDueDate) {
scheduleNotification(
"Due Reminder",
"The task '" + task.title + "' is due.",
notificationsPlugin,
task.dueDate!,
currentTimeZone,
platformChannelSpecificsDueDate,
id: task.id,
);
}
}
}
2019-03-18 16:56:15 +00:00
void logoutUser(BuildContext context) {
_storage.deleteAll().then((_) {
Navigator.pop(context);
setState(() {
client.reset();
2019-03-18 16:56:15 +00:00
_currentUser = null;
});
}).catchError((err) {
2022-04-10 13:31:56 +00:00
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
2019-03-18 16:56:15 +00:00
content: Text('An error occured while logging out!'),
));
});
}
void _loadCurrentUser() async {
var currentUser = await _storage.read(key: 'currentUser');
2018-09-17 13:35:57 +00:00
if (currentUser == null) {
setState(() {
_loading = false;
});
return;
}
var token = await _storage.read(key: currentUser);
var base = await _storage.read(key: '${currentUser}_base');
if (token == null || base == null) {
setState(() {
_loading = false;
});
return;
}
2022-05-07 15:44:11 +00:00
client.configure(token: token, base: base, authenticated: true);
2022-09-03 15:43:16 +00:00
User loadedCurrentUser;
try {
loadedCurrentUser = await UserAPIService(client).getCurrentUser();
} on ApiException catch (e) {
dev.log("Error code: " + e.errorCode.toString(),level: 1000);
if (e.errorCode ~/ 100 == 4) {
client.authenticated = false;
if (e.errorCode == 401) {
// token has expired, but we can reuse username and base. user just has to enter password again
expired = true;
}
setState(() {
client.authenticated = false;
_currentUser = null;
_loading = false;
});
return;
}
2022-09-03 15:43:16 +00:00
loadedCurrentUser = User(id: int.parse(currentUser), username: '');
} catch (otherExceptions) {
2022-09-03 15:43:16 +00:00
loadedCurrentUser = User(id: int.parse(currentUser), username: '');
}
2018-09-17 13:35:57 +00:00
setState(() {
_currentUser = loadedCurrentUser;
_loading = false;
});
}
@override
Widget build(BuildContext context) {
if (_loading) {
return new Center(child: new CircularProgressIndicator());
}
2022-08-27 21:04:43 +00:00
if(client.authenticated) {
scheduleDueNotifications();
}
return new _VikunjaGlobalInherited(
data: this,
2022-08-27 21:04:43 +00:00
key: UniqueKey(),
child: !client.authenticated ? widget.login : widget.child,
);
}
}
class _VikunjaGlobalInherited extends InheritedWidget {
final VikunjaGlobalState data;
2022-08-27 21:04:43 +00:00
_VikunjaGlobalInherited({Key? key, required this.data, required Widget child})
: super(key: key, child: child);
@override
bool updateShouldNotify(_VikunjaGlobalInherited oldWidget) {
2018-09-16 19:47:53 +00:00
return (data.currentUser != null &&
2022-08-27 21:04:43 +00:00
data.currentUser!.id != oldWidget.data.currentUser!.id) ||
data.client != oldWidget.data.client;
}
}