diff --git a/lib/src/services/api/mediafiles/download.api.dart b/lib/src/services/api/mediafiles/download.api.dart index f7e8bd27..bbb47f0d 100644 --- a/lib/src/services/api/mediafiles/download.api.dart +++ b/lib/src/services/api/mediafiles/download.api.dart @@ -267,13 +267,13 @@ Future requestMediaReupload(String mediaId) async { final messages = await twonlyDB.messagesDao.getMessagesByMediaId(mediaId); for (final message in messages) { - if (message.openedAt != null) continue; + if (message.openedAt != null || message.senderId == null) continue; await sendCipherText( - messages.first.senderId!, + message.senderId!, EncryptedContent( mediaUpdate: EncryptedContent_MediaUpdate( type: EncryptedContent_MediaUpdate_Type.DECRYPTION_ERROR, - targetMessageId: messages.first.messageId, + targetMessageId: message.messageId, ), ), ); diff --git a/lib/src/services/background/callback_dispatcher.background.dart b/lib/src/services/background/callback_dispatcher.background.dart index fbc22029..2e518128 100644 --- a/lib/src/services/background/callback_dispatcher.background.dart +++ b/lib/src/services/background/callback_dispatcher.background.dart @@ -40,6 +40,7 @@ void callbackDispatcher() { // if (await initBackgroundExecution()) { // await handlePeriodicTask(); // } + break; case 'eu.twonly.processing_task': if (await initBackgroundExecution()) { await handleProcessingTask(); @@ -130,25 +131,27 @@ Future handlePeriodicTask({int lastExecutionInSecondsLimit = 120}) async { return; } - while (!AppState.gotMessageFromServer) { - if (stopwatch.elapsed.inSeconds >= 15) { - Log.info('No new message from the server after 15 seconds.'); - break; + try { + while (!AppState.gotMessageFromServer) { + if (stopwatch.elapsed.inSeconds >= 15) { + Log.info('No new message from the server after 15 seconds.'); + break; + } + await Future.delayed(const Duration(milliseconds: 500)); } - await Future.delayed(const Duration(milliseconds: 500)); + + if (AppState.gotMessageFromServer) { + Log.info('Received a server message from the server.'); + } + + await finishStartedPreprocessing(); + + await Future.delayed(const Duration(milliseconds: 2000)); + } finally { + await apiService.close(() {}); + stopwatch.stop(); } - if (AppState.gotMessageFromServer) { - Log.info('Received a server message from the server.'); - } - - await finishStartedPreprocessing(); - - await Future.delayed(const Duration(milliseconds: 2000)); - - await apiService.close(() {}); - stopwatch.stop(); - Log.info('eu.twonly.periodic_task finished after ${stopwatch.elapsed}.'); return; } diff --git a/lib/src/services/notifications/fcm.notifications.dart b/lib/src/services/notifications/fcm.notifications.dart index c41c4cce..f7059ea1 100644 --- a/lib/src/services/notifications/fcm.notifications.dart +++ b/lib/src/services/notifications/fcm.notifications.dart @@ -11,6 +11,7 @@ import 'package:twonly/globals.dart'; import 'package:twonly/locator.dart'; import 'package:twonly/src/services/background/callback_dispatcher.background.dart'; import 'package:twonly/src/services/notifications/background.notifications.dart'; +import 'package:twonly/src/services/notifications/setup.notifications.dart'; import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/utils/log.dart'; @@ -117,6 +118,7 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { SentryWidgetsFlutterBinding.ensureInitialized(); await AppEnvironment.init(); final isInitialized = await initBackgroundExecution(); + await setupPushNotification(); Log.info('Handling a background message: ${message.messageId}'); await handleRemoteMessage(message); diff --git a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart index 5c00e0e2..eafad80b 100644 --- a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart +++ b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart @@ -138,7 +138,12 @@ class MainCameraController { ? ImageFormatGroup.nv21 : ImageFormatGroup.bgra8888, ); - await cameraController?.initialize(); + try { + await cameraController?.initialize(); + } catch (e) { + Log.error(e); + return; + } await cameraController?.startImageStream(_processCameraImage); await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor); if (userService.currentUser.videoStabilizationEnabled && !kDebugMode) { diff --git a/lib/src/visual/views/chats/media_viewer.view.dart b/lib/src/visual/views/chats/media_viewer.view.dart index 5158ada4..d6363a71 100644 --- a/lib/src/visual/views/chats/media_viewer.view.dart +++ b/lib/src/visual/views/chats/media_viewer.view.dart @@ -61,7 +61,7 @@ class _MediaViewerViewState extends State { Message? currentMessage; DateTime? canBeSeenUntil; - double progress = 0; + final ValueNotifier progress = ValueNotifier(0); bool showSendTextMessageInput = false; final GlobalKey mediaWidgetKey = GlobalKey(); @@ -100,6 +100,7 @@ class _MediaViewerViewState extends State { progressTimer?.cancel(); _subscription?.cancel(); downloadStateListener?.cancel(); + progress.dispose(); ScreenProtector.preventScreenshotOff(); @@ -226,7 +227,7 @@ class _MediaViewerViewState extends State { canBeSeenUntil = null; imageSaving = false; imageSaved = false; - progress = 0; + progress.value = 0; showSendTextMessageInput = false; }); @@ -388,9 +389,7 @@ class _MediaViewerViewState extends State { final duration = ctrl.value.duration.inSeconds; if (duration > 0) { - setState(() { - progress = 1 - ctrl.value.position.inSeconds / duration; - }); + progress.value = 1 - ctrl.value.position.inSeconds / duration; } if (currentMediaLocal.mediaFile.displayLimitInMilliseconds != @@ -450,9 +449,8 @@ class _MediaViewerViewState extends State { } final difference = canBeSeenUntil!.difference(clock.now()); // Calculate the progress as a value between 0.0 and 1.0 - progress = + progress.value = difference.inMilliseconds / (mediaFile.displayLimitInMilliseconds!); - setState(() {}); }); } } @@ -647,7 +645,7 @@ class _MediaViewerViewState extends State { children: [ if (_showDownloadingLoader) _loader(), if ((currentMedia != null || videoController != null) && - (canBeSeenUntil == null || progress >= 0)) + (canBeSeenUntil == null || progress.value >= 0)) GestureDetector( onTap: onTap, onDoubleTap: (videoController == null) ? null : onTap, @@ -717,7 +715,7 @@ class _MediaViewerViewState extends State { if (currentMedia != null && currentMedia?.mediaFile.downloadState != DownloadState.ready) Positioned.fill(child: _loader()), - if (canBeSeenUntil != null || progress >= 0) + if (canBeSeenUntil != null || progress.value >= 0) Positioned( right: 20, top: 27, @@ -726,9 +724,14 @@ class _MediaViewerViewState extends State { SizedBox( width: 20, height: 20, - child: CircularProgressIndicator( - value: progress, - strokeWidth: 2, + child: ValueListenableBuilder( + valueListenable: progress, + builder: (context, value, child) { + return CircularProgressIndicator( + value: value, + strokeWidth: 2, + ); + }, ), ), ], diff --git a/lib/src/visual/views/home.view.dart b/lib/src/visual/views/home.view.dart index 27e90248..e5afc67b 100644 --- a/lib/src/visual/views/home.view.dart +++ b/lib/src/visual/views/home.view.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:app_links/app_links.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_sharing_intent/model/sharing_file.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/locator.dart'; @@ -40,9 +41,11 @@ class HomeViewState extends State { final MainCameraController _mainCameraController = MainCameraController(); final PageController _homeViewPageController = PageController(initialPage: 1); - late StreamSubscription> _intentStreamSub; - late StreamSubscription _deepLinkSub; + StreamSubscription>? _intentStreamSub; + StreamSubscription? _deepLinkSub; StreamSubscription? _onMessageOpenedAppSub; + StreamSubscription? _homeViewPageIndexSub; + StreamSubscription? _selectNotificationSub; static final streamHomeViewPageIndex = StreamController.broadcast(); @@ -53,14 +56,16 @@ class HomeViewState extends State { if (mounted) setState(() {}); }; - streamHomeViewPageIndex.stream.listen((index) { + _homeViewPageIndexSub = streamHomeViewPageIndex.stream.listen((index) { _homeViewPageController.jumpToPage(index); setState(() { _activePageIdx = index; }); }); - selectNotificationStream.stream.listen((response) async { + _selectNotificationSub = selectNotificationStream.stream.listen(( + response, + ) async { if (response.payload != null && response.payload!.startsWith(Routes.chats) && response.payload! != Routes.chats) { @@ -110,8 +115,8 @@ class HomeViewState extends State { RemoteMessage? initialRemoteMessage; try { - initialRemoteMessage = - await FirebaseMessaging.instance.getInitialMessage(); + initialRemoteMessage = await FirebaseMessaging.instance + .getInitialMessage(); } catch (e) { Log.error('Could not get initial Firebase message: $e'); } @@ -157,12 +162,12 @@ class HomeViewState extends State { @override void dispose() { _onMessageOpenedAppSub?.cancel(); - selectNotificationStream.close(); - streamHomeViewPageIndex.close(); + _homeViewPageIndexSub?.cancel(); + _selectNotificationSub?.cancel(); _disableCameraTimer?.cancel(); _mainCameraController.closeCamera(); - _intentStreamSub.cancel(); - _deepLinkSub.cancel(); + _intentStreamSub?.cancel(); + _deepLinkSub?.cancel(); super.dispose(); }