diff --git a/lib/app.dart b/lib/app.dart index 11f9f5d..c4f9c77 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -52,7 +52,7 @@ class _AppState extends State with WidgetsBindingObserver { Future setUserPlan() async { final user = await getUser(); globalBestFriendUserId = -1; - if (user != null && context.mounted) { + if (user != null && mounted) { if (user.myBestFriendContactId != null) { final contact = await twonlyDB.contactsDao .getContactByUserId(user.myBestFriendContactId!) @@ -63,7 +63,9 @@ class _AppState extends State with WidgetsBindingObserver { } } } - context.read().updatePlan(user.subscriptionPlan); + if (mounted) { + context.read().updatePlan(user.subscriptionPlan); + } } } diff --git a/lib/src/services/api/media_received.dart b/lib/src/services/api/media_received.dart index 4952220..3683a0d 100644 --- a/lib/src/services/api/media_received.dart +++ b/lib/src/services/api/media_received.dart @@ -15,6 +15,7 @@ import 'package:cryptography_plus/cryptography_plus.dart'; import 'package:logging/logging.dart'; import 'package:twonly/src/model/protobuf/api/client_to_server.pb.dart' as client; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/storage.dart'; Map downloadStartedForMediaReceived = {}; @@ -143,7 +144,8 @@ Future startDownloadMedia(Message message, bool force) async { response.asStream().listen((http.StreamedResponse r) { r.stream.listen((List chunk) { // Display percentage of completion - print('downloadPercentage: ${downloaded / (r.contentLength ?? 0) * 100}'); + Log.info( + 'downloadPercentage: ${downloaded / (r.contentLength ?? 0) * 100}'); chunks.add(chunk); downloaded += chunk.length; @@ -160,7 +162,8 @@ Future startDownloadMedia(Message message, bool force) async { } // Display percentage of completion - print('downloadPercentage: ${downloaded / (r.contentLength ?? 0) * 100}'); + Log.info( + 'downloadPercentage: ${downloaded / (r.contentLength ?? 0) * 100}'); // Save the file final Uint8List bytes = Uint8List(r.contentLength ?? 0); @@ -203,9 +206,9 @@ Future handleEncryptedFile(Message msg, {Uint8List? encryptedBytesTmp}) async { var imageBytes = Uint8List.fromList(plaintextBytes); if (content.isVideo) { - final splited = extractUint8Lists(imageBytes); - imageBytes = splited[0]; - await writeMediaFile(msg.messageId, "mp4", splited[1]); + final extractedBytes = extractUint8Lists(imageBytes); + imageBytes = extractedBytes[0]; + await writeMediaFile(msg.messageId, "mp4", extractedBytes[1]); } await writeMediaFile(msg.messageId, "png", imageBytes); @@ -272,7 +275,7 @@ Future deleteMediaFile(int mediaId, String type) async { await file.delete(); } } catch (e) { - Logger("media_received.dart").shout("Erro deleting: $e"); + Logger("media_received.dart").shout("Error deleting: $e"); } } diff --git a/lib/src/services/api/media_send.dart b/lib/src/services/api/media_send.dart index 8e2ed18..7ebf844 100644 --- a/lib/src/services/api/media_send.dart +++ b/lib/src/services/api/media_send.dart @@ -131,7 +131,6 @@ Future addOrModifyImageToUpload( /// in case the media file was already encrypted of even uploaded /// remove the data so it will be done again. - /// TODO: when the uploadTokens are already set notify the server... await twonlyDB.mediaUploadsDao.updateMediaUpload( mediaUploadId, MediaUploadsCompanion( diff --git a/lib/src/services/signal/encryption.signal.dart b/lib/src/services/signal/encryption.signal.dart index 5ad072e..43719f4 100644 --- a/lib/src/services/signal/encryption.signal.dart +++ b/lib/src/services/signal/encryption.signal.dart @@ -2,10 +2,10 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; -import 'package:logging/logging.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; import 'package:twonly/src/services/signal/utils.signal.dart'; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/misc.dart'; Future signalEncryptMessage(int target, MessageJson msg) async { @@ -24,7 +24,7 @@ Future signalEncryptMessage(int target, MessageJson msg) async { return b.takeBytes(); } catch (e) { - Logger("utils/signal").shout(e.toString()); + Log.error(e.toString()); return null; } } @@ -38,7 +38,7 @@ Future signalDecryptMessage(int source, Uint8List msg) async { List? msgs = removeLastXBytes(msg, 4); if (msgs == null) { - Logger("utils/signal").shout("Message requires at least 4 bytes."); + Log.error("Message requires at least 4 bytes."); return null; } Uint8List body = msgs[0]; @@ -51,14 +51,13 @@ Future signalDecryptMessage(int source, Uint8List msg) async { SignalMessage signalMsg = SignalMessage.fromSerialized(body); plaintext = await session.decryptFromSignal(signalMsg); } else { - Logger("utils/signal").shout("Type not known: $type"); + Log.error("Type not known: $type"); return null; } - MessageJson dectext = - MessageJson.fromJson(jsonDecode(utf8.decode(gzip.decode(plaintext)))); - return dectext; + return MessageJson.fromJson( + jsonDecode(utf8.decode(gzip.decode(plaintext)))); } catch (e) { - Logger("utils/signal").shout(e.toString()); + Log.error(e.toString()); return null; } } diff --git a/lib/src/views/camera/camera_preview_components/save_to_gallery.dart b/lib/src/views/camera/camera_preview_components/save_to_gallery.dart index 22c3769..d4f2c43 100644 --- a/lib/src/views/camera/camera_preview_components/save_to_gallery.dart +++ b/lib/src/views/camera/camera_preview_components/save_to_gallery.dart @@ -64,7 +64,7 @@ class SaveToGalleryButtonState extends State { } else { memoryPath += ".png"; Uint8List? imageBytes = await widget.getMergedImage(); - if (imageBytes == null || !context.mounted) return; + if (imageBytes == null || !mounted) return; await File(memoryPath).writeAsBytes(imageBytes); res = await saveImageToGallery(imageBytes); } @@ -72,7 +72,7 @@ class SaveToGalleryButtonState extends State { setState(() { _imageSaved = true; }); - } else { + } else if (mounted && context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(res), diff --git a/lib/src/views/camera/camera_preview_controller_view.dart b/lib/src/views/camera/camera_preview_controller_view.dart index fb4c903..6108978 100644 --- a/lib/src/views/camera/camera_preview_controller_view.dart +++ b/lib/src/views/camera/camera_preview_controller_view.dart @@ -204,7 +204,9 @@ class _CameraPreviewViewState extends State { Future updateScaleFactor(double newScale) async { if (selectedCameraDetails.scaleFactor == newScale || - cameraController == null) return; + cameraController == null) { + return; + } await cameraController?.setZoomLevel(newScale.clamp( selectedCameraDetails.minAvailableZoom, selectedCameraDetails.maxAvailableZoom)); @@ -253,7 +255,7 @@ class _CameraPreviewViewState extends State { } await cameraController?.pausePreview(); - if (!context.mounted) return; + if (!mounted) return; cameraController?.setFlashMode( selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off); @@ -286,13 +288,13 @@ class _CameraPreviewViewState extends State { reverseTransitionDuration: Duration.zero, ), ); - if (context.mounted) { + if (mounted) { setState(() { sharePreviewIsShown = false; showSelfieFlash = false; }); } - if (!context.mounted) return true; + if (!mounted) return true; // shouldReturn is null when the user used the back button if (shouldReturn != null && shouldReturn) { // ignore: use_build_context_synchronously @@ -348,8 +350,9 @@ class _CameraPreviewViewState extends State { } Future startVideoRecording() async { - if (cameraController != null && cameraController!.value.isRecordingVideo) + if (cameraController != null && cameraController!.value.isRecordingVideo) { return; + } if (hasAudioPermission && videoWithAudio) { await widget.selectCamera( selectedCameraDetails.cameraId, diff --git a/lib/src/views/camera/image_editor/modules/all_emojis.dart b/lib/src/views/camera/image_editor/modules/all_emojis.dart index a1e7a7b..2b4796d 100755 --- a/lib/src/views/camera/image_editor/modules/all_emojis.dart +++ b/lib/src/views/camera/image_editor/modules/all_emojis.dart @@ -44,7 +44,7 @@ class _EmojisState extends State { user.lastUsedEditorEmojis!.toSet().toList(); } await updateUser(user); - if (!context.mounted) return; + if (!mounted) return; Navigator.pop( context, EmojiLayerData( diff --git a/lib/src/views/camera/share_image_editor_view.dart b/lib/src/views/camera/share_image_editor_view.dart index 35da02f..e51eb5f 100644 --- a/lib/src/views/camera/share_image_editor_view.dart +++ b/lib/src/views/camera/share_image_editor_view.dart @@ -320,7 +320,7 @@ class _ShareImageEditorView extends State { } Future imageBytes = getMergedImage(); videoController?.pause(); - if (isDisposed || !context.mounted) return; + if (isDisposed || !mounted) return; bool? wasSend = await Navigator.push( context, MaterialPageRoute( @@ -336,7 +336,7 @@ class _ShareImageEditorView extends State { ), ), ); - if (wasSend != null && wasSend && context.mounted) { + if (wasSend != null && wasSend && mounted) { // ignore: use_build_context_synchronously Navigator.pop(context, true); } else { @@ -404,11 +404,13 @@ class _ShareImageEditorView extends State { setState(() { sendingOrLoadingImage = false; }); - await Navigator.push(context, MaterialPageRoute(builder: (context) { - return SubscriptionView( - redirectError: err, - ); - })); + if (mounted) { + await Navigator.push(context, MaterialPageRoute(builder: (context) { + return SubscriptionView( + redirectError: err, + ); + })); + } } else { Future imageHandler = addOrModifyImageToUpload(mediaUploadId!, imageBytes); diff --git a/lib/src/views/chats/add_new_user.view.dart b/lib/src/views/chats/add_new_user.view.dart index 65e2966..08a1763 100644 --- a/lib/src/views/chats/add_new_user.view.dart +++ b/lib/src/views/chats/add_new_user.view.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:twonly/src/providers/connection.provider.dart'; +import 'package:twonly/src/services/signal/session.signal.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; @@ -16,8 +17,6 @@ import 'package:twonly/src/views/components/headline.dart'; import 'package:twonly/src/views/components/initialsavatar.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/services/api/messages.dart'; -// ignore: library_prefixes -import 'package:twonly/src/services/signal/utils.signal.dart' as SignalHelper; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/settings/subscription/subscription_view.dart'; @@ -92,7 +91,7 @@ class _SearchUsernameView extends State { ); if (added > 0) { - if (await SignalHelper.addNewContact(res.value.userdata)) { + if (await createNewSignalSession(res.value.userdata)) { // before notifying the other party, add await setupNotificationWithUsers(); await encryptAndSendMessageAsync( diff --git a/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart b/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart index 1543f1e..110a86b 100644 --- a/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart +++ b/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/services/api/media_send.dart' as send; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/views/components/message_send_state_icon.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; @@ -108,7 +109,7 @@ class _InChatMediaViewerState extends State { image = imagePath; }); } else { - print("Not found: $imagePath"); + Log.error("file not found: $imagePath"); } } diff --git a/lib/src/views/chats/media_viewer.view.dart b/lib/src/views/chats/media_viewer.view.dart index 168a99c..b6d3a8a 100644 --- a/lib/src/views/chats/media_viewer.view.dart +++ b/lib/src/views/chats/media_viewer.view.dart @@ -58,7 +58,6 @@ class _MediaViewerViewState extends State { bool imageSaved = false; bool imageSaving = false; - bool isMounted = true; StreamSubscription? downloadStateListener; @@ -85,7 +84,6 @@ class _MediaViewerViewState extends State { _subscription.cancel(); downloadStateListener?.cancel(); videoController?.dispose(); - isMounted = false; super.dispose(); } @@ -120,7 +118,7 @@ class _MediaViewerViewState extends State { } Future nextMediaOrExit() async { - if (!isMounted) return; + if (!mounted) return; videoController?.dispose(); nextMediaTimer?.cancel(); progressTimer?.cancel(); @@ -135,7 +133,7 @@ class _MediaViewerViewState extends State { } } if (allMediaFiles.isEmpty || allMediaFiles.length == 1) { - if (isMounted) { + if (mounted) { Navigator.pop(context); } } else { @@ -145,7 +143,7 @@ class _MediaViewerViewState extends State { } Future loadCurrentMediaFile({bool showTwonly = false}) async { - if (!isMounted) return; + if (!mounted) return; if (!context.mounted || allMediaFiles.isEmpty) return nextMediaOrExit(); await _noScreenshot.screenshotOff(); @@ -181,7 +179,7 @@ class _MediaViewerViewState extends State { if (updated.downloadState == DownloadState.downloaded) { downloadStateListener?.cancel(); await handleNextDownloadedMedia(updated, showTwonly); - // start downloading all the other possibile missing media files. + // start downloading all the other possible missing media files. tryDownloadAllMediaFiles(force: true); } } @@ -443,7 +441,7 @@ class _MediaViewerViewState extends State { return CameraSendToView(widget.contact); }, )); - if (isMounted && maxShowTime != gMediaShowInfinite) { + if (mounted && maxShowTime != gMediaShowInfinite) { nextMediaOrExit(); } else { videoController?.play(); diff --git a/lib/src/views/contact/contact_verify.view.dart b/lib/src/views/contact/contact_verify.view.dart index f3c1e8f..5531789 100644 --- a/lib/src/views/contact/contact_verify.view.dart +++ b/lib/src/views/contact/contact_verify.view.dart @@ -4,12 +4,12 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:twonly/globals.dart'; +import 'package:twonly/src/services/signal/session.signal.dart'; import 'package:twonly/src/views/components/format_long_string.dart'; import 'package:flutter/material.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/services/signal/utils.signal.dart'; import 'package:url_launcher/url_launcher.dart'; class ContactVerifyView extends StatefulWidget { diff --git a/lib/src/views/memories/memories.view.dart b/lib/src/views/memories/memories.view.dart index b84b703..2360ca5 100644 --- a/lib/src/views/memories/memories.view.dart +++ b/lib/src/views/memories/memories.view.dart @@ -21,7 +21,6 @@ class MemoriesViewState extends State { List galleryItems = []; Map> orderedByMonth = {}; List months = []; - bool mounted = true; StreamSubscription>? messageSub; @override @@ -32,7 +31,6 @@ class MemoriesViewState extends State { @override void dispose() { - mounted = false; messageSub?.cancel(); super.dispose(); } diff --git a/lib/src/views/memories/memories_photo_slider.view.dart b/lib/src/views/memories/memories_photo_slider.view.dart index 0b2ad39..395afd4 100644 --- a/lib/src/views/memories/memories_photo_slider.view.dart +++ b/lib/src/views/memories/memories_photo_slider.view.dart @@ -70,7 +70,7 @@ class _MemoriesPhotoSliderViewState extends State { setState(() {}); await send.purgeSendMediaFiles(); await received.purgeReceivedMediaFiles(); - if (context.mounted) { + if (mounted) { Navigator.pop(context, true); } } diff --git a/lib/src/views/settings/help/contact_us_view.dart b/lib/src/views/settings/help/contact_us_view.dart index 4af58b9..b6078a1 100644 --- a/lib/src/views/settings/help/contact_us_view.dart +++ b/lib/src/views/settings/help/contact_us_view.dart @@ -39,7 +39,7 @@ class _ContactUsState extends State { 'feedback': feedbackFull, }, ); - if (!context.mounted) return; + if (!mounted) return; if (response.statusCode == 200) { // Handle successful response diff --git a/lib/src/views/settings/help/diagnostics_view.dart b/lib/src/views/settings/help/diagnostics_view.dart index a68667a..c6f277f 100644 --- a/lib/src/views/settings/help/diagnostics_view.dart +++ b/lib/src/views/settings/help/diagnostics_view.dart @@ -67,10 +67,12 @@ class _DiagnosticsViewState extends State { if (result.status != ShareResultStatus.success) { Clipboard.setData(ClipboardData(text: logText)); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Log copied to clipboard!')), - ); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Log copied to clipboard!')), + ); + } } }, child: const Text('Share debug log'), diff --git a/lib/src/views/settings/help/faq.dart b/lib/src/views/settings/help/faq.dart index 1730bff..84c7693 100644 --- a/lib/src/views/settings/help/faq.dart +++ b/lib/src/views/settings/help/faq.dart @@ -30,7 +30,6 @@ class _FAQPageState extends State { final response = await http.get(Uri.parse("$domain/faq.json")); if (response.statusCode == 200) { - _locale = Localizations.localeOf(context).languageCode; setState(() { _faqData = json.decode(utf8.decode(response.bodyBytes)); noInternet = false; diff --git a/lib/src/views/settings/subscription/manage_subscription_view.dart b/lib/src/views/settings/subscription/manage_subscription_view.dart index 7110eb6..54d8685 100644 --- a/lib/src/views/settings/subscription/manage_subscription_view.dart +++ b/lib/src/views/settings/subscription/manage_subscription_view.dart @@ -46,9 +46,11 @@ class _ManageSubscriptionViewState extends State { Future toggleRenewalOption() async { Result res = await apiService.updatePlanOptions(!autoRenewal!); if (res.isError) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(errorCodeToText(context, res.error))), - ); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(errorCodeToText(context, res.error))), + ); + } } await initAsync(true); } @@ -88,12 +90,12 @@ class _ManageSubscriptionViewState extends State { }, ), ), - SizedBox(height: 20), - Divider(), - ListTile( - title: Text("Kündigen"), - onTap: () async {}, - ), + // SizedBox(height: 20), + // Divider(), + // ListTile( + // title: Text("Cancel subscription"), + // onTap: () async {}, + // ), ], ), );