fluffychat/lib/utils/client_manager.dart

173 lines
5.7 KiB
Dart
Raw Normal View History

import 'dart:io';
import 'package:flutter/foundation.dart';
2021-10-26 16:50:34 +00:00
2023-12-30 08:46:58 +00:00
import 'package:desktop_notifications/desktop_notifications.dart';
2023-12-08 09:17:21 +00:00
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
2021-09-19 12:22:26 +00:00
import 'package:hive_flutter/hive_flutter.dart';
import 'package:matrix/encryption/utils/key_verification.dart';
import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
2023-12-08 09:17:21 +00:00
import 'package:universal_html/html.dart' as html;
2023-12-08 09:17:21 +00:00
import 'package:fluffychat/config/app_config.dart';
2022-06-17 20:17:41 +00:00
import 'package:fluffychat/utils/custom_http_client.dart';
2022-04-14 08:37:56 +00:00
import 'package:fluffychat/utils/custom_image_resizer.dart';
import 'package:fluffychat/utils/init_with_restore.dart';
2022-12-30 16:54:01 +00:00
import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart';
2021-10-26 16:50:34 +00:00
import 'package:fluffychat/utils/platform_infos.dart';
import 'matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart';
abstract class ClientManager {
static const String clientNamespace = 'im.fluffychat.store.clients';
static Future<List<Client>> getClients({
bool initialize = true,
required SharedPreferences store,
}) async {
2021-09-19 12:22:26 +00:00
if (PlatformInfos.isLinux) {
Hive.init((await getApplicationSupportDirectory()).path);
} else {
await Hive.initFlutter();
}
final clientNames = <String>{};
try {
final clientNamesList = store.getStringList(clientNamespace) ?? [];
clientNames.addAll(clientNamesList);
} catch (e, s) {
Logs().w('Client names in store are corrupted', e, s);
await store.remove(clientNamespace);
}
if (clientNames.isEmpty) {
clientNames.add(PlatformInfos.clientName);
await store.setStringList(clientNamespace, clientNames.toList());
}
final clients = clientNames.map(createClient).toList();
2022-04-14 05:34:55 +00:00
if (initialize) {
await Future.wait(
clients.map(
(client) => client.initWithRestore(
onMigration: () {
final l10n = lookupL10n(PlatformDispatcher.instance.locale);
sendInitNotification(
l10n.databaseMigrationTitle,
l10n.databaseMigrationBody,
);
},
).catchError(
(e, s) => Logs().e('Unable to initialize client', e, s),
),
),
);
2022-04-14 05:34:55 +00:00
}
if (clients.length > 1 && clients.any((c) => !c.isLogged())) {
final loggedOutClients = clients.where((c) => !c.isLogged()).toList();
for (final client in loggedOutClients) {
Logs().w(
'Multi account is enabled but client ${client.userID} is not logged in. Removing...',
);
clientNames.remove(client.clientName);
clients.remove(client);
}
await store.setStringList(clientNamespace, clientNames.toList());
}
return clients;
}
static Future<void> addClientNameToStore(
String clientName,
SharedPreferences store,
) async {
final clientNamesList = store.getStringList(clientNamespace) ?? [];
clientNamesList.add(clientName);
await store.setStringList(clientNamespace, clientNamesList);
}
static Future<void> removeClientNameFromStore(
String clientName,
SharedPreferences store,
) async {
final clientNamesList = store.getStringList(clientNamespace) ?? [];
2021-11-24 17:39:40 +00:00
clientNamesList.remove(clientName);
await store.setStringList(clientNamespace, clientNamesList);
2021-11-24 17:39:40 +00:00
}
static NativeImplementations get nativeImplementations => kIsWeb
? const NativeImplementationsDummy()
: NativeImplementationsIsolate(compute);
2022-06-17 20:17:41 +00:00
static Client createClient(String clientName) {
return Client(
clientName,
httpClient:
PlatformInfos.isAndroid ? CustomHttpClient.createHTTPClient() : null,
2022-06-17 20:17:41 +00:00
verificationMethods: {
KeyVerificationMethod.numbers,
if (kIsWeb || PlatformInfos.isMobile || PlatformInfos.isLinux)
KeyVerificationMethod.emoji,
},
importantStateEvents: <String>{
// To make room emotes work
'im.ponies.room_emotes',
},
logLevel: kReleaseMode ? Level.warning : Level.verbose,
2023-11-22 06:51:16 +00:00
databaseBuilder: flutterMatrixSdkDatabaseBuilder,
legacyDatabaseBuilder: FlutterHiveCollectionsDatabase.databaseBuilder,
2022-06-17 20:17:41 +00:00
supportedLoginTypes: {
AuthenticationTypes.password,
2023-03-26 09:20:54 +00:00
AuthenticationTypes.sso,
2022-06-17 20:17:41 +00:00
},
nativeImplementations: nativeImplementations,
2022-06-17 20:17:41 +00:00
customImageResizer: PlatformInfos.isMobile ? customImageResizer : null,
defaultNetworkRequestTimeout: const Duration(minutes: 30),
enableDehydratedDevices: true,
2022-06-17 20:17:41 +00:00
);
}
2023-12-08 09:17:21 +00:00
static void sendInitNotification(String title, String body) async {
2023-12-08 09:17:21 +00:00
if (kIsWeb) {
html.Notification(
title,
body: body,
2023-12-08 09:17:21 +00:00
);
return;
2023-12-08 09:17:21 +00:00
}
if (Platform.isLinux) {
await NotificationsClient().notify(
title,
body: body,
appName: AppConfig.applicationName,
hints: [
NotificationHint.soundName('message-new-instant'),
],
);
return;
}
2023-12-08 09:17:21 +00:00
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
2023-12-08 09:17:21 +00:00
await flutterLocalNotificationsPlugin.initialize(
const InitializationSettings(
android: AndroidInitializationSettings('notifications_icon'),
iOS: DarwinInitializationSettings(),
),
);
flutterLocalNotificationsPlugin.show(
0,
title,
body,
2023-12-08 09:17:21 +00:00
const NotificationDetails(
android: AndroidNotificationDetails(
'error_message',
'Error Messages',
importance: Importance.high,
2023-12-08 09:17:21 +00:00
priority: Priority.max,
),
iOS: DarwinNotificationDetails(sound: 'notification.caf'),
2023-12-08 09:17:21 +00:00
),
);
}
}