Skip to content

Commit 51c7db0

Browse files
committed
Refactor disconnected overlay reconnect UI and simplify reconnect flow
1 parent 8260a7c commit 51c7db0

1 file changed

Lines changed: 71 additions & 69 deletions

File tree

packages/devtools_app/lib/src/framework/observer/disconnect_observer.dart

Lines changed: 71 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:devtools_app_shared/service.dart';
88
import 'package:devtools_app_shared/ui.dart';
99
import 'package:devtools_app_shared/utils.dart';
1010
import 'package:flutter/material.dart';
11+
import 'package:logging/logging.dart';
1112

1213
import '../../framework/framework_core.dart';
1314
import '../../service/connected_app/connection_info.dart';
@@ -18,6 +19,8 @@ import '../../shared/framework/routing.dart';
1819
import '../../shared/globals.dart';
1920
import '../../shared/primitives/query_parameters.dart';
2021

22+
final _log = Logger('disconnect_observer');
23+
2124
class DisconnectObserver extends StatefulWidget {
2225
const DisconnectObserver({
2326
super.key,
@@ -131,6 +134,40 @@ class DisconnectObserverState extends State<DisconnectObserver>
131134
widget.routerDelegate.navigate(snapshotScreenId, args);
132135
}
133136

137+
Widget _buildReconnectActions(ThemeData theme) {
138+
final reconnectButton = ElevatedButton(
139+
onPressed: _attemptReconnect,
140+
child: const Text('Reconnect'),
141+
);
142+
143+
if (!isEmbedded()) {
144+
return Row(
145+
mainAxisAlignment: MainAxisAlignment.center,
146+
children: [
147+
reconnectButton,
148+
const SizedBox(width: defaultSpacing),
149+
ConnectToNewAppButton(
150+
routerDelegate: widget.routerDelegate,
151+
onPressed: hideDisconnectedOverlay,
152+
gaScreen: gac.devToolsMain,
153+
),
154+
],
155+
);
156+
}
157+
158+
return Column(
159+
mainAxisSize: MainAxisSize.min,
160+
children: [
161+
reconnectButton,
162+
const SizedBox(height: defaultSpacing),
163+
Text(
164+
'Or run a new debug session to connect to it.',
165+
style: theme.textTheme.bodyMedium,
166+
),
167+
],
168+
);
169+
}
170+
134171
OverlayEntry _createDisconnectedOverlay() {
135172
final theme = Theme.of(context);
136173
currentDisconnectedOverlay = OverlayEntry(
@@ -153,37 +190,8 @@ class DisconnectObserverState extends State<DisconnectObserver>
153190
const SizedBox(height: defaultSpacing),
154191
if (isReconnecting)
155192
const CircularProgressIndicator()
156-
else if (!isEmbedded())
157-
Row(
158-
mainAxisAlignment: MainAxisAlignment.center,
159-
children: [
160-
ElevatedButton(
161-
onPressed: _attemptReconnect,
162-
child: const Text('Reconnect'),
163-
),
164-
const SizedBox(width: defaultSpacing),
165-
ConnectToNewAppButton(
166-
routerDelegate: widget.routerDelegate,
167-
onPressed: hideDisconnectedOverlay,
168-
gaScreen: gac.devToolsMain,
169-
),
170-
],
171-
)
172193
else
173-
Column(
174-
mainAxisSize: MainAxisSize.min,
175-
children: [
176-
ElevatedButton(
177-
onPressed: _attemptReconnect,
178-
child: const Text('Reconnect'),
179-
),
180-
const SizedBox(height: defaultSpacing),
181-
Text(
182-
'Or run a new debug session to connect to it.',
183-
style: theme.textTheme.bodyMedium,
184-
),
185-
],
186-
),
194+
_buildReconnectActions(theme),
187195
if (reconnectErrorText case final error?) ...[
188196
const SizedBox(height: denseSpacing),
189197
Text(
@@ -219,48 +227,42 @@ class DisconnectObserverState extends State<DisconnectObserver>
219227
_isReconnecting.value = true;
220228
_reconnectErrorText.value = null;
221229

222-
var reconnectionSuccess = false;
223-
224230
try {
225231
await dtdManager.reconnect();
232+
} catch (error, stackTrace) {
233+
_log.warning('Failed to reconnect DTD.', error, stackTrace);
234+
}
226235

227-
final uri = _lastVmServiceUri;
228-
if (uri != null &&
229-
!serviceConnection.serviceManager.connectedState.value.connected) {
230-
// Call initVmService directly — do NOT use routerDelegate.navigate()
231-
// because that goes through _replaceStack which calls manuallyDisconnect
232-
// when clearing the URI, causing the disconnect observer to suppress
233-
// the overlay (userInitiatedConnectionState = true).
234-
reconnectionSuccess = await FrameworkCore.initVmService(
235-
serviceUriAsString: uri,
236-
logException: false,
237-
errorReporter: (title, error) {
238-
_reconnectErrorText.value = '$title, $error';
239-
},
240-
);
241-
} else {
242-
reconnectionSuccess =
243-
serviceConnection.serviceManager.connectedState.value.connected;
244-
}
245-
} catch (e) {
246-
_reconnectErrorText.value = e.toString();
247-
} finally {
248-
_isReconnecting.value = false;
249-
250-
if (reconnectionSuccess ||
251-
serviceConnection.serviceManager.connectedState.value.connected) {
252-
// Success — also update the router so the URI is reflected in the URL.
253-
unawaited(
254-
widget.routerDelegate.updateArgsIfChanged({
255-
DevToolsQueryParams.vmServiceUriKey: _lastVmServiceUri,
256-
}),
257-
);
258-
_reconnectErrorText.value = null;
259-
hideDisconnectedOverlay();
260-
} else {
261-
// Failed (stale URI, VM dead, etc.) — restore the overlay with buttons.
262-
showDisconnectedOverlay();
263-
}
236+
var reconnectionSuccess =
237+
serviceConnection.serviceManager.connectedState.value.connected;
238+
239+
final uri = _lastVmServiceUri;
240+
if (!reconnectionSuccess && uri != null) {
241+
// Call initVmService directly — do NOT use routerDelegate.navigate()
242+
// because that goes through _replaceStack which calls manuallyDisconnect
243+
// when clearing the URI, causing the disconnect observer to suppress
244+
// the overlay (userInitiatedConnectionState = true).
245+
reconnectionSuccess = await FrameworkCore.initVmService(
246+
serviceUriAsString: uri,
247+
logException: false,
248+
errorReporter: (title, error) {
249+
_reconnectErrorText.value = '$title, $error';
250+
},
251+
);
252+
}
253+
254+
_isReconnecting.value = false;
255+
256+
if (reconnectionSuccess) {
257+
unawaited(
258+
widget.routerDelegate.updateArgsIfChanged({
259+
DevToolsQueryParams.vmServiceUriKey: _lastVmServiceUri,
260+
}),
261+
);
262+
_reconnectErrorText.value = null;
263+
hideDisconnectedOverlay();
264+
} else {
265+
showDisconnectedOverlay();
264266
}
265267
}
266268
}

0 commit comments

Comments
 (0)