From 6ec24c3757cf6da8a2459ddc67379648d5459e44 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 13 Nov 2023 17:40:11 +0100 Subject: [PATCH 1/8] Add localization with navigatorKey --- .../flutter_enricher_event_processor.dart | 5 +++- flutter/lib/src/localizations.dart | 13 +++++++++ flutter/pubspec.yaml | 2 ++ ...flutter_enricher_event_processor_test.dart | 29 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 flutter/lib/src/localizations.dart diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index b0eaa0fe71..781395509d 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:sentry/sentry.dart'; +import '../localizations.dart'; import '../navigation/sentry_navigator_observer.dart'; import '../sentry_flutter_options.dart'; @@ -107,7 +108,9 @@ class FlutterEnricherEventProcessor implements EventProcessor { } SentryCulture _getCulture(SentryCulture? culture) { - final languageTag = _window?.locale.toLanguageTag(); + final windowLanguageTag = _window?.locale.toLanguageTag(); + final screenLocale = retrieveWidgetLocale(); + final languageTag = screenLocale?.toLanguageTag() ?? windowLanguageTag; // Future enhancement: // _window?.locales diff --git a/flutter/lib/src/localizations.dart b/flutter/lib/src/localizations.dart new file mode 100644 index 0000000000..bbb001b1cb --- /dev/null +++ b/flutter/lib/src/localizations.dart @@ -0,0 +1,13 @@ +import 'package:flutter/cupertino.dart'; +import 'package:meta/meta.dart'; + +GlobalKey sentryNavigatorKey = GlobalKey(); + +@internal +Locale? retrieveWidgetLocale() { + final BuildContext? context = sentryNavigatorKey.currentContext; + if (context != null) { + return Localizations.localeOf(context); + } + return null; +} diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index ded2470f09..15b69ec73a 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -29,6 +29,8 @@ dev_dependencies: flutter_lints: ^2.0.0 collection: ^1.16.0 remove_from_coverage: ^2.0.0 + flutter_localizations: + sdk: flutter flutter: plugin: diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index 4e748b2934..fba3b438b9 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -1,13 +1,16 @@ import 'dart:async'; import 'package:flutter/foundation.dart'; + // backcompatibility for Flutter < 3.3 // ignore: unnecessary_import import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/event_processor/flutter_enricher_event_processor.dart'; +import 'package:sentry_flutter/src/localizations.dart'; import '../mocks.dart'; @@ -73,6 +76,32 @@ void main() { expect(culture?.timezone, isNotNull); }); + testWidgets( + 'GIVEN MaterialApp WHEN setting locale and sentryNavigatorKey THEN enrich event culture with selected locale', + (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + navigatorKey: sentryNavigatorKey, + home: Material(), + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: const [ + Locale('en', 'US'), + Locale('de', 'DE'), + ], + locale: const Locale('de', 'DE'), + )); + + final enricher = fixture.getSut( + binding: () => tester.binding, + ); + + final event = await enricher.apply(SentryEvent()); + + expect(event?.contexts.culture?.locale, 'de-DE'); + }); + testWidgets('app context in foreground', (WidgetTester tester) async { final enricher = fixture.getSut( binding: () => tester.binding, From 98f3521820318d6e7f3a6a4a8b557fff0b8716bd Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 13 Nov 2023 17:53:50 +0100 Subject: [PATCH 2/8] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ddc11675..582972566d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixes +- Fixes setting the correct locale to contexts with navigatorKey ([#1724](https://github.com/getsentry/sentry-dart/pull/1724)) + - If you have a selected locale in e.g MaterialApp, this fix will retrieve the correct locale in the event context. - Unsupported types with Expando ([#1690](https://github.com/getsentry/sentry-dart/pull/1690)) ### Features From 22644fa58d832874f8cefce9dd394f3aa6c910db Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 13 Nov 2023 18:15:14 +0100 Subject: [PATCH 3/8] Update tests --- .../flutter_enricher_event_processor.dart | 2 +- flutter/lib/src/localizations.dart | 8 +++---- flutter/lib/src/sentry_flutter_options.dart | 3 +++ ...flutter_enricher_event_processor_test.dart | 21 +++++++++++++++++-- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index 781395509d..bc3d6f4f01 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -109,7 +109,7 @@ class FlutterEnricherEventProcessor implements EventProcessor { SentryCulture _getCulture(SentryCulture? culture) { final windowLanguageTag = _window?.locale.toLanguageTag(); - final screenLocale = retrieveWidgetLocale(); + final screenLocale = retrieveWidgetLocale(_options.navigatorKey); final languageTag = screenLocale?.toLanguageTag() ?? windowLanguageTag; // Future enhancement: diff --git a/flutter/lib/src/localizations.dart b/flutter/lib/src/localizations.dart index bbb001b1cb..f763f496c3 100644 --- a/flutter/lib/src/localizations.dart +++ b/flutter/lib/src/localizations.dart @@ -1,13 +1,11 @@ import 'package:flutter/cupertino.dart'; import 'package:meta/meta.dart'; -GlobalKey sentryNavigatorKey = GlobalKey(); - @internal -Locale? retrieveWidgetLocale() { - final BuildContext? context = sentryNavigatorKey.currentContext; +Locale? retrieveWidgetLocale(GlobalKey? navigatorKey) { + final BuildContext? context = navigatorKey?.currentContext; if (context != null) { - return Localizations.localeOf(context); + return Localizations.maybeLocaleOf(context); } return null; } diff --git a/flutter/lib/src/sentry_flutter_options.dart b/flutter/lib/src/sentry_flutter_options.dart index 7a82f3b53f..8ee18f0aad 100644 --- a/flutter/lib/src/sentry_flutter_options.dart +++ b/flutter/lib/src/sentry_flutter_options.dart @@ -286,4 +286,7 @@ class SentryFlutterOptions extends SentryOptions { // ignore: invalid_use_of_internal_member super.profilesSampleRate = value; } + + /// The navigatorKey used to retrieve the current context of the app. + GlobalKey? navigatorKey; } diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index fba3b438b9..8a6aaf34db 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -79,8 +79,11 @@ void main() { testWidgets( 'GIVEN MaterialApp WHEN setting locale and sentryNavigatorKey THEN enrich event culture with selected locale', (WidgetTester tester) async { + GlobalKey navigatorKey = + GlobalKey(); + await tester.pumpWidget(MaterialApp( - navigatorKey: sentryNavigatorKey, + navigatorKey: navigatorKey, home: Material(), localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, @@ -95,6 +98,10 @@ void main() { final enricher = fixture.getSut( binding: () => tester.binding, + optionsBuilder: (options) { + options.navigatorKey = navigatorKey; + return options; + }, ); final event = await enricher.apply(SentryEvent()); @@ -373,21 +380,31 @@ void main() { } class Fixture { + // options + late SentryFlutterOptions options; + FlutterEnricherEventProcessor getSut({ required WidgetBindingGetter binding, PlatformChecker? checker, bool hasNativeIntegration = false, bool reportPackages = true, + SentryFlutterOptions Function(SentryFlutterOptions)? optionsBuilder, }) { final platformChecker = checker ?? MockPlatformChecker( hasNativeIntegration: hasNativeIntegration, ); + final options = SentryFlutterOptions( dsn: fakeDsn, checker: platformChecker, )..reportPackages = reportPackages; - return FlutterEnricherEventProcessor(options); + + // Allow customization of options through the provided optionsBuilder function + final customizedOptions = optionsBuilder?.call(options) ?? options; + + this.options = customizedOptions; + return FlutterEnricherEventProcessor(customizedOptions); } PageRoute route(RouteSettings? settings) => PageRouteBuilder( From ded8447d21c56e6fb1776db3ba25e213748f1eae Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 13 Nov 2023 18:17:07 +0100 Subject: [PATCH 4/8] Update tests --- .../flutter_enricher_event_processor_test.dart | 7 ------- 1 file changed, 7 deletions(-) diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index 8a6aaf34db..1bca77e125 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -380,9 +380,6 @@ void main() { } class Fixture { - // options - late SentryFlutterOptions options; - FlutterEnricherEventProcessor getSut({ required WidgetBindingGetter binding, PlatformChecker? checker, @@ -399,11 +396,7 @@ class Fixture { dsn: fakeDsn, checker: platformChecker, )..reportPackages = reportPackages; - - // Allow customization of options through the provided optionsBuilder function final customizedOptions = optionsBuilder?.call(options) ?? options; - - this.options = customizedOptions; return FlutterEnricherEventProcessor(customizedOptions); } From a9a610dc0bfa4b50f0b1dbda373a82fb1ebfd815 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 13 Nov 2023 18:18:13 +0100 Subject: [PATCH 5/8] Format --- .../event_processor/flutter_enricher_event_processor_test.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index 1bca77e125..b2a0a60800 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -79,8 +79,7 @@ void main() { testWidgets( 'GIVEN MaterialApp WHEN setting locale and sentryNavigatorKey THEN enrich event culture with selected locale', (WidgetTester tester) async { - GlobalKey navigatorKey = - GlobalKey(); + GlobalKey navigatorKey = GlobalKey(); await tester.pumpWidget(MaterialApp( navigatorKey: navigatorKey, From baf79a4fe29568df62362a1f7cd3708af82a11bc Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 13 Nov 2023 23:26:45 +0100 Subject: [PATCH 6/8] Remove unused import --- .../event_processor/flutter_enricher_event_processor_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index b2a0a60800..d15eca9f4f 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -10,7 +10,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/src/event_processor/flutter_enricher_event_processor.dart'; -import 'package:sentry_flutter/src/localizations.dart'; import '../mocks.dart'; From 7f96dd0283a4931404b4e2999b0a6b48100d38fd Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Tue, 14 Nov 2023 10:48:15 +0100 Subject: [PATCH 7/8] Apply review improvements --- .../flutter_enricher_event_processor.dart | 11 +++++++++-- flutter/lib/src/localizations.dart | 11 ----------- flutter/lib/src/sentry_flutter_options.dart | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) delete mode 100644 flutter/lib/src/localizations.dart diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index bc3d6f4f01..73b486f67c 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:sentry/sentry.dart'; -import '../localizations.dart'; import '../navigation/sentry_navigator_observer.dart'; import '../sentry_flutter_options.dart'; @@ -109,7 +108,7 @@ class FlutterEnricherEventProcessor implements EventProcessor { SentryCulture _getCulture(SentryCulture? culture) { final windowLanguageTag = _window?.locale.toLanguageTag(); - final screenLocale = retrieveWidgetLocale(_options.navigatorKey); + final screenLocale = _retrieveWidgetLocale(_options.navigatorKey); final languageTag = screenLocale?.toLanguageTag() ?? windowLanguageTag; // Future enhancement: @@ -257,4 +256,12 @@ class FlutterEnricherEventProcessor implements EventProcessor { return app; } } + + Locale? _retrieveWidgetLocale(GlobalKey? navigatorKey) { + final BuildContext? context = navigatorKey?.currentContext; + if (context != null) { + return Localizations.maybeLocaleOf(context); + } + return null; + } } diff --git a/flutter/lib/src/localizations.dart b/flutter/lib/src/localizations.dart deleted file mode 100644 index f763f496c3..0000000000 --- a/flutter/lib/src/localizations.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:meta/meta.dart'; - -@internal -Locale? retrieveWidgetLocale(GlobalKey? navigatorKey) { - final BuildContext? context = navigatorKey?.currentContext; - if (context != null) { - return Localizations.maybeLocaleOf(context); - } - return null; -} diff --git a/flutter/lib/src/sentry_flutter_options.dart b/flutter/lib/src/sentry_flutter_options.dart index 8ee18f0aad..1a71a0d37e 100644 --- a/flutter/lib/src/sentry_flutter_options.dart +++ b/flutter/lib/src/sentry_flutter_options.dart @@ -287,6 +287,6 @@ class SentryFlutterOptions extends SentryOptions { super.profilesSampleRate = value; } - /// The navigatorKey used to retrieve the current context of the app. + /// The [navigatorKey] is used to add information of the currently used locale to the contexts. GlobalKey? navigatorKey; } From 2ac3d229f35a52881cde02f4b624eb10294502b8 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Tue, 14 Nov 2023 10:50:27 +0100 Subject: [PATCH 8/8] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 582972566d..0004e3fe72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ ### Fixes - Fixes setting the correct locale to contexts with navigatorKey ([#1724](https://github.com/getsentry/sentry-dart/pull/1724)) - - If you have a selected locale in e.g MaterialApp, this fix will retrieve the correct locale in the event context. + - If you have a selected locale in e.g MaterialApp, this fix will retrieve the correct locale for the event context. - Unsupported types with Expando ([#1690](https://github.com/getsentry/sentry-dart/pull/1690)) ### Features