Skip to content

Commit 7da4423

Browse files
committed
read textScale from sentry widget event processor
1 parent a2d3c75 commit 7da4423

7 files changed

+96
-48
lines changed

dart/test/protocol/sentry_app_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void main() {
9090
deviceAppHash: 'hash1',
9191
inForeground: true,
9292
viewNames: ['screen1'],
93-
textScale: 'textScale1'
93+
textScale: 'textScale1',
9494
);
9595

9696
expect('name1', copy.name);

flutter/lib/src/event_processor/flutter_enricher_event_processor.dart

+1-18
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ class FlutterEnricherEventProcessor implements EventProcessor {
5050

5151
final app = contexts.app;
5252
if (app != null) {
53-
contexts.app = _appWithCurrentRouteViewName(app).copyWith(
54-
textScale: _retrieveWidgetTextScale(_options.navigatorKey),
55-
);
53+
contexts.app = _appWithCurrentRouteViewName(app);
5654
}
5755

5856
// Flutter has a lot of Accessibility Settings available and exposes them
@@ -268,21 +266,6 @@ class FlutterEnricherEventProcessor implements EventProcessor {
268266
}
269267
return Localizations.maybeLocaleOf(context);
270268
}
271-
272-
String? _retrieveWidgetTextScale(GlobalKey<NavigatorState>? navigatorKey) {
273-
final context = navigatorKey?.currentContext;
274-
if (context == null) {
275-
return null;
276-
}
277-
final textScaleFactor =
278-
MediaQuery.maybeTextScalerOf(context)?.textScaleFactor;
279-
if (textScaleFactor == null) {
280-
return null;
281-
}
282-
return textScaleFactor == 1.0
283-
? 'no scaling'
284-
: 'linear (${textScaleFactor}x)';
285-
}
286269
}
287270

288271
/// Copied from https://api.flutter.dev/flutter/services/appFlavor-constant.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'dart:async';
2+
3+
import 'package:flutter/widgets.dart';
4+
5+
import '../../sentry_flutter.dart';
6+
7+
class WidgetEventProcessor implements EventProcessor {
8+
@override
9+
FutureOr<SentryEvent?> apply(SentryEvent event, {Hint? hint}) {
10+
if (event is SentryTransaction) {
11+
return event;
12+
}
13+
if (event.exceptions == null && event.throwable == null) {
14+
return event;
15+
}
16+
final context = sentryWidgetGlobalKey.currentContext;
17+
if (context == null) {
18+
return event;
19+
}
20+
final textScaleFactor =
21+
MediaQuery.maybeTextScalerOf(context)?.textScaleFactor;
22+
if (textScaleFactor == null) {
23+
return event;
24+
}
25+
final textScale =
26+
textScaleFactor == 1.0 ? 'no scaling' : 'linear (${textScaleFactor}x)';
27+
return event.copyWith(
28+
contexts: event.contexts.copyWith(
29+
app: event.contexts.app?.copyWith(
30+
textScale: textScale,
31+
),
32+
),
33+
);
34+
}
35+
}

flutter/lib/src/sentry_flutter.dart

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../sentry_flutter.dart';
99
import 'event_processor/android_platform_exception_event_processor.dart';
1010
import 'event_processor/flutter_exception_event_processor.dart';
1111
import 'event_processor/platform_exception_event_processor.dart';
12+
import 'event_processor/widget_event_processor.dart';
1213
import 'integrations/connectivity/connectivity_integration.dart';
1314
import 'integrations/screenshot_integration.dart';
1415
import 'native/factory.dart';
@@ -110,12 +111,13 @@ mixin SentryFlutter {
110111
options.addScopeObserver(NativeScopeObserver(_native!));
111112
}
112113

113-
var flutterEventProcessor = FlutterEnricherEventProcessor(options);
114-
options.addEventProcessor(flutterEventProcessor);
114+
options.addEventProcessor(FlutterEnricherEventProcessor(options));
115+
options.addEventProcessor(WidgetEventProcessor());
115116

116117
if (options.platformChecker.platform.isAndroid) {
117-
options
118-
.addEventProcessor(AndroidPlatformExceptionEventProcessor(options));
118+
options.addEventProcessor(
119+
AndroidPlatformExceptionEventProcessor(options),
120+
);
119121
}
120122

121123
options.addEventProcessor(PlatformExceptionEventProcessor());

flutter/lib/src/sentry_widget.dart

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import 'package:flutter/cupertino.dart';
2+
import 'package:meta/meta.dart';
23
import '../sentry_flutter.dart';
34

5+
/// Key which is used to identify the [SentryWidget]
6+
@internal
7+
final sentryWidgetGlobalKey = GlobalKey(debugLabel: 'sentry_widget');
8+
49
/// This widget serves as a wrapper to include Sentry widgets such
510
/// as [SentryScreenshotWidget] and [SentryUserInteractionWidget].
611
class SentryWidget extends StatefulWidget {
@@ -18,6 +23,9 @@ class _SentryWidgetState extends State<SentryWidget> {
1823
Widget content = widget.child;
1924
content = SentryScreenshotWidget(child: content);
2025
content = SentryUserInteractionWidget(child: content);
21-
return content;
26+
return Container(
27+
key: sentryWidgetGlobalKey,
28+
child: content,
29+
);
2230
}
2331
}

flutter/test/event_processor/flutter_enricher_event_processor_test.dart

-24
Original file line numberDiff line numberDiff line change
@@ -138,30 +138,6 @@ void main() {
138138
expect(event?.contexts.culture?.locale, 'de-DE');
139139
});
140140

141-
testWidgets(
142-
'GIVEN MaterialApp WHEN setting sentryNavigatorKey THEN enrich event app with textScale',
143-
(WidgetTester tester) async {
144-
GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
145-
146-
await tester.pumpWidget(MaterialApp(
147-
navigatorKey: navigatorKey,
148-
home: Material(),
149-
));
150-
151-
final enricher = fixture.getSut(
152-
binding: () => tester.binding,
153-
optionsBuilder: (options) {
154-
options.navigatorKey = navigatorKey;
155-
return options;
156-
},
157-
);
158-
159-
tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.resumed);
160-
final event = await enricher.apply(SentryEvent());
161-
162-
expect(event?.contexts.app?.textScale, 'no scaling');
163-
});
164-
165141
testWidgets('app context in foreground', (WidgetTester tester) async {
166142
final enricher = fixture.getSut(
167143
binding: () => tester.binding,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:sentry_flutter/sentry_flutter.dart';
4+
import 'package:sentry_flutter/src/event_processor/widget_event_processor.dart';
5+
6+
void main() {
7+
TestWidgetsFlutterBinding.ensureInitialized();
8+
late Fixture fixture;
9+
10+
setUp(() {
11+
fixture = Fixture();
12+
});
13+
14+
testWidgets('adds screenshot attachment dart:io', (tester) async {
15+
await tester.runAsync(() async {
16+
final sut = fixture.getSut();
17+
await tester.pumpWidget(
18+
SentryWidget(
19+
child: Text(
20+
'Catching Pokémon is a snap!',
21+
textDirection: TextDirection.ltr,
22+
),
23+
),
24+
);
25+
26+
final throwable = Exception();
27+
SentryEvent? event = SentryEvent(throwable: throwable);
28+
event = event.copyWith(
29+
contexts: event.contexts.copyWith(
30+
app: SentryApp(),
31+
),
32+
);
33+
event = await sut.apply(event);
34+
35+
expect(event?.contexts.app?.textScale, 'no scaling');
36+
});
37+
});
38+
}
39+
40+
class Fixture {
41+
WidgetEventProcessor getSut() {
42+
return WidgetEventProcessor();
43+
}
44+
}

0 commit comments

Comments
 (0)