main
1import 'package:blood_pressure_app/config.dart';
2import 'package:blood_pressure_app/data_util/entry_context.dart';
3import 'package:blood_pressure_app/data_util/full_entry_builder.dart';
4import 'package:blood_pressure_app/features/data_picker/interval_picker.dart';
5import 'package:blood_pressure_app/features/home/navigation_action_buttons.dart';
6import 'package:blood_pressure_app/features/measurement_list/compact_measurement_list.dart';
7import 'package:blood_pressure_app/features/measurement_list/measurement_list.dart';
8import 'package:blood_pressure_app/features/measurement_list/weight_list.dart';
9import 'package:blood_pressure_app/features/statistics/value_graph.dart';
10import 'package:blood_pressure_app/model/storage/interval_store.dart';
11import 'package:blood_pressure_app/model/storage/settings_store.dart';
12import 'package:flutter/material.dart';
13import 'package:flutter/scheduler.dart';
14import 'package:provider/provider.dart';
15
16/// 0 when add entry dialoge has not been shown, 1 when dialoge is scheduled, 2 when dialoge was launched.
17int _appStart = 0;
18
19/// Central screen of the app with graph and measurement list that is the center
20/// of navigation.
21class AppHome extends StatelessWidget {
22 /// Create a home screen.
23 const AppHome({super.key});
24
25 Widget _buildValueGraph(BuildContext context) => Column(
26 children: [
27 Padding(
28 padding: const EdgeInsets.only(right: 8.0),
29 child: SizedBox(
30 height: 240.0,
31 width: MediaQuery.of(context).size.width,
32 child: FullEntryBuilder(
33 rangeType: IntervalStoreManagerLocation.mainPage,
34 onData: (context, records, intakes, notes) => BloodPressureValueGraph(
35 records: records,
36 colors: notes,
37 intakes: intakes,
38 ),
39 ),
40 ),
41 ),
42 IntervalPicker(type: IntervalStoreManagerLocation.mainPage),
43 ],
44 );
45
46 Widget _buildMeasurementList(BuildContext context) => FullEntryBuilder(
47 rangeType: IntervalStoreManagerLocation.mainPage,
48 onEntries: (context, entries) => Padding(
49 padding: const EdgeInsets.only(top: 12.0),
50 child: (context.select<Settings, bool>((s) => s.compactList))
51 ? CompactMeasurementList(data: entries)
52 : MeasurementList(entries: entries),
53 ),
54 );
55
56 @override
57 Widget build(BuildContext context) => SafeArea(
58 child: OrientationBuilder(
59 builder: (BuildContext context, Orientation orientation) {
60 // direct use of settings possible as no listening is required
61 if (_appStart == 0) {
62 if (Provider.of<Settings>(context, listen: false).startWithAddMeasurementPage) {
63 SchedulerBinding.instance.addPostFrameCallback((_) {
64 if (context.mounted) {
65 context.createEntry();
66 _appStart++;
67 } else {
68 _appStart--;
69 }
70 });
71 }
72 _appStart++;
73 }
74
75 if (showValueGraphAsHomeScreenInLandscapeMode && orientation == Orientation.landscape) {
76 return Scaffold(
77 body: _buildValueGraph(context),
78 );
79 }
80 return DefaultTabController(
81 length: 2,
82 child: Scaffold(
83 body: CustomScrollView(
84 slivers: [
85 SliverToBoxAdapter(child: _buildValueGraph(context),),
86 if (!(context.select<Settings, bool>((s) => s.weightInput)))
87 SliverFillRemaining(child: _buildMeasurementList(context)),
88
89 if ((context.select<Settings, bool>((s) => s.weightInput)))
90 const SliverToBoxAdapter(child: TabBar(
91 tabs: [
92 Tab(icon: Icon(Icons.monitor_heart)),
93 Tab(icon: Icon(Icons.scale)),
94 ],
95 )),
96 if ((context.select<Settings, bool>((s) => s.weightInput)))
97 SliverFillRemaining(
98 child: TabBarView(
99 children: [
100 _buildMeasurementList(context),
101 const WeightList(rangeType: IntervalStoreManagerLocation.mainPage),
102 ]
103 ),
104 )
105 ],
106 ),
107 floatingActionButton: const NavigationActionButtons(),
108 ),
109 );
110 },
111 ),
112 );
113}