Skip to content

Commit 2a0b6db

Browse files
open_wearable/lib/widgets/sensors/configuration/sensor_configuration_device_row.dart: restructured code to avoid unmounted widgets
1 parent fde6d8a commit 2a0b6db

File tree

2 files changed

+113
-102
lines changed

2 files changed

+113
-102
lines changed

open_wearable/lib/widgets/sensors/configuration/sensor_configuration_device_row.dart

Lines changed: 105 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,19 @@ class SensorConfigurationDeviceRow extends StatefulWidget {
2323
class _SensorConfigurationDeviceRowState extends State<SensorConfigurationDeviceRow>
2424
with SingleTickerProviderStateMixin {
2525
late TabController _tabController;
26-
2726
List<Widget> _content = [];
2827

2928
@override
3029
void initState() {
3130
super.initState();
3231
_tabController = TabController(length: 2, vsync: this);
3332
_tabController.addListener(() {
34-
if (_tabController.indexIsChanging) {
35-
_buildContent(context);
33+
if (!_tabController.indexIsChanging) {
34+
_updateContent();
3635
}
3736
});
3837
_content = [PlatformCircularProgressIndicator()];
39-
_buildContent(context);
38+
_updateContent();
4039
}
4140

4241
@override
@@ -66,97 +65,11 @@ class _SensorConfigurationDeviceRowState extends State<SensorConfigurationDevice
6665
);
6766
}
6867

69-
Future<void> _buildContent(BuildContext context) async {
70-
final device = widget.device;
68+
Future<void> _updateContent() async {
69+
final Wearable device = widget.device;
7170

72-
if (device is SensorConfigurationManager) {
73-
if (_tabController.index == 0) {
74-
List<Widget> content = (device as SensorConfigurationManager).sensorConfigurations
75-
.map((config) => SensorConfigurationValueRow(sensorConfiguration: config)).cast<Widget>()
76-
.toList();
77-
78-
// Store Config
79-
content.addAll([
80-
const Divider(),
81-
SaveConfigRow(),
82-
]);
83-
84-
if (device is EdgeRecorderManager) {
85-
content.addAll([
86-
const Divider(),
87-
EdgeRecorderPrefixRow(
88-
manager: device as EdgeRecorderManager,
89-
),
90-
]);
91-
}
92-
setState(() {
93-
_content = content;
94-
});
95-
} else {
96-
setState(() {
97-
_content = [PlatformCircularProgressIndicator()];
98-
});
99-
100-
List<String> configKeys = await SensorConfigurationStorage.listConfigurationKeys();
101-
102-
if (configKeys.isEmpty) {
103-
setState(() {
104-
_content = [
105-
PlatformListTile(title: Text("No configurations found")),
106-
];
107-
});
108-
return;
109-
}
110-
111-
setState(() {
112-
_content = configKeys.map((key) {
113-
return PlatformListTile(
114-
onTap: () {
115-
// Load the selected configuration
116-
SensorConfigurationStorage.loadConfiguration(key).then((config) async {
117-
if (mounted) {
118-
bool result = await Provider.of<SensorConfigurationProvider>(context, listen: false)
119-
.restoreFromJson(config);
120-
121-
if (!result && mounted) {
122-
showPlatformDialog(
123-
context: context,
124-
builder: (context) {
125-
return PlatformAlertDialog(
126-
title: Text("Error"),
127-
content: Text("Failed to load configuration: $key"),
128-
actions: [
129-
PlatformDialogAction(
130-
child: PlatformText("OK"),
131-
onPressed: () => Navigator.of(context).pop(),
132-
),
133-
],
134-
);
135-
},
136-
);
137-
return;
138-
}
139-
// switch the tab to the first one
140-
_tabController.index = 0;
141-
_buildContent(context);
142-
}
143-
});
144-
},
145-
title: Text(key),
146-
trailing: PlatformIconButton(
147-
icon: Icon(context.platformIcons.delete),
148-
onPressed: () async {
149-
await SensorConfigurationStorage.deleteConfiguration(key);
150-
if (mounted) {
151-
_buildContent(context);
152-
}
153-
},
154-
),
155-
);
156-
}).toList();
157-
});
158-
}
159-
} else {
71+
if (device is! SensorConfigurationManager) {
72+
if (!mounted) return;
16073
setState(() {
16174
_content = [
16275
const Padding(
@@ -165,11 +78,109 @@ class _SensorConfigurationDeviceRowState extends State<SensorConfigurationDevice
16578
),
16679
];
16780
});
81+
return;
82+
}
83+
84+
final SensorConfigurationManager sensorManager = device as SensorConfigurationManager;
85+
86+
if (_tabController.index == 0) {
87+
_buildNewTabContent(sensorManager);
88+
} else {
89+
await _buildLoadTabContent(sensorManager);
90+
}
91+
}
92+
93+
void _buildNewTabContent(SensorConfigurationManager device) {
94+
final List<Widget> content = device.sensorConfigurations
95+
.map((config) => SensorConfigurationValueRow(sensorConfiguration: config))
96+
.cast<Widget>()
97+
.toList();
98+
99+
content.addAll([
100+
const Divider(),
101+
const SaveConfigRow(),
102+
]);
103+
104+
if (device is EdgeRecorderManager) {
105+
content.addAll([
106+
const Divider(),
107+
EdgeRecorderPrefixRow(manager: device as EdgeRecorderManager),
108+
]);
109+
}
110+
111+
if (!mounted) return;
112+
setState(() {
113+
_content = content;
114+
});
115+
}
116+
117+
Future<void> _buildLoadTabContent(SensorConfigurationManager device) async {
118+
if (!mounted) return;
119+
setState(() {
120+
_content = [PlatformCircularProgressIndicator()];
121+
});
122+
123+
final configKeys = await SensorConfigurationStorage.listConfigurationKeys();
124+
125+
if (!mounted) return;
126+
127+
if (configKeys.isEmpty) {
128+
setState(() {
129+
_content = [
130+
PlatformListTile(title: const Text("No configurations found")),
131+
];
132+
});
133+
return;
168134
}
135+
136+
final widgets = configKeys.map((key) {
137+
return PlatformListTile(
138+
title: Text(key),
139+
onTap: () async {
140+
final config = await SensorConfigurationStorage.loadConfiguration(key);
141+
if (!mounted) return;
142+
143+
final result = await Provider.of<SensorConfigurationProvider>(context, listen: false)
144+
.restoreFromJson(config);
145+
146+
if (!result && mounted) {
147+
showPlatformDialog(
148+
context: context,
149+
builder: (_) => PlatformAlertDialog(
150+
title: const Text("Error"),
151+
content: Text("Failed to load configuration: $key"),
152+
actions: [
153+
PlatformDialogAction(
154+
child: PlatformText("OK"),
155+
onPressed: () => Navigator.of(context).pop(),
156+
),
157+
],
158+
),
159+
);
160+
return;
161+
}
162+
163+
_tabController.index = 0;
164+
_updateContent();
165+
},
166+
trailing: PlatformIconButton(
167+
icon: Icon(context.platformIcons.delete),
168+
onPressed: () async {
169+
await SensorConfigurationStorage.deleteConfiguration(key);
170+
if (mounted) _updateContent();
171+
},
172+
),
173+
);
174+
}).toList();
175+
176+
setState(() {
177+
_content = widgets;
178+
});
169179
}
170180

171181
Widget? _buildTabBar(BuildContext context) {
172182
if (widget.device is! SensorConfigurationManager) return null;
183+
173184
return SizedBox(
174185
width: MediaQuery.of(context).size.width * 0.4,
175186
child: TabBar.secondary(

open_wearable/pubspec.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ packages:
1313
dependency: transitive
1414
description:
1515
name: async
16-
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
16+
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
1717
url: "https://pub.dev"
1818
source: hosted
19-
version: "2.12.0"
19+
version: "2.13.0"
2020
bloc:
2121
dependency: transitive
2222
description:
@@ -133,10 +133,10 @@ packages:
133133
dependency: transitive
134134
description:
135135
name: fake_async
136-
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
136+
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
137137
url: "https://pub.dev"
138138
source: hosted
139-
version: "1.3.2"
139+
version: "1.3.3"
140140
ffi:
141141
dependency: transitive
142142
description:
@@ -356,10 +356,10 @@ packages:
356356
dependency: transitive
357357
description:
358358
name: leak_tracker
359-
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
359+
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
360360
url: "https://pub.dev"
361361
source: hosted
362-
version: "10.0.8"
362+
version: "10.0.9"
363363
leak_tracker_flutter_testing:
364364
dependency: transitive
365365
description:
@@ -738,10 +738,10 @@ packages:
738738
dependency: transitive
739739
description:
740740
name: vm_service
741-
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
741+
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
742742
url: "https://pub.dev"
743743
source: hosted
744-
version: "14.3.1"
744+
version: "15.0.0"
745745
web:
746746
dependency: transitive
747747
description:

0 commit comments

Comments
 (0)