main
  1import 'package:blood_pressure_app/components/confirm_deletion_dialoge.dart';
  2import 'package:blood_pressure_app/components/nullable_text.dart';
  3import 'package:blood_pressure_app/components/pressure_text.dart';
  4import 'package:blood_pressure_app/data_util/entry_context.dart';
  5import 'package:blood_pressure_app/model/storage/storage.dart';
  6import 'package:flutter/material.dart';
  7import 'package:flutter_bloc/flutter_bloc.dart';
  8import 'package:blood_pressure_app/l10n/app_localizations.dart';
  9import 'package:health_data_store/health_data_store.dart';
 10import 'package:intl/intl.dart';
 11
 12/// Display of a blood pressure measurement data.
 13class MeasurementListRow extends StatelessWidget {
 14  /// Create a display of a measurements.
 15  const MeasurementListRow({super.key,
 16    required this.data,
 17    required this.onRequestEdit,
 18  });
 19
 20  /// The measurement to display.
 21  final FullEntry data;
 22
 23  /// Called when the user taps on the edit icon.
 24  final void Function() onRequestEdit; // TODO: consider removing in favor of context methods
 25
 26  @override
 27  Widget build(BuildContext context) {
 28    final localizations = AppLocalizations.of(context)!;
 29    final settings = context.watch<Settings>();
 30    final formatter = DateFormat(settings.dateFormatString);
 31    return ExpansionTile(
 32      // Leading color possible
 33      title: _buildRow(formatter),
 34      childrenPadding: const EdgeInsets.only(bottom: 10),
 35      backgroundColor: data.color == null ? null : Color(data.color!).withAlpha(30),
 36      collapsedShape: data.color == null ? null : Border(
 37        left: BorderSide(color: Color(data.color!), width: 8),
 38      ),
 39      children: [
 40        ListTile(
 41          subtitle: Text(formatter.format(data.time)),
 42          title: Text(localizations.timestamp),
 43          trailing: Row(
 44            mainAxisSize: MainAxisSize.min,
 45            children: [
 46              IconButton(
 47                onPressed: onRequestEdit,
 48                icon: const Icon(Icons.edit),
 49                tooltip: localizations.edit,
 50              ),
 51              IconButton(
 52                onPressed: () => context.deleteEntry(data),
 53                icon: const Icon(Icons.delete),
 54                tooltip: localizations.delete,
 55              ),
 56            ],
 57          ),
 58        ),
 59        if (data.note?.isNotEmpty ?? false)
 60          ListTile(
 61            title: Text(localizations.note),
 62            subtitle: Text(data.note!),
 63          ),
 64        for (final MedicineIntake intake in data.$3)
 65          ListTile(
 66            title: Text(intake.medicine.designation),
 67            subtitle: Text('${intake.dosis.mg}mg'), // TODO: setting for unit
 68            leading: Icon(Icons.medication,
 69              color: intake.medicine.color == null ? null : Color(intake.medicine.color!)),
 70            trailing: IconButton(
 71              onPressed: () async {
 72                final messenger = ScaffoldMessenger.of(context);
 73                final intakeRepo = RepositoryProvider.of<MedicineIntakeRepository>(context);
 74                if (!settings.confirmDeletion || await showConfirmDeletionDialoge(context)) {
 75                  await intakeRepo.remove(intake);
 76                }
 77                messenger.removeCurrentSnackBar();
 78                messenger.showSnackBar(SnackBar(
 79                  content: Text(localizations.deletionConfirmed),
 80                  action: SnackBarAction(
 81                    label: localizations.btnUndo,
 82                    onPressed: () => intakeRepo.add(intake),
 83                  ),
 84                ));
 85              },
 86              icon: const Icon(Icons.delete),
 87            ),
 88          ),
 89      ],
 90    );
 91  }
 92
 93  Row _buildRow(DateFormat formatter) => Row(
 94    children: [
 95      Expanded(
 96        flex: 30,
 97        child: PressureText(data.sys),
 98      ),
 99      Expanded(
100        flex: 30,
101        child: PressureText(data.dia),
102      ),
103      Expanded(
104        flex: 30,
105        child: NullableText((data.pul?.toString())),
106      ),
107      Expanded(
108        flex: 10,
109        child: data.$3.isNotEmpty ? Icon(Icons.medication) : SizedBox.shrink(),
110      ),
111    ],
112  );
113}