70 lines
1.9 KiB
Dart
70 lines
1.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'app_scope.dart';
|
|
import 'dashboard_tab.dart';
|
|
import 'full_log_tab.dart';
|
|
import 'status_bar.dart';
|
|
import 'toolbar.dart';
|
|
|
|
/// Top-level scaffold: toolbar at top, two tabs (Dashboard / Full log),
|
|
/// status bar at bottom. Both tabs share the same controllers; switching
|
|
/// is purely a view change.
|
|
class TabScaffold extends StatefulWidget {
|
|
const TabScaffold({super.key});
|
|
|
|
@override
|
|
State<TabScaffold> createState() => _TabScaffoldState();
|
|
}
|
|
|
|
class _TabScaffoldState extends State<TabScaffold>
|
|
with SingleTickerProviderStateMixin {
|
|
late final TabController _tabs = TabController(length: 2, vsync: this);
|
|
|
|
@override
|
|
void dispose() {
|
|
_tabs.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final scope = AppScope.of(context);
|
|
return Scaffold(
|
|
body: SafeArea(
|
|
child: Column(
|
|
children: [
|
|
const Toolbar(),
|
|
Material(
|
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
|
child: TabBar(
|
|
controller: _tabs,
|
|
tabs: [
|
|
const Tab(text: 'Dashboard'),
|
|
Tab(
|
|
child: ValueListenableBuilder<int>(
|
|
valueListenable: scope.session.logTick,
|
|
builder: (_, __, ___) => Text(
|
|
'Full log (${scope.session.logs.length})',
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Expanded(
|
|
child: TabBarView(
|
|
controller: _tabs,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
children: const [
|
|
DashboardTab(),
|
|
FullLogTab(),
|
|
],
|
|
),
|
|
),
|
|
const StatusBar(),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |