Skip to content

Commit

Permalink
Merge branch 'stable' into events
Browse files Browse the repository at this point in the history
# Conflicts:
#	lib/src/core/wiredash_widget.dart
  • Loading branch information
passsy committed Apr 5, 2024
2 parents 3f16b5d + 852809f commit 059ada8
Show file tree
Hide file tree
Showing 5 changed files with 933 additions and 3 deletions.
34 changes: 34 additions & 0 deletions lib/src/core/wiredash_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ class WiredashState extends State<Wiredash> {
secret: widget.secret,
);

if (oldWidget.options?.localizationDelegate !=
widget.options?.localizationDelegate) {
_verifySyncLocalizationsDelegate();
}
_services.updateWidget(widget);

_onProjectIdChanged();
}
}
Expand Down Expand Up @@ -421,6 +427,34 @@ class WiredashState extends State<Wiredash> {
// Use what's set by the operating system
return _defaultLocale;
}

void _verifySyncLocalizationsDelegate() {
assert(() {
final delegate = widget.options?.localizationDelegate;
if (delegate == null) {
return true;
}
final locale = _currentLocale;
if (!delegate.isSupported(locale)) {
// load should not be called
return true;
}
final loadFuture = delegate.load(locale);
if (loadFuture is! SynchronousFuture) {
reportWiredashInfo(
'Warning: $delegate load() is async',
StackTrace.current,
'Warning: ${delegate.runtimeType}.load() returned a Future for Locale "$locale".\n'
'This will lead to your app losing all its state when you open Wiredash!\n'
'\tDO return a SynchronousFuture from your LocalizationsDelegate.load() method. \n'
'\tDO NOT use the async keyword in LocalizationsDelegate.load().\n'
'When load() returns SynchronousFuture the Localizations widget can build your app widget with the already loaded localizations at the first frame.\n'
'For more information visit https://github.com/wiredashio/wiredash-sdk/issues/341',
);
}
return true;
}());
}
}

Locale get _defaultLocale {
Expand Down
160 changes: 160 additions & 0 deletions test/issues/issue_341_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:wiredash/wiredash.dart';

import '../util/flutter_error.dart';

void main() {
group('issue 341', () {
testWidgets('no LocalizationsDelegate', (tester) async {
await tester.pumpWidget(const MyApp());
await tester.pumpAndSettle();
expect(TestWidget.createCount, 1);
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
expect(TestWidget.createCount, 1); // Nice!
});

testWidgets('LocalizationsDelegate with SynchronousFuture', (tester) async {
await tester.pumpWidget(const MyApp(asyncDelegate: false));
await tester.pumpAndSettle();
expect(TestWidget.createCount, 1);
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
expect(TestWidget.createCount, 1); // Nice!
});

testWidgets('async LocalizationsDelegate', (tester) async {
final errors = captureFlutterErrors();
await tester.pumpWidget(const MyApp(asyncDelegate: true));
await tester.pumpAndSettle();
expect(TestWidget.createCount, 1);
await tester.tap(find.byType(FloatingActionButton));
await tester.pumpAndSettle();
errors.restoreDefaultErrorHandlers();
// This causes the TestWidget to lose its state
expect(TestWidget.createCount, 2);
expect(errors.presentErrorText, contains("SynchronousFuture"));
expect(
errors.presentErrorText,
contains("AsyncCustomWiredashTranslationsDelegate"),
);
expect(errors.presentError.length, 1);
});
});
}

class MyApp extends StatefulWidget {
const MyApp({
super.key,
this.asyncDelegate,
});

@override
State<MyApp> createState() => _MyAppState();

final bool? asyncDelegate;
}

class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Wiredash(
projectId: "xxxxx",
secret: "xxxxx",
options: WiredashOptionsData(
localizationDelegate: widget.asyncDelegate == null
? null
: widget.asyncDelegate == true
? const AsyncCustomWiredashTranslationsDelegate()
: const SyncCustomWiredashTranslationsDelegate(),
),
child: const MaterialApp(
home: TestWidget(),
),
);
}
}

class TestWidget extends StatefulWidget {
const TestWidget({super.key});

@override
State<TestWidget> createState() => _TestWidgetState();

static int createCount = 0;
}

class _TestWidgetState extends State<TestWidget> {
@override
void initState() {
super.initState();
debugPrint("TestWidget initState");
addTearDown(() {
TestWidget.createCount = 0;
});
TestWidget.createCount++;
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: const Placeholder(),
floatingActionButton: FloatingActionButton(
onPressed: () => Wiredash.of(context).show(),
),
);
}
}

class AsyncCustomWiredashTranslationsDelegate
extends LocalizationsDelegate<WiredashLocalizations> {
const AsyncCustomWiredashTranslationsDelegate();

@override
bool isSupported(Locale locale) {
return ['en'].contains(locale.languageCode);
}

@override
Future<WiredashLocalizations> load(Locale locale) async {
switch (locale.languageCode) {
case 'en':
return _EnOverrides();
default:
throw "Unsupported locale $locale";
}
}

@override
bool shouldReload(AsyncCustomWiredashTranslationsDelegate old) => false;
}

class SyncCustomWiredashTranslationsDelegate
extends LocalizationsDelegate<WiredashLocalizations> {
const SyncCustomWiredashTranslationsDelegate();

@override
bool isSupported(Locale locale) {
return ['en'].contains(locale.languageCode);
}

@override
Future<WiredashLocalizations> load(Locale locale) {
switch (locale.languageCode) {
case 'en':
return SynchronousFuture(_EnOverrides());
default:
throw "Unsupported locale $locale";
}
}

@override
bool shouldReload(SyncCustomWiredashTranslationsDelegate old) => false;
}

class _EnOverrides extends WiredashLocalizationsEn {
@override
String get feedbackStep1MessageHint => 'Test';
}
3 changes: 3 additions & 0 deletions wiresdk_sidekick/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ build/

# Directory created by dartdoc
doc/api/

# Lock dependencies for deterministic builds on all systems
!pubspec.lock
Loading

0 comments on commit 059ada8

Please sign in to comment.