diff --git a/lib/components/input_bar.dart b/lib/components/input_bar.dart index 7fe9b078..0e2680d4 100644 --- a/lib/components/input_bar.dart +++ b/lib/components/input_bar.dart @@ -261,16 +261,11 @@ class InputBar extends StatelessWidget { maxLines: maxLines, keyboardType: keyboardType, autofocus: autofocus, - onSubmitted: (text) { - // fix for library for now - onSubmitted(text); - }, + onSubmitted: onSubmitted, focusNode: focusNode, controller: controller, decoration: decoration, - onChanged: (text) { - onChanged(text); - }, + onChanged: onChanged, textCapitalization: TextCapitalization.sentences, ), suggestionsCallback: getSuggestions, diff --git a/lib/components/matrix.dart b/lib/components/matrix.dart index f6e9cf7f..7c06b42e 100644 --- a/lib/components/matrix.dart +++ b/lib/components/matrix.dart @@ -38,12 +38,9 @@ class Matrix extends StatefulWidget { final String clientName; - final Client client; - final Store store; - Matrix({this.child, this.clientName, this.client, this.store, Key key}) - : super(key: key); + Matrix({this.child, this.clientName, this.store, Key key}) : super(key: key); @override MatrixState createState() => MatrixState(); @@ -90,8 +87,7 @@ class MatrixState extends State { void _initWithStore() async { var initLoginState = client.onLoginStateChanged.stream.first; try { - client.database = await getDatabase(client); - await client.connect(); + client.init(); final firstLoginState = await initLoginState; if (firstLoginState == LoginState.logged) { if (PlatformInfos.isMobile) { @@ -264,85 +260,84 @@ class MatrixState extends State { void initMatrix() { store = widget.store ?? Store(); - if (widget.client == null) { - debugPrint('[Matrix] Init matrix client'); - final Set verificationMethods = { - KeyVerificationMethod.numbers - }; - if (PlatformInfos.isMobile) { - // emojis don't show in web somehow - verificationMethods.add(KeyVerificationMethod.emoji); - } - client = Client(widget.clientName, - enableE2eeRecovery: true, - verificationMethods: verificationMethods, - importantStateEvents: { - 'im.ponies.room_emotes', // we want emotes to work properly - }); - onJitsiCallSub ??= client.onEvent.stream - .where((e) => - e.type == EventUpdateType.timeline && - e.eventType == 'm.room.message' && - e.content['content']['msgtype'] == Matrix.callNamespace && - e.content['sender'] != client.userID) - .listen(onJitsiCall); - onRoomKeyRequestSub ??= - client.onRoomKeyRequest.stream.listen((RoomKeyRequest request) async { - final room = request.room; - if (request.sender != room.client.userID) { - return; // ignore share requests by others - } - final sender = room.getUserByMXIDSync(request.sender); - if (await showOkCancelAlertDialog( - context: context, - title: L10n.of(context).requestToReadOlderMessages, - message: - '${sender.id}\n\n${L10n.of(context).device}:\n${request.requestingDevice.deviceId}\n\n${L10n.of(context).identity}:\n${request.requestingDevice.curve25519Key.beautified}', - okLabel: L10n.of(context).verify, - cancelLabel: L10n.of(context).deny, - ) == - OkCancelResult.ok) { - await request.forwardKey(); - } - }); - onKeyVerificationRequestSub ??= client.onKeyVerificationRequest.stream - .listen((KeyVerification request) async { - var hidPopup = false; - request.onUpdate = () { - if (!hidPopup && - {KeyVerificationState.done, KeyVerificationState.error} - .contains(request.state)) { - Navigator.of(context, rootNavigator: true).pop('dialog'); - } - hidPopup = true; - }; - if (await showOkCancelAlertDialog( - context: context, - title: L10n.of(context).newVerificationRequest, - message: L10n.of(context).askVerificationRequest(request.userId), - ) == - OkCancelResult.ok) { - request.onUpdate = null; - hidPopup = true; - await request.acceptVerification(); - await Navigator.of(context).push( - AppRoute.defaultRoute( - context, - KeyVerificationView(request: request), - ), - ); - } else { - request.onUpdate = null; - hidPopup = true; - await request.rejectVerification(); - } - }); - _initWithStore(); - } else { - client = widget.client; - client.connect(); + final Set verificationMethods = { + KeyVerificationMethod.numbers + }; + if (PlatformInfos.isMobile) { + // emojis don't show in web somehow + verificationMethods.add(KeyVerificationMethod.emoji); } + client = Client( + widget.clientName, + enableE2eeRecovery: true, + verificationMethods: verificationMethods, + importantStateEvents: { + 'im.ponies.room_emotes', // we want emotes to work properly + }, + databaseBuilder: getDatabase, + ); + onJitsiCallSub ??= client.onEvent.stream + .where((e) => + e.type == EventUpdateType.timeline && + e.eventType == 'm.room.message' && + e.content['content']['msgtype'] == Matrix.callNamespace && + e.content['sender'] != client.userID) + .listen(onJitsiCall); + + onRoomKeyRequestSub ??= + client.onRoomKeyRequest.stream.listen((RoomKeyRequest request) async { + final room = request.room; + if (request.sender != room.client.userID) { + return; // ignore share requests by others + } + final sender = room.getUserByMXIDSync(request.sender); + if (await showOkCancelAlertDialog( + context: context, + title: L10n.of(context).requestToReadOlderMessages, + message: + '${sender.id}\n\n${L10n.of(context).device}:\n${request.requestingDevice.deviceId}\n\n${L10n.of(context).identity}:\n${request.requestingDevice.curve25519Key.beautified}', + okLabel: L10n.of(context).verify, + cancelLabel: L10n.of(context).deny, + ) == + OkCancelResult.ok) { + await request.forwardKey(); + } + }); + onKeyVerificationRequestSub ??= client.onKeyVerificationRequest.stream + .listen((KeyVerification request) async { + var hidPopup = false; + request.onUpdate = () { + if (!hidPopup && + {KeyVerificationState.done, KeyVerificationState.error} + .contains(request.state)) { + Navigator.of(context, rootNavigator: true).pop('dialog'); + } + hidPopup = true; + }; + if (await showOkCancelAlertDialog( + context: context, + title: L10n.of(context).newVerificationRequest, + message: L10n.of(context).askVerificationRequest(request.userId), + ) == + OkCancelResult.ok) { + request.onUpdate = null; + hidPopup = true; + await request.acceptVerification(); + await Navigator.of(context).push( + AppRoute.defaultRoute( + context, + KeyVerificationView(request: request), + ), + ); + } else { + request.onUpdate = null; + hidPopup = true; + await request.rejectVerification(); + } + }); + _initWithStore(); + if (kIsWeb) { onFocusSub = html.window.onFocus.listen((_) => webHasFocus = true); onBlurSub = html.window.onBlur.listen((_) => webHasFocus = false); diff --git a/lib/main.dart b/lib/main.dart index 8d6a8ff4..101ade15 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/utils/sentry_controller.dart'; import 'package:fluffychat/views/homeserver_picker.dart'; +import 'package:flushbar/flushbar_helper.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -46,6 +47,14 @@ class App extends StatelessWidget { future: Matrix.of(context).client.onLoginStateChanged.stream.first, builder: (context, snapshot) { + if (snapshot.hasError) { + WidgetsBinding.instance + .addPostFrameCallback((_) => FlushbarHelper.createError( + title: L10n.of(context).oopsSomethingWentWrong, + message: snapshot.error.toString(), + ).show(context)); + return HomeserverPicker(); + } if (!snapshot.hasData) { return Scaffold( body: Center( diff --git a/lib/utils/firebase_controller.dart b/lib/utils/firebase_controller.dart index 62cb978d..ef5c3b17 100644 --- a/lib/utils/firebase_controller.dart +++ b/lib/utils/firebase_controller.dart @@ -183,9 +183,7 @@ abstract class FirebaseController { tempClient = true; final platform = kIsWeb ? 'Web' : Platform.operatingSystem; final clientName = 'FluffyChat $platform'; - client = Client(clientName); - client.database = await getDatabase(client); - client.connect(); + client = Client(clientName, databaseBuilder: getDatabase)..init(); debugPrint('[Push] Use a temp client'); await client.onLoginStateChanged.stream .firstWhere((l) => l == LoginState.logged) diff --git a/pubspec.lock b/pubspec.lock index af1551f3..053a89bf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -63,7 +63,7 @@ packages: name: asn1lib url: "https://pub.dartlang.org" source: hosted - version: "0.6.5" + version: "0.8.1" async: dependency: transitive description: @@ -99,6 +99,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + catex: + dependency: transitive + description: + name: catex + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+6" characters: dependency: transitive description: @@ -196,7 +203,7 @@ packages: name: encrypt url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "4.1.0" fake_async: dependency: transitive description: @@ -208,8 +215,8 @@ packages: dependency: "direct main" description: path: "." - ref: b1709ca8c3409f58ed711cff3fbe329e9b3c3a9c - resolved-ref: b1709ca8c3409f58ed711cff3fbe329e9b3c3a9c + ref: "0697d47cc2791419ecf5dbc8840ac95bb6689e68" + resolved-ref: "0697d47cc2791419ecf5dbc8840ac95bb6689e68" url: "https://gitlab.com/famedly/famedlysdk.git" source: git version: "0.0.1" @@ -356,20 +363,13 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_math: - dependency: transitive - description: - name: flutter_math - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" flutter_matrix_html: dependency: "direct main" description: name: flutter_matrix_html url: "https://pub.dartlang.org" source: hosted - version: "0.1.13" + version: "0.1.12" flutter_olm: dependency: "direct main" description: @@ -554,7 +554,7 @@ packages: name: markdown url: "https://pub.dartlang.org" source: hosted - version: "2.1.8" + version: "3.0.0" matcher: dependency: transitive description: @@ -568,7 +568,7 @@ packages: name: matrix_file_e2ee url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.5" matrix_link_text: dependency: "direct main" description: @@ -613,13 +613,6 @@ packages: url: "https://gitlab.com/famedly/libraries/native_imaging.git" source: git version: "0.0.1" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" node_interop: dependency: transitive description: @@ -745,7 +738,7 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.2" permission_handler: dependency: "direct main" description: @@ -794,14 +787,14 @@ packages: name: pointycastle url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "2.0.0" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.5.0-nullsafety.1" + version: "1.5.0-nullsafety.2" process: dependency: transitive description: @@ -809,13 +802,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.13" - provider: - dependency: transitive - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.3.2+2" pub_semver: dependency: transitive description: @@ -911,14 +897,14 @@ packages: name: source_map_stack_trace url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.2" + version: "2.1.0-nullsafety.3" source_maps: dependency: transitive description: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.10-nullsafety.1" + version: "0.10.10-nullsafety.2" source_span: dependency: transitive description: @@ -1024,13 +1010,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.5.9" - tuple: - dependency: transitive - description: - name: tuple - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" typed_data: dependency: transitive description: @@ -1193,5 +1172,5 @@ packages: source: hosted version: "0.1.2" sdks: - dart: ">=2.10.2 <=2.11.0-161.0.dev" + dart: ">=2.10.2 <2.11.0" flutter: ">=1.22.2 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 925229d7..7c437fe8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,16 +1,6 @@ name: fluffychat description: Chat with your friends. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +publish_to: none version: 0.22.0+49 environment: @@ -23,7 +13,7 @@ dependencies: famedlysdk: git: url: https://gitlab.com/famedly/famedlysdk.git - ref: b1709ca8c3409f58ed711cff3fbe329e9b3c3a9c + ref: 0697d47cc2791419ecf5dbc8840ac95bb6689e68 localstorage: ^3.0.3+6 file_picker_cross: 4.2.2 @@ -50,7 +40,7 @@ dependencies: mime_type: ^0.3.2 flushbar: ^1.10.4 adaptive_dialog: ^0.9.0+1 - flutter_matrix_html: ^0.1.13 + flutter_matrix_html: ^0.1.12 moor: ^3.4.0 sqlite3_flutter_libs: ^0.2.0 sqlite3: ^0.1.8 @@ -71,7 +61,7 @@ dependencies: sentry: ">=3.0.0 <4.0.0" scroll_to_index: ^1.0.6 swipe_to_action: ^0.1.0 - flutter_svg: ^0.19.1 + flutter_svg: 0.19.1 # Because fluffychat depends on flutter_svg >=0.19.2 which requires Flutter SDK version >=1.24.0-6.0.pre <2.0.0, version solving failed. flutter_cache_manager: ^2.0.0 dev_dependencies: @@ -87,49 +77,11 @@ flutter_icons: ios: false image_path: "assets/logo.png" -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - # Adds code generation (synthetic package) support generate: true - - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: assets: - assets/ - assets/sounds/ - assets/js/ - - assets/js/package/ - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + - assets/js/package/ \ No newline at end of file