fluffychat/lib/main.dart

106 lines
3.9 KiB
Dart
Raw Permalink Normal View History

2020-01-01 18:10:13 +00:00
import 'package:flutter/material.dart';
2021-10-26 16:50:34 +00:00
2022-11-13 11:40:10 +00:00
import 'package:collection/collection.dart';
2023-08-07 16:40:02 +00:00
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2022-11-02 08:57:06 +00:00
import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.dart';
2020-01-01 18:10:13 +00:00
import 'package:fluffychat/config/app_config.dart';
2021-10-26 16:50:34 +00:00
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/platform_infos.dart';
2023-11-01 11:03:27 +00:00
import 'package:fluffychat/widgets/error_widget.dart';
2023-08-07 16:40:02 +00:00
import 'config/setting_keys.dart';
2021-02-07 16:18:38 +00:00
import 'utils/background_push.dart';
2022-08-25 16:31:30 +00:00
import 'widgets/fluffy_chat_app.dart';
2020-09-08 08:55:32 +00:00
2020-12-11 13:14:33 +00:00
void main() async {
Logs().i('Welcome to ${AppConfig.applicationName} <3');
2023-08-07 16:40:02 +00:00
2021-02-07 16:18:38 +00:00
// Our background push shared isolate accesses flutter-internal things very early in the startup proccess
// To make sure that the parts of flutter needed are started up already, we need to ensure that the
// widget bindings are initialized already.
WidgetsFlutterBinding.ensureInitialized();
2022-11-02 08:57:06 +00:00
Logs().nativeColors = !PlatformInfos.isIOS;
final store = await SharedPreferences.getInstance();
final clients = await ClientManager.getClients(store: store);
2022-11-13 11:40:10 +00:00
// If the app starts in detached mode, we assume that it is in
// background fetch mode for processing push notifications. This is
// currently only supported on Android.
if (PlatformInfos.isAndroid &&
AppLifecycleState.detached == WidgetsBinding.instance.lifecycleState) {
// Do not send online presences when app is in background fetch mode.
for (final client in clients) {
2024-03-14 17:28:07 +00:00
client.backgroundSync = false;
client.syncPresence = PresenceType.offline;
}
// In the background fetch mode we do not want to waste ressources with
// starting the Flutter engine but process incoming push notifications.
BackgroundPush.clientOnly(clients.first);
// To start the flutter engine afterwards we add an custom observer.
WidgetsBinding.instance.addObserver(AppStarter(clients, store));
Logs().i(
'${AppConfig.applicationName} started in background-fetch mode. No GUI will be created unless the app is no longer detached.',
);
return;
}
// Started in foreground mode.
Logs().i(
'${AppConfig.applicationName} started in foreground mode. Rendering GUI...',
);
await startGui(clients, store);
}
/// Fetch the pincode for the applock and start the flutter engine.
Future<void> startGui(List<Client> clients, SharedPreferences store) async {
// Fetch the pin for the applock if existing for mobile applications.
2023-08-07 16:40:02 +00:00
String? pin;
2021-02-07 16:18:38 +00:00
if (PlatformInfos.isMobile) {
2023-08-07 16:40:02 +00:00
try {
pin =
await const FlutterSecureStorage().read(key: SettingKeys.appLockKey);
} catch (e, s) {
Logs().d('Unable to read PIN from Secure storage', e, s);
}
2021-07-08 16:42:46 +00:00
}
// Preload first client
final firstClient = clients.firstOrNull;
await firstClient?.roomsLoading;
await firstClient?.accountDataLoading;
2023-11-01 11:03:27 +00:00
ErrorWidget.builder = (details) => FluffyChatErrorWidget(details);
runApp(FluffyChatApp(clients: clients, pincode: pin, store: store));
2020-01-02 21:31:39 +00:00
}
/// Watches the lifecycle changes to start the application when it
/// is no longer detached.
class AppStarter with WidgetsBindingObserver {
final List<Client> clients;
final SharedPreferences store;
bool guiStarted = false;
AppStarter(this.clients, this.store);
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (guiStarted) return;
if (state == AppLifecycleState.detached) return;
Logs().i(
'${AppConfig.applicationName} switches from the detached background-fetch mode to ${state.name} mode. Rendering GUI...',
);
// Switching to foreground mode needs to reenable send online sync presence.
for (final client in clients) {
2024-03-14 17:28:07 +00:00
client.backgroundSync = true;
client.syncPresence = PresenceType.online;
}
startGui(clients, store);
// We must make sure that the GUI is only started once.
guiStarted = true;
}
}