Skip to content

Commit 5d57083

Browse files
committed
feat: add support for UIScene
1 parent 7fe0741 commit 5d57083

19 files changed

Lines changed: 412 additions & 370 deletions

File tree

examples/configurable_widget/lib/android_configuration_page.dart

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class _AndroidConfigurationPageState extends State<AndroidConfigurationPage> {
3434
_textEditingController.text = storedName ?? 'World';
3535
_punctuation =
3636
storedPunctuation != null && punctuations.contains(storedPunctuation)
37-
? storedPunctuation
38-
: punctuations.first;
37+
? storedPunctuation
38+
: punctuations.first;
3939
_initialized = true;
4040
});
4141
}
@@ -59,9 +59,7 @@ class _AndroidConfigurationPageState extends State<AndroidConfigurationPage> {
5959
@override
6060
Widget build(BuildContext context) {
6161
return Scaffold(
62-
appBar: AppBar(
63-
title: const Text('Configure widget'),
64-
),
62+
appBar: AppBar(title: const Text('Configure widget')),
6563
body: _initialized
6664
? ListView(
6765
children: [
@@ -88,18 +86,18 @@ class _AndroidConfigurationPageState extends State<AndroidConfigurationPage> {
8886
});
8987
},
9088
items: punctuations
91-
.map((option) => DropdownMenuItem(
92-
value: option,
93-
child: Text(option),
94-
))
89+
.map(
90+
(option) => DropdownMenuItem(
91+
value: option,
92+
child: Text(option),
93+
),
94+
)
9595
.toList(),
9696
),
9797
),
9898
],
9999
)
100-
: const Center(
101-
child: CircularProgressIndicator(),
102-
),
100+
: const Center(child: CircularProgressIndicator()),
103101
bottomNavigationBar: _initialized
104102
? Container(
105103
color: Theme.of(context).colorScheme.surface,

examples/configurable_widget/lib/main.dart

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ Future<void> configureMain() async {
2323
await HomeWidget.initiallyLaunchedFromHomeWidgetConfigure();
2424

2525
if (configuredWidgetId != null) {
26-
return runApp(MaterialApp(
27-
home: AndroidConfigurationPage(widgetId: configuredWidgetId)));
26+
return runApp(
27+
MaterialApp(
28+
home: AndroidConfigurationPage(widgetId: configuredWidgetId),
29+
),
30+
);
2831
}
2932
}
3033
return main();
@@ -44,10 +47,7 @@ Future<void> _initPunctuations() async {
4447
// Needed for communication between the app and the widget
4548
await HomeWidget.setAppGroupId('group.es.antonborri.configurableWidget');
4649
// Save the punctuations to the widget
47-
await HomeWidget.saveWidgetData(
48-
'punctuations',
49-
jsonEncode(punctuations),
50-
);
50+
await HomeWidget.saveWidgetData('punctuations', jsonEncode(punctuations));
5151
}
5252

5353
class MainApp extends StatefulWidget {
@@ -79,12 +79,10 @@ class _MainAppState extends State<MainApp> {
7979
int widgetId,
8080
) async {
8181
final name = await HomeWidget.getWidgetData<String>('name.$widgetId');
82-
final punctuation =
83-
await HomeWidget.getWidgetData<String>('punctuation.$widgetId');
84-
return <String, dynamic>{
85-
'name': name,
86-
'punctuation': punctuation,
87-
};
82+
final punctuation = await HomeWidget.getWidgetData<String>(
83+
'punctuation.$widgetId',
84+
);
85+
return <String, dynamic>{'name': name, 'punctuation': punctuation};
8886
}
8987

9088
/// Loads pinned home screen widget instances (Android: per instance; iOS: per kind).
@@ -95,13 +93,15 @@ class _MainAppState extends State<MainApp> {
9593
for (final w in installedWidgets) {
9694
Map<String, dynamic>? configuration;
9795
if (Platform.isAndroid && w.androidWidgetId != null) {
98-
configuration =
99-
await _androidConfigurationFromStorage(w.androidWidgetId!);
96+
configuration = await _androidConfigurationFromStorage(
97+
w.androidWidgetId!,
98+
);
10099
} else if (Platform.isIOS && w.configuration != null) {
101100
configuration = Map<String, dynamic>.from(w.configuration!);
102101
}
103-
entries
104-
.add(_InstalledWidgetEntry(info: w, configuration: configuration));
102+
entries.add(
103+
_InstalledWidgetEntry(info: w, configuration: configuration),
104+
);
105105
}
106106
if (!mounted) return;
107107
setState(() {
@@ -141,7 +141,7 @@ class _MainAppState extends State<MainApp> {
141141
IconButton(
142142
icon: const Icon(Icons.refresh),
143143
onPressed: _getInstalledWidgets,
144-
)
144+
),
145145
],
146146
),
147147
body: _installedWidgets.isEmpty

examples/configurable_widget/pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ publish_to: 'none'
44
version: 0.1.0
55

66
environment:
7-
sdk: '>=3.5.0 <4.0.0'
7+
sdk: '>=3.10.0 <4.0.0'
8+
flutter: '>=3.38.1'
89

910
resolution: workspace
1011

examples/lockscreen_widgets/pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ publish_to: 'none'
44
version: 0.1.0
55

66
environment:
7-
sdk: ^3.9.2
7+
sdk: '>=3.10.0 <4.0.0'
8+
flutter: '>=3.38.1'
89

910
resolution: workspace
1011

packages/home_widget/example/integration_test/android_test.dart

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,19 @@ void main() {
108108
});
109109

110110
testWidgets('Register Background Callback', (tester) async {
111-
final returnValue =
112-
await HomeWidget.registerInteractivityCallback(backgroundCallback);
111+
final returnValue = await HomeWidget.registerInteractivityCallback(
112+
backgroundCallback,
113+
);
113114
expect(returnValue, true);
114115
});
115116

116117
testWidgets(
117-
'Initially Launched completes and returns null if not launched from widget',
118-
(tester) async {
119-
final retrievedData = await HomeWidget.initiallyLaunchedFromHomeWidget();
120-
expect(retrievedData, isNull);
121-
});
118+
'Initially Launched completes and returns null if not launched from widget',
119+
(tester) async {
120+
final retrievedData = await HomeWidget.initiallyLaunchedFromHomeWidget();
121+
expect(retrievedData, isNull);
122+
},
123+
);
122124

123125
testWidgets('Get Installed Widgets returns empty list', (tester) async {
124126
final retrievedData = await HomeWidget.getInstalledWidgets();
@@ -128,10 +130,7 @@ void main() {
128130
group('saveFile and saveImage', () {
129131
testWidgets('saveFile JSON round-trip', (tester) async {
130132
const key = 'integration_json_file_key';
131-
final data = <String, dynamic>{
132-
'hello': 'world',
133-
'n': 42,
134-
};
133+
final data = <String, dynamic>{'hello': 'world', 'n': 42};
135134
final jsonStr = jsonEncode(data);
136135
final path = await HomeWidget.saveFile(
137136
key,
@@ -155,8 +154,9 @@ void main() {
155154
expect(read, orderedEquals(expected));
156155
});
157156

158-
testWidgets('saveImage decodes asset and saves valid 1x1 PNG',
159-
(tester) async {
157+
testWidgets('saveImage decodes asset and saves valid 1x1 PNG', (
158+
tester,
159+
) async {
160160
const key = 'integration_save_image_key';
161161
final path = await HomeWidget.saveImage(
162162
key,
@@ -171,8 +171,9 @@ void main() {
171171
expect(frame.image.height, 1);
172172
});
173173

174-
testWidgets('saveFile then clear key removes data and file',
175-
(tester) async {
174+
testWidgets('saveFile then clear key removes data and file', (
175+
tester,
176+
) async {
176177
const key = 'integration_savefile_clear_key';
177178
final data = <String, dynamic>{'clear': 'test'};
178179
final jsonStr = jsonEncode(data);
@@ -188,22 +189,23 @@ void main() {
188189
});
189190

190191
testWidgets(
191-
'saveFile then clear key with deleteFile false removes path but keeps file',
192-
(tester) async {
193-
const key = 'integration_savefile_clear_no_delete_key';
194-
final data = <String, dynamic>{'keep': 'on_disk'};
195-
final jsonStr = jsonEncode(data);
196-
final path = await HomeWidget.saveFile(
197-
key,
198-
Uint8List.fromList(utf8.encode(jsonStr)),
199-
extension: 'json',
200-
);
201-
expect(await File(path).exists(), isTrue);
202-
await HomeWidget.saveWidgetData(key, null, deleteFile: false);
203-
expect(await HomeWidget.getWidgetData(key), isNull);
204-
expect(await File(path).exists(), isTrue);
205-
expect(jsonDecode(await File(path).readAsString()), data);
206-
});
192+
'saveFile then clear key with deleteFile false removes path but keeps file',
193+
(tester) async {
194+
const key = 'integration_savefile_clear_no_delete_key';
195+
final data = <String, dynamic>{'keep': 'on_disk'};
196+
final jsonStr = jsonEncode(data);
197+
final path = await HomeWidget.saveFile(
198+
key,
199+
Uint8List.fromList(utf8.encode(jsonStr)),
200+
extension: 'json',
201+
);
202+
expect(await File(path).exists(), isTrue);
203+
await HomeWidget.saveWidgetData(key, null, deleteFile: false);
204+
expect(await HomeWidget.getWidgetData(key), isNull);
205+
expect(await File(path).exists(), isTrue);
206+
expect(jsonDecode(await File(path).readAsString()), data);
207+
},
208+
);
207209
});
208210
}
209211

packages/home_widget/example/integration_test/ios_test.dart

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,7 @@ void main() {
9191
group('saveFile and saveImage', () {
9292
testWidgets('saveFile JSON round-trip', (tester) async {
9393
const key = 'integration_json_file_key';
94-
final data = <String, dynamic>{
95-
'hello': 'world',
96-
'n': 42,
97-
};
94+
final data = <String, dynamic>{'hello': 'world', 'n': 42};
9895
final jsonStr = jsonEncode(data);
9996
final path = await HomeWidget.saveFile(
10097
key,
@@ -118,8 +115,9 @@ void main() {
118115
expect(read, orderedEquals(expected));
119116
});
120117

121-
testWidgets('saveImage decodes asset and saves valid 1x1 PNG',
122-
(tester) async {
118+
testWidgets('saveImage decodes asset and saves valid 1x1 PNG', (
119+
tester,
120+
) async {
123121
const key = 'integration_save_image_key';
124122
final path = await HomeWidget.saveImage(
125123
key,
@@ -134,8 +132,9 @@ void main() {
134132
expect(frame.image.height, 1);
135133
});
136134

137-
testWidgets('saveFile then clear key removes data and file',
138-
(tester) async {
135+
testWidgets('saveFile then clear key removes data and file', (
136+
tester,
137+
) async {
139138
const key = 'integration_savefile_clear_key';
140139
final data = <String, dynamic>{'clear': 'test'};
141140
final jsonStr = jsonEncode(data);
@@ -151,22 +150,23 @@ void main() {
151150
});
152151

153152
testWidgets(
154-
'saveFile then clear key with deleteFile false removes path but keeps file',
155-
(tester) async {
156-
const key = 'integration_savefile_clear_no_delete_key';
157-
final data = <String, dynamic>{'keep': 'on_disk'};
158-
final jsonStr = jsonEncode(data);
159-
final path = await HomeWidget.saveFile(
160-
key,
161-
Uint8List.fromList(utf8.encode(jsonStr)),
162-
extension: 'json',
163-
);
164-
expect(await File(path).exists(), isTrue);
165-
await HomeWidget.saveWidgetData(key, null, deleteFile: false);
166-
expect(await HomeWidget.getWidgetData(key), isNull);
167-
expect(await File(path).exists(), isTrue);
168-
expect(jsonDecode(await File(path).readAsString()), data);
169-
});
153+
'saveFile then clear key with deleteFile false removes path but keeps file',
154+
(tester) async {
155+
const key = 'integration_savefile_clear_no_delete_key';
156+
final data = <String, dynamic>{'keep': 'on_disk'};
157+
final jsonStr = jsonEncode(data);
158+
final path = await HomeWidget.saveFile(
159+
key,
160+
Uint8List.fromList(utf8.encode(jsonStr)),
161+
extension: 'json',
162+
);
163+
expect(await File(path).exists(), isTrue);
164+
await HomeWidget.saveWidgetData(key, null, deleteFile: false);
165+
expect(await HomeWidget.getWidgetData(key), isNull);
166+
expect(await File(path).exists(), isTrue);
167+
expect(jsonDecode(await File(path).readAsString()), data);
168+
},
169+
);
170170
});
171171

172172
testWidgets('Update Widget completes', (tester) async {
@@ -198,31 +198,30 @@ void main() {
198198

199199
group('Initially Launched', () {
200200
testWidgets(
201-
'Initially Launched completes and returns null if not launched from widget',
202-
(tester) async {
203-
await HomeWidget.setAppGroupId(integrationAppGroupId);
204-
final retrievedData =
205-
await HomeWidget.initiallyLaunchedFromHomeWidget();
206-
expect(retrievedData, isNull);
207-
});
201+
'Initially Launched completes and returns null if not launched from widget',
202+
(tester) async {
203+
await HomeWidget.setAppGroupId(integrationAppGroupId);
204+
final retrievedData =
205+
await HomeWidget.initiallyLaunchedFromHomeWidget();
206+
expect(retrievedData, isNull);
207+
},
208+
);
208209

209210
group('Register Background Callback', () {
210-
testWidgets('RegisterBackgroundCallback completes without error',
211-
(tester) async {
211+
testWidgets('RegisterBackgroundCallback completes without error', (
212+
tester,
213+
) async {
212214
final deviceInfo = await DeviceInfoPlugin().iosInfo;
213215
final hasInteractiveWidgets =
214216
double.parse(deviceInfo.systemVersion.split('.').first) >= 17.0;
215217
await HomeWidget.setAppGroupId(integrationAppGroupId);
216218
if (hasInteractiveWidgets) {
217219
final registerCallbackResult =
218220
await HomeWidget.registerInteractivityCallback(
219-
interactivityCallback,
220-
);
221+
interactivityCallback,
222+
);
221223

222-
expect(
223-
registerCallbackResult,
224-
isTrue,
225-
);
224+
expect(registerCallbackResult, isTrue);
226225
} else {
227226
expect(
228227
() async => await HomeWidget.registerInteractivityCallback(
@@ -250,9 +249,7 @@ void main() {
250249
);
251250

252251
await expectLater(
253-
HomeWidget.requestPinWidget(
254-
name: 'HomeWidgetExample',
255-
),
252+
HomeWidget.requestPinWidget(name: 'HomeWidgetExample'),
256253
completes,
257254
);
258255

@@ -261,10 +258,7 @@ void main() {
261258
completion(isNull),
262259
);
263260

264-
await expectLater(
265-
HomeWidget.finishHomeWidgetConfigure(),
266-
completes,
267-
);
261+
await expectLater(HomeWidget.finishHomeWidgetConfigure(), completes);
268262
});
269263
});
270264

@@ -286,8 +280,9 @@ void main() {
286280
);
287281
});
288282

289-
testWidgets('save/get widget data with appGroupId override',
290-
(tester) async {
283+
testWidgets('save/get widget data with appGroupId override', (
284+
tester,
285+
) async {
291286
await HomeWidget.saveWidgetData(
292287
keyValueKey,
293288
'value',

0 commit comments

Comments
 (0)