Skip to content

Commit

Permalink
Merge pull request #2331 from acterglobal/ben-better-sentry-reporting
Browse files Browse the repository at this point in the history
Switching from rootNavKey.currentContext! to ProviderContainer
  • Loading branch information
gnunicorn authored Oct 29, 2024
2 parents bfd3f57 + 05c046b commit 3fa1ffe
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 52 deletions.
9 changes: 4 additions & 5 deletions app/integration_test/support/util.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import 'dart:io';

import 'package:acter/common/extensions/acter_build_context.dart';
import 'package:acter/common/utils/constants.dart';
import 'package:acter/common/widgets/spaces/select_space_form_field.dart';
import 'package:acter/config/setup.dart';
import 'package:acter/features/home/data/keys.dart';
import 'package:acter/features/labs/model/labs_features.dart';
import 'package:acter/features/labs/providers/labs_providers.dart';
import 'package:acter/features/search/model/keys.dart';
import 'package:acter/features/settings/widgets/settings_menu.dart';
import 'package:acter/router/router.dart';
import 'package:convenient_test_dev/convenient_test_dev.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -62,7 +61,7 @@ extension ActerUtil on ConvenientTest {
}

Future<void> ensureLabEnabled(LabsFeature feat) async {
if (!rootNavKey.currentContext!.read(isActiveProvider(feat))) {
if (!mainProviderContainer.read(isActiveProvider(feat))) {
// ensure we do actually have access to the main nav.
await find.byKey(Keys.mainNav).should(findsOneWidget);
final quickJumpKey = find.byKey(MainNavKeys.quickJump);
Expand All @@ -80,15 +79,15 @@ extension ActerUtil on ConvenientTest {
final confirmKey = find.byKey(Key('labs-${feat.name}'));
await confirmKey.should(findsOneWidget);
// let's read again
if (!rootNavKey.currentContext!.read(isActiveProvider(feat))) {
if (!mainProviderContainer.read(isActiveProvider(feat))) {
await confirmKey.tap();
}

await tester.pump(const Duration(seconds: 1));

// ensure we are active
assert(
rootNavKey.currentContext!.read(isActiveProvider(feat)),
mainProviderContainer.read(isActiveProvider(feat)),
'Could not activate $feat',
);
}
Expand Down
40 changes: 25 additions & 15 deletions app/lib/config/notifications/init.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'dart:io';

import 'package:acter/common/extensions/acter_build_context.dart';
import 'package:acter/common/providers/app_state_provider.dart';
import 'package:acter/common/providers/sdk_provider.dart';
import 'package:acter/config/env.g.dart';
import 'package:acter/config/notifications/firebase_options.dart';
import 'package:acter/config/notifications/util.dart';
import 'package:acter/config/setup.dart';
import 'package:acter/features/labs/model/labs_features.dart';
import 'package:acter/features/labs/providers/labs_providers.dart';
import 'package:acter/router/router.dart';
Expand Down Expand Up @@ -94,22 +94,38 @@ Future<bool> setupPushNotifications(
}

bool _handleMessageTap(Map<String?, Object?> data) {
_log.info('Notification was tapped. Data: \n $data');
final context = rootNavKey.currentContext;
if (context == null) {
// no context "et", delay by 300ms and try again;
Future.delayed(
const Duration(milliseconds: 300),
() => _handleMessageTap(data),
);
return false;
}
return _handleMessageTapForContext(context, data);
}

bool _handleMessageTapForContext(
BuildContext context,
Map<String?, Object?> data,
) {
_log.info('Notification was tapped. Data: \n $data');
try {
final uri = data['payload'] as String?;
if (uri != null) {
_log.info('Uri found $uri');
if (isCurrentRoute(uri)) {
// ensure we reload
rootNavKey.currentContext!.replace(uri);
context.replace(uri);
} else {
_log.info('Different page, routing');
if (shouldReplaceCurrentRoute(uri)) {
// this is a chat-room page, replace this to allow for
// a smother "back"-navigation story
rootNavKey.currentContext!.pushReplacement(uri);
context.pushReplacement(uri);
} else {
rootNavKey.currentContext!.push(uri);
context.push(uri);
}
}
return true;
Expand All @@ -123,7 +139,7 @@ bool _handleMessageTap(Map<String?, Object?> data) {
return false;
}
// fallback support
rootNavKey.currentContext!.push(
context.push(
makeForward(roomId: roomId, deviceId: deviceId, eventId: eventId),
);
} catch (e, s) {
Expand All @@ -136,7 +152,7 @@ bool _handleMessageTap(Map<String?, Object?> data) {
bool _isEnabled() {
try {
// ignore: use_build_context_synchronously
if (!rootNavKey.currentContext!
if (!mainProviderContainer
.read(isActiveProvider(LabsFeature.mobilePushNotifications))) {
_log.info(
'Showing push notifications has been disabled on this device. Ignoring',
Expand All @@ -153,7 +169,7 @@ bool _shouldShow(String url) {
// we ignore if we are in foreground and looking at that URL
if (isCurrentRoute(url) &&
// ignore: use_build_context_synchronously
rootNavKey.currentContext!.read(isAppInForeground)) {
mainProviderContainer.read(isAppInForeground)) {
return false;
}
return true;
Expand All @@ -164,13 +180,7 @@ Future<List<Client>> _genCurrentClients() async {
'Received the update information for the token. Updating all clients.',
);
List<Client> clients = [];
// ignore: use_build_context_synchronously
final currentContext = rootNavKey.currentContext;
if (currentContext == null) {
_log.warning('No currentContext found. skipping setting of new token');
return clients;
}
final sdk = await currentContext.read(sdkProvider.future);
final sdk = await mainProviderContainer.read(sdkProvider.future);

for (final client in sdk.clients) {
final deviceId = client.deviceId().toString();
Expand Down
7 changes: 3 additions & 4 deletions app/lib/config/notifications/util.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:acter/common/extensions/acter_build_context.dart';
import 'package:acter/config/setup.dart';
import 'package:acter/router/providers/router_providers.dart';
import 'package:acter/router/router.dart';
import 'package:acter/router/utils.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk.dart';
import 'package:shared_preferences/shared_preferences.dart';
Expand All @@ -18,7 +17,7 @@ Future<void> setRejected(String deviceId, bool value) async {
}

bool isCurrentRoute(String uri) {
final currentUri = rootNavKey.currentContext!.read(currentRoutingLocation);
final currentUri = mainProviderContainer.read(currentRoutingLocation);
return currentUri == uri;
}

Expand All @@ -27,7 +26,7 @@ bool shouldReplaceCurrentRoute(String uri) {
return false;
}

final currentUri = rootNavKey.currentContext!.read(currentRoutingLocation);
final currentUri = mainProviderContainer.read(currentRoutingLocation);
return currentUri.startsWith(chatRoomUriMatcher);
}

Expand Down
3 changes: 3 additions & 0 deletions app/lib/config/setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import 'dart:io';

import 'package:acter/config/env.g.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

const userAgent = '${Env.rageshakeAppName}/${Env.rageshakeAppName}';
final defaultLogSetting = Platform.environment.containsKey(rustLogKey)
? Platform.environment[rustLogKey] as String
: Env.defaultRustLog;

final mainProviderContainer = ProviderContainer();

void configSetup() {
// Pass the configuration to the SDK plugin
ActerSdk.setup(
Expand Down
9 changes: 3 additions & 6 deletions app/lib/features/calendar_sync/calendar_sync.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import 'dart:async';
import 'dart:io';

import 'package:acter/common/extensions/acter_build_context.dart';
import 'package:acter/common/themes/colors/color_scheme.dart';
import 'package:acter/config/setup.dart';
import 'package:acter/features/calendar_sync/providers/events_to_sync_provider.dart';
import 'package:acter/features/labs/model/labs_features.dart';
import 'package:acter/features/labs/providers/labs_providers.dart';
import 'package:acter/router/router.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk_ffi.dart';
import 'package:device_calendar/device_calendar.dart';
Expand All @@ -32,7 +31,7 @@ ProviderSubscription<AsyncValue<List<EventAndRsvp>>>? _subscription;

Future<bool> _isEnabled() async {
try {
return (await rootNavKey.currentContext!
return (await mainProviderContainer
.read(asyncIsActiveProvider(LabsFeature.deviceCalendarSync).future));
} catch (e, s) {
_log.severe('Reading current context failed', e, s);
Expand Down Expand Up @@ -87,9 +86,7 @@ Future<void> initCalendarSync({bool ignoreRejection = false}) async {
// clear if it existed before
_subscription?.close();
// start listening
_subscription =
ProviderScope.containerOf(rootNavKey.currentContext!, listen: true)
.listen(
_subscription = mainProviderContainer.listen(
eventsToSyncProvider,
(prev, next) async {
final events = next.valueOrNull;
Expand Down
8 changes: 6 additions & 2 deletions app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ Future<void> _startAppInner(Widget app, bool withSentry) async {
app = DesktopSupport(child: app);
}

// use the globally defined ProviderContainer
final wrappedApp =
UncontrolledProviderScope(container: mainProviderContainer, child: app);

if (withSentry) {
await SentryFlutter.init(
(options) {
Expand All @@ -81,10 +85,10 @@ Future<void> _startAppInner(Widget app, bool withSentry) async {
// and prevent reporting otherwise.
options.beforeSend = sentryBeforeSend;
},
appRunner: () => runApp(app),
appRunner: () => runApp(wrappedApp),
);
} else {
runApp(app);
runApp(wrappedApp);
}
}

Expand Down
27 changes: 12 additions & 15 deletions app/lib/router/shell_routers/chat_shell_router.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:acter/common/extensions/acter_build_context.dart';
import 'package:acter/common/extensions/options.dart';
import 'package:acter/common/providers/chat_providers.dart';
import 'package:acter/common/utils/routes.dart';
import 'package:acter/config/setup.dart';
import 'package:acter/features/chat/pages/room_page.dart';
import 'package:acter/features/chat/pages/room_profile_page.dart';
import 'package:acter/features/chat/widgets/chat_layout_builder.dart';
Expand All @@ -19,8 +19,7 @@ import 'package:go_router/go_router.dart';
/// the chat-ng feature.
Widget _chatLayoutBuilder({Widget? centerChild, Widget? expandedChild}) {
final isChatNg =
rootNavKey.currentContext?.read(isActiveProvider(LabsFeature.chatNG)) ==
true;
mainProviderContainer.read(isActiveProvider(LabsFeature.chatNG)) == true;
return isChatNg
? ChatLayoutBuilder(
roomListWidgetBuilder: (s) => RoomsListNGWidget(onSelected: s),
Expand All @@ -39,9 +38,7 @@ final chatShellRoutes = [
path: Routes.chat.route,
redirect: authGuardRedirect,
pageBuilder: (context, state) {
rootNavKey.currentContext
?.read(selectedChatIdProvider.notifier)
.select(null);
mainProviderContainer.read(selectedChatIdProvider.notifier).select(null);
return NoTransitionPage(
key: state.pageKey,
child: _chatLayoutBuilder(),
Expand All @@ -53,13 +50,13 @@ final chatShellRoutes = [
path: Routes.chatroom.route,
redirect: authGuardRedirect,
pageBuilder: (context, state) {
final isChatNg = rootNavKey.currentContext
?.read(isActiveProvider(LabsFeature.chatNG)) ==
true;
final isChatNg =
mainProviderContainer.read(isActiveProvider(LabsFeature.chatNG)) ==
true;
final roomId = state.pathParameters['roomId']!;

rootNavKey.currentContext
?.read(selectedChatIdProvider.notifier)
mainProviderContainer
.read(selectedChatIdProvider.notifier)
.select(roomId);
return NoTransitionPage(
key: state.pageKey,
Expand All @@ -82,8 +79,8 @@ final chatShellRoutes = [
pageBuilder: (context, state) {
final roomId = state.pathParameters['roomId']
.expect('chatProfile route needs roomId as path param');
rootNavKey.currentContext
?.read(selectedChatIdProvider.notifier)
mainProviderContainer
.read(selectedChatIdProvider.notifier)
.select(roomId);
return NoTransitionPage(
key: state.pageKey,
Expand All @@ -101,8 +98,8 @@ final chatShellRoutes = [
pageBuilder: (context, state) {
final roomId = state.pathParameters['roomId']
.expect('chatSettingsVisibility route needs roomId as path param');
rootNavKey.currentContext
?.read(selectedChatIdProvider.notifier)
mainProviderContainer
.read(selectedChatIdProvider.notifier)
.select(roomId);
return NoTransitionPage(
key: state.pageKey,
Expand Down
9 changes: 4 additions & 5 deletions app/lib/router/utils.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:acter/common/extensions/acter_build_context.dart';
import 'package:acter/common/providers/chat_providers.dart';
import 'package:acter/common/utils/routes.dart';
import 'package:acter/config/app_shell.dart';
import 'package:acter/config/setup.dart';
import 'package:acter/router/providers/router_providers.dart';
import 'package:acter/router/router.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -54,8 +54,7 @@ final chatRoomUriMatcher = RegExp('/chat/.+');

/// helper to figure out how to route to the specific chat room
void goToChat(BuildContext localContext, String roomId) {
final context = rootNavKey.currentContext!;
final currentUri = context.read(currentRoutingLocation);
final currentUri = mainProviderContainer.read(currentRoutingLocation);
if (!currentUri.startsWith(chatRoomUriMatcher)) {
// we are not in a chat room. just a regular push routing
// will do
Expand All @@ -69,13 +68,13 @@ void goToChat(BuildContext localContext, String roomId) {
}

// we are in a chat page
if (roomId == rootNavKey.currentContext!.read(selectedChatIdProvider)) {
if (roomId == mainProviderContainer.read(selectedChatIdProvider)) {
// we are on the same page, nothing to be done
return;
}

// we are on a different chat page. Push replace the current screen
context.pushReplacementNamed(
(rootNavKey.currentContext ?? localContext).pushReplacementNamed(
Routes.chatroom.name,
pathParameters: {'roomId': roomId},
);
Expand Down
2 changes: 2 additions & 0 deletions packages/acter_notifify/lib/acter_notifify.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:acter_notifify/util.dart';
import 'package:acter_notifify/platform/windows.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:logging/logging.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

final _log = Logger('a3::notifify::acter');

Expand Down Expand Up @@ -87,6 +88,7 @@ Future<String?> initializeNotifify({
);
} catch (error, stack) {
final deviceId = client.deviceId().toString();
Sentry.captureException(error, stackTrace: stack);
_log.severe('Failed to setup ntfy for $deviceId', error, stack);
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/acter_notifify/lib/matrix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:acter_notifify/platform/windows.dart';
import 'package:convert/convert.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:logging/logging.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

final _log = Logger('a3::notifify::matrix');
int id = 0;
Expand Down Expand Up @@ -47,6 +48,7 @@ Future<bool> handleMatrixMessage(
return true;
} catch (e, s) {
_log.severe('Parsing Notification failed: $message', e, s);
Sentry.captureException(e, stackTrace: s);
}
return false;
}
Expand Down
Loading

0 comments on commit 3fa1ffe

Please sign in to comment.