blob: e37d503eae3e52a1e3bbaa6722bb97dde9be0cc3 [file] [edit]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:devtools_app_shared/ui.dart';
import 'package:devtools_app_shared/utils.dart';
import 'package:flutter/material.dart';
import '../shared/analytics/constants.dart' as gac;
import '../shared/common_widgets.dart';
import '../shared/connection_info.dart';
import '../shared/globals.dart';
import '../shared/routing.dart';
// TODO(kenz): see if we can simplify this widget. Several things have changed
// with DevTools routing and service management code since this widget was
// originally written.
/// Widget that requires business logic to be loaded before building its
/// [builder].
///
/// See [_InitializerState.build] for the logic that determines whether the
/// business logic is loaded.
///
/// Use this widget to wrap pages that require [service.serviceManager] to be
/// connected. As we require additional services to be available, add them
/// here.
class Initializer extends StatefulWidget {
const Initializer({super.key, required this.builder});
/// The builder for the widget's children.
///
/// Will only be built when a connection to an app is established.
final WidgetBuilder builder;
@override
State<Initializer> createState() => _InitializerState();
}
class _InitializerState extends State<Initializer>
with SingleTickerProviderStateMixin, AutoDisposeMixin {
static const _waitForConnectionTimeout = Duration(seconds: 2);
Timer? _timer;
bool _showConnectToNewAppButton = false;
@override
void initState() {
super.initState();
_timer = Timer(_waitForConnectionTimeout, () {
setState(() {
_showConnectToNewAppButton = true;
});
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: serviceConnection.serviceManager.connectedState,
builder: (context, connectedState, _) {
if (connectedState.connected ||
offlineDataController.showingOfflineData.value) {
return widget.builder(context);
}
// TODO(kenz): this should be more sophisticated logic.
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const Spacer(),
CenteredMessage(
_showConnectToNewAppButton
? 'Cannot connect to VM service.'
: 'Waiting for VM service connection...',
),
if (_showConnectToNewAppButton) ...[
const SizedBox(height: defaultSpacing),
ConnectToNewAppButton(
routerDelegate: DevToolsRouterDelegate.of(context),
gaScreen: gac.devToolsMain,
),
],
const Spacer(),
],
);
},
);
}
}