Merge branch 'main' of https://git.extera.xyz/OfficialDakari/ExteraNext
This commit is contained in:
commit
ae014ad40b
|
|
@ -3,6 +3,9 @@ import 'dart:ui';
|
|||
import 'package:matrix/matrix.dart';
|
||||
|
||||
abstract class AppConfig {
|
||||
static const String pushIsolatePortName = 'push_isolate';
|
||||
static const String mainIsolatePortName = 'main_isolate';
|
||||
|
||||
static String _applicationName = 'Extera';
|
||||
|
||||
static String get applicationName => _applicationName;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import 'dart:isolate';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
|
@ -15,9 +18,20 @@ import 'config/setting_keys.dart';
|
|||
import 'utils/background_push.dart';
|
||||
import 'widgets/fluffy_chat_app.dart';
|
||||
|
||||
ReceivePort? mainIsolateReceivePort;
|
||||
|
||||
void main() async {
|
||||
Logs().i('Welcome to ${AppConfig.applicationName} <3');
|
||||
|
||||
if (PlatformInfos.isAndroid) {
|
||||
final port = mainIsolateReceivePort = ReceivePort();
|
||||
IsolateNameServer.removePortNameMapping('main_isolate');
|
||||
IsolateNameServer.registerPortWithName(
|
||||
port.sendPort,
|
||||
'main_isolate',
|
||||
);
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class RecordingViewModelState extends State<RecordingViewModel> {
|
|||
Timer? _recorderSubscription;
|
||||
Duration duration = Duration.zero;
|
||||
|
||||
bool error = false;
|
||||
bool isSending = false;
|
||||
|
||||
bool get isRecording => _audioRecorder != null;
|
||||
|
|
@ -88,7 +87,11 @@ class RecordingViewModelState extends State<RecordingViewModel> {
|
|||
|
||||
final result = await audioRecorder.hasPermission();
|
||||
if (result != true) {
|
||||
setState(() => error = true);
|
||||
showOkAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).oopsSomethingWentWrong,
|
||||
message: L10n.of(context).noPermission,
|
||||
);
|
||||
return;
|
||||
}
|
||||
await WakelockPlus.enable();
|
||||
|
|
@ -107,9 +110,14 @@ class RecordingViewModelState extends State<RecordingViewModel> {
|
|||
);
|
||||
setState(() => duration = Duration.zero);
|
||||
_subscribe();
|
||||
} catch (_) {
|
||||
setState(() => error = true);
|
||||
rethrow;
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to start voice message recording', e, s);
|
||||
showOkAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).oopsSomethingWentWrong,
|
||||
message: e.toString(),
|
||||
);
|
||||
setState(_reset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +147,6 @@ class RecordingViewModelState extends State<RecordingViewModel> {
|
|||
_audioRecorder?.stop();
|
||||
_audioRecorder = null;
|
||||
isSending = false;
|
||||
error = false;
|
||||
fileName = null;
|
||||
duration = Duration.zero;
|
||||
amplitudeTimeline.clear();
|
||||
|
|
|
|||
|
|
@ -276,26 +276,16 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||
}
|
||||
|
||||
Future<void> importEmojiZip() async {
|
||||
final result = await showFutureLoadingDialog<Archive?>(
|
||||
context: context,
|
||||
future: () async {
|
||||
final result = await selectFiles(
|
||||
context,
|
||||
type: FileSelectorType.zip,
|
||||
);
|
||||
|
||||
if (result.isEmpty) return null;
|
||||
|
||||
final buffer = await result.first.readAsBytes();
|
||||
|
||||
final archive = ZipDecoder().decodeBytes(buffer);
|
||||
|
||||
return archive;
|
||||
},
|
||||
final result = await selectFiles(
|
||||
context,
|
||||
type: FileSelectorType.zip,
|
||||
);
|
||||
|
||||
final archive = result.result;
|
||||
if (archive == null) return;
|
||||
if (result.isEmpty) return;
|
||||
|
||||
final buffer = InputMemoryStream(await result.single.readAsBytes());
|
||||
|
||||
final archive = ZipDecoder().decodeStream(buffer);
|
||||
|
||||
await showDialog(
|
||||
context: context,
|
||||
|
|
@ -338,8 +328,6 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||
'${pack.pack.displayName ?? client.userID?.localpart ?? 'emotes'}.zip';
|
||||
final output = ZipEncoder().encode(archive);
|
||||
|
||||
if (output == null) return;
|
||||
|
||||
MatrixFile(
|
||||
name: fileName,
|
||||
bytes: Uint8List.fromList(output),
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import 'dart:io';
|
|||
import 'dart:isolate';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:extera_next/main.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
@ -75,6 +76,20 @@ class BackgroundPush {
|
|||
|
||||
void _init() async {
|
||||
try {
|
||||
mainIsolateReceivePort?.listen(
|
||||
(message) async {
|
||||
try {
|
||||
await notificationTap(
|
||||
NotificationResponseJson.fromJsonString(message),
|
||||
client: client,
|
||||
router: FluffyChatApp.router,
|
||||
l10n: l10n,
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().wtf('Main Notification Tap crashed', e, s);
|
||||
}
|
||||
},
|
||||
);
|
||||
if (PlatformInfos.isAndroid) {
|
||||
final port = ReceivePort();
|
||||
IsolateNameServer.removePortNameMapping('background_tab_port');
|
||||
|
|
@ -103,11 +118,10 @@ class BackgroundPush {
|
|||
iOS: DarwinInitializationSettings(),
|
||||
),
|
||||
onDidReceiveNotificationResponse: (response) => notificationTap(
|
||||
response,
|
||||
client: client,
|
||||
router: FluffyChatApp.router,
|
||||
l10n: l10n
|
||||
),
|
||||
response,
|
||||
client: client,
|
||||
router: FluffyChatApp.router,
|
||||
l10n: l10n),
|
||||
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
|
||||
);
|
||||
Logs().v('Flutter Local Notifications initialized');
|
||||
|
|
@ -125,7 +139,7 @@ class BackgroundPush {
|
|||
if (Platform.isAndroid) {
|
||||
await UnifiedPush.initialize(
|
||||
onNewEndpoint: _newUpEndpoint,
|
||||
onRegistrationFailed: _upUnregistered,
|
||||
onRegistrationFailed: (_, i) => _upUnregistered(i),
|
||||
onUnregistered: _upUnregistered,
|
||||
onMessage: _onUpMessage,
|
||||
);
|
||||
|
|
@ -312,12 +326,8 @@ class BackgroundPush {
|
|||
final response = details.notificationResponse;
|
||||
|
||||
if (response != null) {
|
||||
notificationTap(
|
||||
response,
|
||||
client: client,
|
||||
router: FluffyChatApp.router,
|
||||
l10n: l10n
|
||||
);
|
||||
notificationTap(response,
|
||||
client: client, router: FluffyChatApp.router, l10n: l10n);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -363,55 +373,18 @@ class BackgroundPush {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> goToRoom(NotificationResponse? response) async {
|
||||
try {
|
||||
if (response?.payload == null) return;
|
||||
final arr = response?.payload?.split(' ');
|
||||
final roomId = arr?[0];
|
||||
final eventId = arr?[1];
|
||||
Logs().v('[Push] Attempting to go to room $roomId...');
|
||||
if (roomId == null || eventId == null) {
|
||||
return;
|
||||
}
|
||||
await client.roomsLoading;
|
||||
await client.accountDataLoading;
|
||||
if (client.getRoomById(roomId) == null) {
|
||||
await client
|
||||
.waitForRoomInSync(roomId)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
}
|
||||
if (response?.actionId == "read") {
|
||||
if (AppConfig.sendPublicReadReceipts) {
|
||||
await client.setReadMarker(roomId, mRead: eventId);
|
||||
} else {
|
||||
await client.setReadMarker(roomId, mReadPrivate: eventId);
|
||||
}
|
||||
return;
|
||||
} else if (response?.actionId == "reply") {
|
||||
final replyText = response?.input;
|
||||
final room = client.getRoomById(roomId);
|
||||
if (replyText != null && room != null) {
|
||||
await room.sendTextEvent(replyText,
|
||||
inReplyTo: await room.getEventById(eventId));
|
||||
}
|
||||
return;
|
||||
}
|
||||
FluffyChatApp.router.go(
|
||||
client.getRoomById(roomId)?.membership == Membership.invite
|
||||
? '/rooms'
|
||||
: '/rooms/$roomId',
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().e('[Push] Failed to open room', e, s);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setupUp() async {
|
||||
await UnifiedPushUi(matrix!.context, ["default"], UPFunctions())
|
||||
.registerAppWithDialog();
|
||||
await UnifiedPushUi(
|
||||
context: matrix!.context,
|
||||
instances: ["default"],
|
||||
unifiedPushFunctions: UPFunctions(),
|
||||
showNoDistribDialog: false,
|
||||
onNoDistribDialogDismissed: () {}, // TODO: Implement me
|
||||
).registerAppWithDialog();
|
||||
}
|
||||
|
||||
Future<void> _newUpEndpoint(String newEndpoint, String i) async {
|
||||
Future<void> _newUpEndpoint(PushEndpoint newPushEndpoint, String i) async {
|
||||
final newEndpoint = newPushEndpoint.url;
|
||||
upAction = true;
|
||||
if (newEndpoint.isEmpty) {
|
||||
await _upUnregistered(i);
|
||||
|
|
@ -471,8 +444,9 @@ class BackgroundPush {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _onUpMessage(Uint8List message, String i) async {
|
||||
Future<void> _onUpMessage(PushMessage pushMessage, String i) async {
|
||||
upAction = true;
|
||||
final message = pushMessage.content;
|
||||
final data = Map<String, dynamic>.from(
|
||||
json.decode(utf8.decode(message))['notification'],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,149 +0,0 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart' hide Key;
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
// ignore: deprecated_member_use
|
||||
class FlutterHiveCollectionsDatabase extends HiveCollectionsDatabase {
|
||||
FlutterHiveCollectionsDatabase(
|
||||
super.name,
|
||||
String super.path, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
static const String _cipherStorageKey = 'hive_encryption_key';
|
||||
|
||||
static Future<FlutterHiveCollectionsDatabase> databaseBuilder(
|
||||
Client client,
|
||||
) async {
|
||||
Logs().d('Open Hive...');
|
||||
HiveAesCipher? hiverCipher;
|
||||
try {
|
||||
// Workaround for secure storage is calling Platform.operatingSystem on web
|
||||
if (kIsWeb) {
|
||||
// ignore: unawaited_futures
|
||||
html.window.navigator.storage?.persist();
|
||||
throw MissingPluginException();
|
||||
}
|
||||
|
||||
const secureStorage = FlutterSecureStorage();
|
||||
final containsEncryptionKey =
|
||||
await secureStorage.read(key: _cipherStorageKey) != null;
|
||||
if (!containsEncryptionKey) {
|
||||
// do not try to create a buggy secure storage for new Linux users
|
||||
if (Platform.isLinux) throw MissingPluginException();
|
||||
final key = Hive.generateSecureKey();
|
||||
await secureStorage.write(
|
||||
key: _cipherStorageKey,
|
||||
value: base64UrlEncode(key),
|
||||
);
|
||||
}
|
||||
|
||||
// workaround for if we just wrote to the key and it still doesn't exist
|
||||
final rawEncryptionKey = await secureStorage.read(key: _cipherStorageKey);
|
||||
if (rawEncryptionKey == null) throw MissingPluginException();
|
||||
|
||||
hiverCipher = HiveAesCipher(base64Url.decode(rawEncryptionKey));
|
||||
} on MissingPluginException catch (_) {
|
||||
const FlutterSecureStorage()
|
||||
.delete(key: _cipherStorageKey)
|
||||
.catchError((_) {});
|
||||
Logs().i('Hive encryption is not supported on this platform');
|
||||
} catch (e, s) {
|
||||
const FlutterSecureStorage()
|
||||
.delete(key: _cipherStorageKey)
|
||||
.catchError((_) {});
|
||||
Logs().w('Unable to init Hive encryption', e, s);
|
||||
}
|
||||
|
||||
final db = FlutterHiveCollectionsDatabase(
|
||||
'hive_collections_${client.clientName.replaceAll(' ', '_').toLowerCase()}',
|
||||
await findDatabasePath(client),
|
||||
key: hiverCipher,
|
||||
);
|
||||
try {
|
||||
await db.open();
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to open Hive. Delete database and storage key...', e, s);
|
||||
const FlutterSecureStorage().delete(key: _cipherStorageKey);
|
||||
await db.clear().catchError((_) {});
|
||||
await Hive.deleteFromDisk();
|
||||
rethrow;
|
||||
}
|
||||
Logs().d('Hive is ready');
|
||||
return db;
|
||||
}
|
||||
|
||||
static Future<String> findDatabasePath(Client client) async {
|
||||
var path = client.clientName;
|
||||
if (!kIsWeb) {
|
||||
Directory directory;
|
||||
try {
|
||||
if (Platform.isLinux) {
|
||||
directory = await getApplicationSupportDirectory();
|
||||
} else {
|
||||
directory = await getApplicationDocumentsDirectory();
|
||||
}
|
||||
} catch (_) {
|
||||
try {
|
||||
directory = await getLibraryDirectory();
|
||||
} catch (_) {
|
||||
directory = Directory.current;
|
||||
}
|
||||
}
|
||||
// do not destroy your stable FluffyChat in debug mode
|
||||
directory = Directory(
|
||||
directory.uri.resolve(kDebugMode ? 'hive_debug' : 'hive').toFilePath(),
|
||||
);
|
||||
directory.create(recursive: true);
|
||||
path = directory.path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@override
|
||||
int get maxFileSize => supportsFileStoring ? 100 * 1000 * 1000 : 0;
|
||||
@override
|
||||
bool get supportsFileStoring => !kIsWeb;
|
||||
|
||||
Future<String> _getFileStoreDirectory() async {
|
||||
try {
|
||||
try {
|
||||
return (await getTemporaryDirectory()).path;
|
||||
} catch (_) {
|
||||
return (await getApplicationDocumentsDirectory()).path;
|
||||
}
|
||||
} catch (_) {
|
||||
return (await getDownloadsDirectory())!.path;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List?> getFile(Uri mxcUri) async {
|
||||
if (!supportsFileStoring) return null;
|
||||
final tempDirectory = await _getFileStoreDirectory();
|
||||
final file =
|
||||
File('$tempDirectory/${Uri.encodeComponent(mxcUri.toString())}');
|
||||
if (await file.exists() == false) return null;
|
||||
final bytes = await file.readAsBytes();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@override
|
||||
Future storeFile(Uri mxcUri, Uint8List bytes, int time) async {
|
||||
if (!supportsFileStoring) return null;
|
||||
final tempDirectory = await _getFileStoreDirectory();
|
||||
final file =
|
||||
File('$tempDirectory/${Uri.encodeComponent(mxcUri.toString())}');
|
||||
if (await file.exists()) return;
|
||||
await file.writeAsBytes(bytes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -110,10 +110,10 @@ Future<MatrixSdkDatabase> _constructDatabase(String clientName) async {
|
|||
final database = await factory.openDatabase(
|
||||
path,
|
||||
options: OpenDatabaseOptions(
|
||||
version: 1,
|
||||
// most important : apply encryption when opening the DB
|
||||
onConfigure: helper?.applyPragmaKey,
|
||||
singleInstance: false),
|
||||
version: 1,
|
||||
// most important : apply encryption when opening the DB
|
||||
onConfigure: helper?.applyPragmaKey,
|
||||
),
|
||||
);
|
||||
|
||||
return await MatrixSdkDatabase.init(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ class MatrixLocals extends MatrixLocalizations {
|
|||
|
||||
MatrixLocals(this.l10n);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
String voiceMessage(String senderName, Duration? duration) {
|
||||
return l10n.voiceMessage;
|
||||
|
|
@ -358,4 +360,17 @@ class MatrixLocals extends MatrixLocalizations {
|
|||
|
||||
@override
|
||||
String get cancelledSend => l10n.sendCanceled;
|
||||
|
||||
@override
|
||||
// TODO: implement pollHasBeenEnded
|
||||
String get pollHasBeenEnded => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
String startedAPoll(String senderName) {
|
||||
// TODO: implement startedAPoll
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
// This is currently not used, just to keep up with matrix-dart-sdk upstream.
|
||||
// I will reimplement polls to match fluffychat's, I don't know when...
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,11 +46,10 @@ extension NotificationResponseJson on NotificationResponse {
|
|||
void notificationTapBackground(
|
||||
NotificationResponse notificationResponse,
|
||||
) async {
|
||||
Logs().i('Notification tap in background');
|
||||
|
||||
final sendPort = IsolateNameServer.lookupPortByName('background_tab_port');
|
||||
final sendPort = IsolateNameServer.lookupPortByName(AppConfig.mainIsolatePortName);
|
||||
if (sendPort != null) {
|
||||
sendPort.send(notificationResponse.toJsonString());
|
||||
Logs().i('Notification tap sent to main isolate');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/show_text_input_dialog.dart';
|
||||
import 'package:extera_next/widgets/fluffy_chat_app.dart';
|
||||
|
|
@ -34,7 +36,7 @@ extension UiaRequestManager on MatrixState {
|
|||
minLines: 1,
|
||||
maxLines: 1,
|
||||
obscureText: true,
|
||||
hintText: l10n.password,
|
||||
hintText: L10n.of(context).password,
|
||||
));
|
||||
if (input == null || input.isEmpty) {
|
||||
return uiaRequest.cancel();
|
||||
|
|
@ -80,24 +82,38 @@ extension UiaRequestManager on MatrixState {
|
|||
),
|
||||
);
|
||||
default:
|
||||
final url = Uri.parse(
|
||||
'${client.homeserver}/_matrix/client/r0/auth/$stage/fallback/web?session=${uiaRequest.session}',
|
||||
final stageUrl = uiaRequest.params
|
||||
.tryGetMap<String, Object?>(stage)
|
||||
?.tryGet<String>('url');
|
||||
final fallbackUrl = client.homeserver!.replace(
|
||||
path: '/_matrix/client/v3/auth/$stage/fallback/web',
|
||||
queryParameters: {
|
||||
'session': uiaRequest.session,
|
||||
},
|
||||
);
|
||||
final url = stageUrl != null
|
||||
? (Uri.tryParse(stageUrl) ?? fallbackUrl)
|
||||
: fallbackUrl;
|
||||
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
useRootNavigator: false,
|
||||
title: l10n.pleaseFollowInstructionsOnWeb,
|
||||
context: navigatorContext,
|
||||
okLabel: l10n.open,
|
||||
cancelLabel: l10n.cancel,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return uiaRequest.cancel();
|
||||
|
||||
launchUrl(url, mode: LaunchMode.inAppBrowserView);
|
||||
final completer = Completer();
|
||||
final listener =
|
||||
AppLifecycleListener(onResume: () => completer.complete());
|
||||
await completer.future;
|
||||
listener.dispose();
|
||||
|
||||
return uiaRequest.completeStage(
|
||||
AuthenticationData(session: uiaRequest.session),
|
||||
);
|
||||
launchUrlString(url.toString());
|
||||
if (OkCancelResult.ok ==
|
||||
await showOkCancelAlertDialog(
|
||||
useRootNavigator: false,
|
||||
title: l10n.pleaseFollowInstructionsOnWeb,
|
||||
context: navigatorContext,
|
||||
okLabel: l10n.next,
|
||||
cancelLabel: l10n.cancel,
|
||||
)) {
|
||||
return uiaRequest.completeStage(
|
||||
AuthenticationData(session: uiaRequest.session),
|
||||
);
|
||||
} else {
|
||||
return uiaRequest.cancel();
|
||||
}
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logs().e('Error while background UIA', e, s);
|
||||
|
|
@ -113,4 +129,4 @@ class UiaException implements Exception {
|
|||
|
||||
@override
|
||||
String toString() => reason;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,8 +16,11 @@
|
|||
#include <handy_window/handy_window_plugin.h>
|
||||
#include <pasteboard/pasteboard_plugin.h>
|
||||
#include <record_linux/record_linux_plugin.h>
|
||||
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
||||
#include <sqlcipher_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
#include <webcrypto/webcrypto_plugin.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
#include <window_to_front/window_to_front_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
|
|
@ -51,12 +54,21 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||
g_autoptr(FlPluginRegistrar) record_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin");
|
||||
record_linux_plugin_register_with_registrar(record_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
|
||||
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) sqlcipher_flutter_libs_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin");
|
||||
sqlite3_flutter_libs_plugin_register_with_registrar(sqlcipher_flutter_libs_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) webcrypto_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "WebcryptoPlugin");
|
||||
webcrypto_plugin_register_with_registrar(webcrypto_registrar);
|
||||
g_autoptr(FlPluginRegistrar) window_manager_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
|
||||
window_manager_plugin_register_with_registrar(window_manager_registrar);
|
||||
g_autoptr(FlPluginRegistrar) window_to_front_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowToFrontPlugin");
|
||||
window_to_front_plugin_register_with_registrar(window_to_front_registrar);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
handy_window
|
||||
pasteboard
|
||||
record_linux
|
||||
screen_retriever_linux
|
||||
sqlcipher_flutter_libs
|
||||
url_launcher_linux
|
||||
webcrypto
|
||||
window_manager
|
||||
window_to_front
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import package_info_plus
|
|||
import pasteboard
|
||||
import path_provider_foundation
|
||||
import record_macos
|
||||
import screen_retriever_macos
|
||||
import share_plus
|
||||
import shared_preferences_foundation
|
||||
import sqflite_darwin
|
||||
|
|
@ -32,6 +33,8 @@ import url_launcher_macos
|
|||
import video_compress
|
||||
import video_player_avfoundation
|
||||
import wakelock_plus
|
||||
import webcrypto
|
||||
import window_manager
|
||||
import window_to_front
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
|
|
@ -54,6 +57,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))
|
||||
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
|
||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
|
|
@ -62,5 +66,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin"))
|
||||
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
WebcryptoPlugin.register(with: registry.registrar(forPlugin: "WebcryptoPlugin"))
|
||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||
WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin"))
|
||||
}
|
||||
|
|
|
|||
116
pubspec.lock
116
pubspec.lock
|
|
@ -253,10 +253,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
|
||||
sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.4+2"
|
||||
version: "0.3.5"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -730,10 +730,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_vodozemac
|
||||
sha256: "54cd3790b6dfdc1afce928f8c46f7eeea9e4f8326f077400894935926f202057"
|
||||
sha256: "16d4b44dd338689441fe42a80d0184e5c864e9563823de9e7e6371620d2c0590"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.4.1"
|
||||
flutter_web_auth_2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1203,10 +1203,10 @@ packages:
|
|||
description:
|
||||
path: "."
|
||||
ref: main
|
||||
resolved-ref: f678376e3a4825a6e1a00d89585d6bae0843950c
|
||||
resolved-ref: "8272294736361eae8f3c81d220aaffcf30f38fb1"
|
||||
url: "https://git.extera.xyz/OfficialDakari/matrix-dart-sdk.git"
|
||||
source: git
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1563,10 +1563,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: qr_code_scanner_plus
|
||||
sha256: a0f1ac8e13299b3db2646635f252fe2ec67222b848b24ed34d11052faf080bfa
|
||||
sha256: b764e5004251c58d9dee0c295e6006e05bd8d249e78ac3383abdb5afe0a996cd
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.12"
|
||||
version: "2.0.14"
|
||||
qr_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1679,6 +1679,46 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
screen_retriever:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_retriever
|
||||
sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
screen_retriever_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_retriever_linux
|
||||
sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
screen_retriever_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_retriever_macos
|
||||
sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
screen_retriever_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_retriever_platform_interface
|
||||
sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
screen_retriever_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: screen_retriever_windows
|
||||
sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
scroll_to_index:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -2056,34 +2096,50 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: unifiedpush
|
||||
sha256: "6dbed5a6305ca33f1865c7a3d814ae39476b79a2d23ca76a5708f023f405730f"
|
||||
sha256: "8ed9767f750a1dc6159a77e2171641d0cb825dc87682d1ce1b8618689b79f58e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
version: "6.2.0"
|
||||
unifiedpush_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: unifiedpush_android
|
||||
sha256: "7443dece0a850ae956514f809983eb2b39fc518c2c7d24dbfe817198bec89134"
|
||||
sha256: "556796c81e8151ee8e4275baea2f7191119e8b1412ec35523cc2ac1c44c348bf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "3.4.0"
|
||||
unifiedpush_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: unifiedpush_linux
|
||||
sha256: c062d5eedd1cec70bcd33270cc4e01ae0ff6501f33d471167c06b34a968adfeb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
unifiedpush_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: unifiedpush_platform_interface
|
||||
sha256: dd588d78a8b2bfc10430e30035526e98caa543d0b7364a6344b5eb4815721c6d
|
||||
sha256: "83372bc8d794b8b12ef6993b518d7be907dcfc2191bdf6de0ece5c4445d89880"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "4.0.0"
|
||||
unifiedpush_storage_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: unifiedpush_storage_interface
|
||||
sha256: b8d423a4695efc616aa21d8ab48fb5ef99d6288c68b56282b8faac1579ceabd9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
unifiedpush_ui:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: unifiedpush_ui
|
||||
sha256: cf86f0214f37debd41f25c0425c8489df85e27f9f8784fed571eb7a86d39ba11
|
||||
sha256: "1b36b2aa0bc6b61577e2661c1183bd3442969ecf77b4c78174796d324f66dd1d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
version: "0.2.0"
|
||||
universal_html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -2248,10 +2304,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: vodozemac
|
||||
sha256: "95cac62ffab94db99e134c8f9aac198f8131a4eed0bed76a6cfc9c72add229b9"
|
||||
sha256: "39144e20740807731871c9248d811ed5a037b21d0aa9ffcfa630954de74139d9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.4.0"
|
||||
wakelock_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -2300,6 +2356,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
webcrypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webcrypto
|
||||
sha256: e393b3d0b01694a8f81efecf278ed7392877130e6e7b29f578863e4f2d0b2ebd
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.8"
|
||||
webdriver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -2316,6 +2380,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
webpush_encryption:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webpush_encryption
|
||||
sha256: "63046b7d6909f4a72ce3c153fa574726e257aaf21b1995ba063dc241a1b1520b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
webrtc_interface:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -2340,6 +2412,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.5"
|
||||
window_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: window_manager
|
||||
sha256: "7eb6d6c4164ec08e1bf978d6e733f3cebe792e2a23fb07cbca25c2872bfdbdcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1"
|
||||
window_to_front:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
16
pubspec.yaml
16
pubspec.yaml
|
|
@ -2,7 +2,7 @@ name: extera_next
|
|||
description: Chat with your friends.
|
||||
publish_to: none
|
||||
# On version bump also increase the build number for F-Droid
|
||||
version: 2.1.0
|
||||
version: 2.1.1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.0 <4.0.0"
|
||||
|
|
@ -16,7 +16,7 @@ dependencies:
|
|||
blurhash_dart: ^1.2.1
|
||||
chewie: ^1.11.0
|
||||
collection: ^1.18.0
|
||||
cross_file: ^0.3.4+2
|
||||
cross_file: ^0.3.5
|
||||
cupertino_icons: any
|
||||
desktop_drop: ^0.4.4
|
||||
desktop_notifications: ^0.6.3
|
||||
|
|
@ -47,7 +47,7 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/famedly/flutter_typeahead.git
|
||||
ref: main
|
||||
flutter_vodozemac: ^0.3.0
|
||||
flutter_vodozemac: ^0.4.1
|
||||
flutter_web_auth_2: ^3.1.1 # Version 4 blocked by https://github.com/MixinNetwork/flutter-plugins/issues/379
|
||||
flutter_webrtc: ^0.12.9
|
||||
geolocator: ^13.0.1
|
||||
|
|
@ -79,10 +79,10 @@ dependencies:
|
|||
pretty_qr_code: ^3.2.1
|
||||
provider: ^6.0.2
|
||||
punycode: ^1.0.0
|
||||
qr_code_scanner_plus: ^2.0.10+1
|
||||
qr_code_scanner_plus: ^2.0.14
|
||||
qr_image: ^1.0.0
|
||||
receive_sharing_intent: ^1.8.1
|
||||
record: ^6.1.1
|
||||
record: ^6.1.2
|
||||
scroll_to_index: ^3.0.1
|
||||
share_plus: ^10.0.2
|
||||
shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401
|
||||
|
|
@ -91,13 +91,13 @@ dependencies:
|
|||
sqlcipher_flutter_libs: ^0.6.1
|
||||
swipe_to_action: ^0.3.0
|
||||
tor_detector_web: ^1.1.0
|
||||
unifiedpush: ^5.0.1
|
||||
unifiedpush_ui: ^0.1.0
|
||||
unifiedpush: ^6.2.0
|
||||
unifiedpush_ui: ^0.2.0
|
||||
universal_html: ^2.2.4
|
||||
url_launcher: ^6.2.5
|
||||
video_compress: ^3.1.4
|
||||
video_player: ^2.9.2
|
||||
vodozemac: ^0.3.0
|
||||
vodozemac: ^0.4.0
|
||||
wakelock_plus: ^1.2.2
|
||||
webrtc_interface: ^1.0.13
|
||||
dio: ^5.9.0
|
||||
|
|
|
|||
|
|
@ -17,9 +17,12 @@
|
|||
#include <pasteboard/pasteboard_plugin.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <record_windows/record_windows_plugin_c_api.h>
|
||||
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
|
||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||
#include <sqlcipher_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <webcrypto/webcrypto_plugin.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
#include <window_to_front/window_to_front_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
|
|
@ -45,12 +48,18 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
RecordWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("RecordWindowsPluginCApi"));
|
||||
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
|
||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
||||
Sqlite3FlutterLibsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
WebcryptoPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("WebcryptoPlugin"));
|
||||
WindowManagerPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
|
||||
WindowToFrontPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("WindowToFrontPlugin"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,12 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
pasteboard
|
||||
permission_handler_windows
|
||||
record_windows
|
||||
screen_retriever_windows
|
||||
share_plus
|
||||
sqlcipher_flutter_libs
|
||||
url_launcher_windows
|
||||
webcrypto
|
||||
window_manager
|
||||
window_to_front
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue