diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 07a20b287..f998b62b3 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -43,9 +43,9 @@ import 'package:go_router/go_router.dart'; import 'package:image_picker/image_picker.dart'; import 'package:matrix/matrix.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:universal_html/html.dart' as html; -import 'package:sentry_flutter/sentry_flutter.dart'; import '../../utils/account_bundles.dart'; import '../../utils/localized_exception_extension.dart'; @@ -482,35 +482,46 @@ class ChatController extends State Future? _setReadMarkerFuture; void setReadMarker({String? eventId}) { - if (_setReadMarkerFuture != null) return; - if (_scrolledUp) return; - if (scrollUpBannerEventId != null) return; - if (eventId == null && !room.hasNewMessages && room.notificationCount == 0) { - return; - } + if (_setReadMarkerFuture != null) return; + if (_scrolledUp) return; + if (scrollUpBannerEventId != null) return; + if (eventId == null && + !room.hasNewMessages && + room.notificationCount == 0) { + return; + } - // Do not send read markers when app is not in foreground - // #Pangea - try { - // Pangea# - if (kIsWeb && !Matrix.of(context).webHasFocus) return; + // Do not send read markers when app is not in foreground // #Pangea - } catch (err, s) { - ErrorHandler.logError(e: PangeaWarningError("Web focus error: $err"), s: s); - return; - } - // Pangea# - if (!kIsWeb && WidgetsBinding.instance.lifecycleState != AppLifecycleState.resumed) { - return; - } + try { + // Pangea# + if (kIsWeb && !Matrix.of(context).webHasFocus) return; + // #Pangea + } catch (err, s) { + ErrorHandler.logError( + e: PangeaWarningError("Web focus error: $err"), + s: s, + ); + return; + } + // Pangea# + if (!kIsWeb && + WidgetsBinding.instance.lifecycleState != AppLifecycleState.resumed) { + return; + } - final timeline = this.timeline; - if (timeline == null || timeline.events.isEmpty) { - ErrorHandler.logError(e: PangeaWarningError("Timeline is null or empty"), s: StackTrace.current); - return; - } + final timeline = this.timeline; + if (timeline == null || timeline.events.isEmpty) { + // #Pangea + ErrorHandler.logError( + e: PangeaWarningError("Timeline is null or empty"), + s: StackTrace.current, + ); + // Pangea# + return; + } - Logs().d('Set read marker...', eventId); + Logs().d('Set read marker...', eventId); // ignore: unawaited_futures _setReadMarkerFuture = timeline .setReadMarker( @@ -519,27 +530,32 @@ class ChatController extends State ) .then((_) { _setReadMarkerFuture = null; - }).catchError((e, s) { - ErrorHandler.logError( - e: PangeaWarningError("Failed to set read marker: $e"), - s: s, - m: 'Failed to set read marker for eventId: $eventId', - ); - Sentry.captureException( - e, - stackTrace: s, - withScope: (scope) { - scope.setExtra('extra_info', 'Failed during setReadMarker with eventId: $eventId'); - scope.setTag('where', 'setReadMarker'); - }, - ); - }); + }) + // #Pangea + .catchError((e, s) { + ErrorHandler.logError( + e: PangeaWarningError("Failed to set read marker: $e"), + s: s, + m: 'Failed to set read marker for eventId: $eventId', + ); + Sentry.captureException( + e, + stackTrace: s, + withScope: (scope) { + scope.setExtra( + 'extra_info', + 'Failed during setReadMarker with eventId: $eventId', + ); + scope.setTag('where', 'setReadMarker'); + }, + ); + }); + // Pangea# - if (eventId == null || eventId == timeline.room.lastEvent?.eventId) { - Matrix.of(context).backgroundPush?.cancelNotification(roomId); + if (eventId == null || eventId == timeline.room.lastEvent?.eventId) { + Matrix.of(context).backgroundPush?.cancelNotification(roomId); + } } -} - @override void dispose() { diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index 06e4855ec..c7e9d6e64 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -8,10 +8,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; -import 'package:url_launcher/url_launcher_string.dart'; - import 'package:package_info_plus/package_info_plus.dart'; //adding to check app version - +import 'package:url_launcher/url_launcher_string.dart'; import 'settings.dart'; @@ -20,13 +18,13 @@ class SettingsView extends StatelessWidget { const SettingsView(this.controller, {super.key}); + // #Pangea Future getAppVersion(BuildContext context) async { - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - return L10n.of(context)!.versionText(packageInfo.version, packageInfo.buildNumber); -} - - - + final PackageInfo packageInfo = await PackageInfo.fromPlatform(); + return L10n.of(context)! + .versionText(packageInfo.version, packageInfo.buildNumber); + } + // Pangea# @override Widget build(BuildContext context) { @@ -55,8 +53,6 @@ class SettingsView extends StatelessWidget { key: const Key('SettingsListViewContent'), children: [ FutureBuilder( - - future: controller.profileFuture, builder: (context, snapshot) { final profile = snapshot.data; @@ -149,8 +145,6 @@ class SettingsView extends StatelessWidget { ], ); }, - - ), // #Pangea // Divider( @@ -260,40 +254,41 @@ class SettingsView extends StatelessWidget { // onTap: () => PlatformInfos.showDialog(context), // trailing: const Icon(Icons.chevron_right_outlined), // ), - ListTile( - leading: const Icon(Icons.shield_outlined), - title: Text(L10n.of(context)!.termsAndConditions), - onTap: () => launchUrlString(AppConfig.termsOfServiceUrl), - trailing: const Icon(Icons.open_in_new_outlined), - ), - // Adding the FutureBuilder here - FutureBuilder( - future: getAppVersion(context), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return ListTile( - leading: Icon(Icons.info_outline), - title: Text(snapshot.data ?? L10n.of(context)!.versionNotFound), - ); - } else if (snapshot.hasError) { - return ListTile( - leading: Icon(Icons.error_outline), - title: Text(L10n.of(context)!.versionFetchError), - ); - } else { - return ListTile( - leading: CircularProgressIndicator(), - title: Text(L10n.of(context)!.fetchingVersion), - ); - } - }, - ), - // Conditional ListTile based on the environment (staging or not) - if (Environment.isStaging) - ListTile( - leading: const Icon(Icons.bug_report_outlined), - title: Text(L10n.of(context)!.connectedToStaging), - ), + ListTile( + leading: const Icon(Icons.shield_outlined), + title: Text(L10n.of(context)!.termsAndConditions), + onTap: () => launchUrlString(AppConfig.termsOfServiceUrl), + trailing: const Icon(Icons.open_in_new_outlined), + ), + FutureBuilder( + future: getAppVersion(context), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return ListTile( + leading: const Icon(Icons.info_outline), + title: Text( + snapshot.data ?? L10n.of(context)!.versionNotFound, + ), + ); + } else if (snapshot.hasError) { + return ListTile( + leading: const Icon(Icons.error_outline), + title: Text(L10n.of(context)!.versionFetchError), + ); + } else { + return ListTile( + leading: const CircularProgressIndicator(), + title: Text(L10n.of(context)!.fetchingVersion), + ); + } + }, + ), + // Conditional ListTile based on the environment (staging or not) + if (Environment.isStaging) + ListTile( + leading: const Icon(Icons.bug_report_outlined), + title: Text(L10n.of(context)!.connectedToStaging), + ), // Pangea# ], ), diff --git a/lib/pangea/controllers/my_analytics_controller.dart b/lib/pangea/controllers/my_analytics_controller.dart index 88d5ee1d2..f7017ad0e 100644 --- a/lib/pangea/controllers/my_analytics_controller.dart +++ b/lib/pangea/controllers/my_analytics_controller.dart @@ -114,7 +114,7 @@ class MyAnalyticsController { // adds an event ID to the cache of un-added event IDs // if the event IDs isn't already added void addMessageSinceUpdate(String eventId) { - try{ + try { final List currentCache = messagesSinceUpdate; if (!currentCache.contains(eventId)) { currentCache.add(eventId); @@ -130,20 +130,23 @@ class MyAnalyticsController { debugPrint("reached max messages, updating"); updateAnalytics(); } - } catch (exception, stackTrace) { - ErrorHandler.logError( - e: PangeaWarningError("Failed to add message since update: $exception"), - s: stackTrace, - m: 'Failed to add message since update for eventId: $eventId' - ); - Sentry.captureException( - exception, - stackTrace: stackTrace, - withScope: (scope) { - scope.setExtra('extra_info', 'Failed during addMessageSinceUpdate with eventId: $eventId'); - scope.setTag('where', 'addMessageSinceUpdate'); - } - ); + } catch (exception, stackTrace) { + ErrorHandler.logError( + e: PangeaWarningError("Failed to add message since update: $exception"), + s: stackTrace, + m: 'Failed to add message since update for eventId: $eventId', + ); + Sentry.captureException( + exception, + stackTrace: stackTrace, + withScope: (scope) { + scope.setExtra( + 'extra_info', + 'Failed during addMessageSinceUpdate with eventId: $eventId', + ); + scope.setTag('where', 'addMessageSinceUpdate'); + }, + ); } } @@ -161,44 +164,48 @@ class MyAnalyticsController { // It's a proxy measure for messages sent since last update List get messagesSinceUpdate { try { - Logs().d('Reading messages since update from local storage'); - final dynamic locallySaved = _pangeaController.pStoreService.read( + Logs().d('Reading messages since update from local storage'); + final dynamic locallySaved = _pangeaController.pStoreService.read( + PLocalKey.messagesSinceUpdate, + local: true, + ); + if (locallySaved == null) { + Logs().d('No locally saved messages found, initializing empty list.'); + _pangeaController.pStoreService.save( PLocalKey.messagesSinceUpdate, + [], local: true, ); - if (locallySaved == null) { - Logs().d('No locally saved messages found, initializing empty list.'); - _pangeaController.pStoreService.save( - PLocalKey.messagesSinceUpdate, - [], - local: true, - ); - return []; - } - return locallySaved as List; - } catch (exception, stackTrace) { - ErrorHandler.logError( - e: PangeaWarningError("Failed to get messages since update: $exception"), - s: stackTrace, - m: 'Failed to retrieve messages since update' - ); - Sentry.captureException( - exception, - stackTrace: stackTrace, - withScope: (scope) { - scope.setExtra('extra_info', 'Error during messagesSinceUpdate getter'); - scope.setTag('where', 'messagesSinceUpdate'); - } - ); - _pangeaController.pStoreService.save( - PLocalKey.messagesSinceUpdate, - [], - local: true, - ); return []; + } + return locallySaved.cast(); + } catch (exception, stackTrace) { + ErrorHandler.logError( + e: PangeaWarningError( + "Failed to get messages since update: $exception", + ), + s: stackTrace, + m: 'Failed to retrieve messages since update', + ); + Sentry.captureException( + exception, + stackTrace: stackTrace, + withScope: (scope) { + scope.setExtra( + 'extra_info', + 'Error during messagesSinceUpdate getter', + ); + scope.setTag('where', 'messagesSinceUpdate'); + }, + ); + _pangeaController.pStoreService.save( + PLocalKey.messagesSinceUpdate, + [], + local: true, + ); + return []; } -} - + } Completer? _updateCompleter; Future updateAnalytics() async { diff --git a/lib/pangea/utils/error_handler.dart b/lib/pangea/utils/error_handler.dart index eb406d48a..65f73c15b 100644 --- a/lib/pangea/utils/error_handler.dart +++ b/lib/pangea/utils/error_handler.dart @@ -11,6 +11,9 @@ import 'package:sentry_flutter/sentry_flutter.dart'; class PangeaWarningError implements Exception { final String message; PangeaWarningError(message) : message = "Pangea Warning Error: $message"; + + @override + String toString() => message; } class ErrorHandler { @@ -60,8 +63,6 @@ class ErrorHandler { if (m != null) debugPrint("error message: $m"); } - if ((e ?? m) != null) debugPrint("error to string: ${e?.toString() ?? m}"); - if (data != null) { Sentry.addBreadcrumb(Breadcrumb.fromJson(data)); debugPrint(data.toString()); @@ -75,7 +76,6 @@ class ErrorHandler { }, ); } - } class ErrorCopy {