diff --git a/lib/providers/films_provider.dart b/lib/providers/films_provider.dart index 554ecab..ddeb265 100644 --- a/lib/providers/films_provider.dart +++ b/lib/providers/films_provider.dart @@ -114,6 +114,7 @@ class FilmsProviderState extends State { } enum _FilmsModelAspect { + all, customFilms, predefinedFilms, filmsInUse, @@ -134,6 +135,14 @@ class Films extends InheritedModel<_FilmsModelAspect> { required super.child, }); + static List of(BuildContext context) { + final model = InheritedModel.inheritFrom(context, aspect: _FilmsModelAspect.all)!; + return [ + ...model.customFilms.values.map((e) => e.value), + ...model.predefinedFilms.values.map((e) => e.value), + ]; + } + static List predefinedFilmsOf(BuildContext context) { return InheritedModel.inheritFrom(context, aspect: _FilmsModelAspect.predefinedFilms)! .predefinedFilms @@ -171,10 +180,12 @@ class Films extends InheritedModel<_FilmsModelAspect> { bool updateShouldNotifyDependent(Films oldWidget, Set<_FilmsModelAspect> dependencies) { return (dependencies.contains(_FilmsModelAspect.selected) && oldWidget.selected != selected) || ((dependencies.contains(_FilmsModelAspect.predefinedFilms) || - dependencies.contains(_FilmsModelAspect.filmsInUse)) && + dependencies.contains(_FilmsModelAspect.filmsInUse) || + dependencies.contains(_FilmsModelAspect.all)) && const DeepCollectionEquality().equals(oldWidget.predefinedFilms, predefinedFilms)) || ((dependencies.contains(_FilmsModelAspect.customFilms) || - dependencies.contains(_FilmsModelAspect.filmsInUse)) && + dependencies.contains(_FilmsModelAspect.filmsInUse) || + dependencies.contains(_FilmsModelAspect.all)) && const DeepCollectionEquality().equals(oldWidget.customFilms, customFilms)); } } diff --git a/lib/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart b/lib/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart index c0a8a12..1f1a1f8 100644 --- a/lib/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart +++ b/lib/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart @@ -25,6 +25,8 @@ class LogbookPhotoEditBloc extends Bloc _onEquipmentProfileChanged(LogbookPhotoEquipmentProfileChangedEvent event, Emitter emit) async { + _newPhoto = _newPhoto.copyWith(equipmentProfileId: Optional(event.equipmentProfile?.id)); + emit( + state.copyWith( + equipmentProfileId: Optional(event.equipmentProfile?.id), + canSave: _canSave(), + ), + ); + } + + Future _onFilmChanged(LogbookPhotoFilmChangedEvent event, Emitter emit) async { + _newPhoto = _newPhoto.copyWith(filmId: Optional(event.film?.id)); + emit( + state.copyWith( + filmId: Optional(event.film?.id), + canSave: _canSave(), + ), + ); + } + Future _onNoteChanged(LogbookPhotoNoteChangedEvent event, Emitter emit) async { _newPhoto = _newPhoto.copyWith(note: event.note); emit( diff --git a/lib/screens/logbook_photo_edit/components/picker_list_tile/widget_list_tile_picker.dart b/lib/screens/logbook_photo_edit/components/picker_list_tile/widget_list_tile_picker.dart index e969c2b..aa7b9a6 100644 --- a/lib/screens/logbook_photo_edit/components/picker_list_tile/widget_list_tile_picker.dart +++ b/lib/screens/logbook_photo_edit/components/picker_list_tile/widget_list_tile_picker.dart @@ -3,11 +3,12 @@ import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/screens/settings/components/shared/dialog_picker/widget_dialog_picker.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; -class PickerListTile extends StatelessWidget { +class PickerListTile extends StatelessWidget { final IconData icon; final String title; final T? selectedValue; final List values; + final String Function(T) titleAdapter; final ValueChanged> onChanged; const PickerListTile({ @@ -15,6 +16,7 @@ class PickerListTile extends StatelessWidget { required this.title, required this.selectedValue, required this.values, + required this.titleAdapter, required this.onChanged, super.key, }); @@ -24,7 +26,7 @@ class PickerListTile extends StatelessWidget { return ListTile( leading: Icon(icon), title: Text(title), - trailing: Text(selectedValue?.toString() ?? S.of(context).notSet), + trailing: Text(_titleAdapter(context, selectedValue)), onTap: () { showDialog>( context: context, @@ -36,7 +38,7 @@ class PickerListTile extends StatelessWidget { const Optional(null), ...values.toSet().map((e) => Optional(e)), ], - titleAdapter: (context, value) => value.value?.toString() ?? S.of(context).notSet, + titleAdapter: (context, value) => _titleAdapter(context, value.value), ), ).then((value) { if (value != null) { @@ -46,4 +48,8 @@ class PickerListTile extends StatelessWidget { }, ); } + + String _titleAdapter(BuildContext context, T? value) { + return value != null ? titleAdapter(value) : S.of(context).notSet; + } } diff --git a/lib/screens/logbook_photo_edit/event_logbook_photo_edit.dart b/lib/screens/logbook_photo_edit/event_logbook_photo_edit.dart index 8773d09..e5c5ff8 100644 --- a/lib/screens/logbook_photo_edit/event_logbook_photo_edit.dart +++ b/lib/screens/logbook_photo_edit/event_logbook_photo_edit.dart @@ -22,6 +22,18 @@ class LogbookPhotoNoteChangedEvent extends LogbookPhotoEditEvent { const LogbookPhotoNoteChangedEvent(this.note); } +class LogbookPhotoEquipmentProfileChangedEvent extends LogbookPhotoEditEvent { + final EquipmentProfile? equipmentProfile; + + const LogbookPhotoEquipmentProfileChangedEvent(this.equipmentProfile); +} + +class LogbookPhotoFilmChangedEvent extends LogbookPhotoEditEvent { + final Film? film; + + const LogbookPhotoFilmChangedEvent(this.film); +} + class LogbookPhotoSaveEvent extends LogbookPhotoEditEvent { const LogbookPhotoSaveEvent(); } diff --git a/lib/screens/logbook_photo_edit/screen_logbook_photo_edit.dart b/lib/screens/logbook_photo_edit/screen_logbook_photo_edit.dart index 67b14f3..c2c6873 100644 --- a/lib/screens/logbook_photo_edit/screen_logbook_photo_edit.dart +++ b/lib/screens/logbook_photo_edit/screen_logbook_photo_edit.dart @@ -1,9 +1,12 @@ import 'dart:io'; +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/platform_config.dart'; +import 'package:lightmeter/providers/equipment_profile_provider.dart'; +import 'package:lightmeter/providers/films_provider.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/logbook_photo_edit/bloc_logbook_photo_edit.dart'; import 'package:lightmeter/screens/logbook_photo_edit/components/coordinates_list_tile/widget_list_tile_coordinates_logbook_photo.dart'; @@ -73,6 +76,8 @@ class _LogbookPhotoEditScreenState extends State { child: Column( children: [ LogbookPhotoCoordinatesListTile(), + _EquipmentProfilePickerListTile(), + _FilmPickerListTile(), _NoteListTile(), _EvListTile(), _IsoListTile(), @@ -224,6 +229,7 @@ class _AperturePickerListTile extends StatelessWidget { title: S.of(context).apertureValue, values: ApertureValue.values, selectedValue: state.aperture, + titleAdapter: (value) => value.toString(), onChanged: (value) { context.read().add(LogbookPhotoApertureChangedEvent(value.value)); }, @@ -244,6 +250,7 @@ class _ShutterSpeedPickerListTile extends StatelessWidget { title: S.of(context).shutterSpeedValue, values: ShutterSpeedValue.values, selectedValue: state.shutterSpeed, + titleAdapter: (value) => value.toString(), onChanged: (value) { context.read().add(LogbookPhotoShutterSpeedChangedEvent(value.value)); }, @@ -251,3 +258,45 @@ class _ShutterSpeedPickerListTile extends StatelessWidget { ); } } + +class _EquipmentProfilePickerListTile extends StatelessWidget { + const _EquipmentProfilePickerListTile(); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) => previous.equipmentProfileId != current.equipmentProfileId, + builder: (context, state) => PickerListTile( + icon: Icons.camera_alt_outlined, + title: S.of(context).equipmentProfile, + values: EquipmentProfiles.of(context), + selectedValue: EquipmentProfiles.of(context).firstWhereOrNull((e) => e.id == state.equipmentProfileId), + titleAdapter: (value) => value.name, + onChanged: (value) { + context.read().add(LogbookPhotoEquipmentProfileChangedEvent(value.value)); + }, + ), + ); + } +} + +class _FilmPickerListTile extends StatelessWidget { + const _FilmPickerListTile(); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) => previous.filmId != current.filmId, + builder: (context, state) => PickerListTile( + icon: Icons.camera_roll_outlined, + title: S.of(context).film, + values: Films.of(context), + selectedValue: Films.of(context).firstWhereOrNull((e) => e.id == state.filmId), + titleAdapter: (value) => value.name, + onChanged: (value) { + context.read().add(LogbookPhotoFilmChangedEvent(value.value)); + }, + ), + ); + } +} diff --git a/lib/screens/logbook_photo_edit/state_logbook_photo_edit.dart b/lib/screens/logbook_photo_edit/state_logbook_photo_edit.dart index f205fe5..c70f936 100644 --- a/lib/screens/logbook_photo_edit/state_logbook_photo_edit.dart +++ b/lib/screens/logbook_photo_edit/state_logbook_photo_edit.dart @@ -10,6 +10,8 @@ class LogbookPhotoEditState { final Coordinates? coordinates; final ApertureValue? aperture; final ShutterSpeedValue? shutterSpeed; + final String? equipmentProfileId; + final String? filmId; final String? note; final bool canSave; final bool isLoading; @@ -24,6 +26,8 @@ class LogbookPhotoEditState { this.coordinates, this.aperture, this.shutterSpeed, + this.equipmentProfileId, + this.filmId, this.note, required this.canSave, this.isLoading = false, @@ -33,6 +37,8 @@ class LogbookPhotoEditState { String? name, Optional? aperture, Optional? shutterSpeed, + Optional? equipmentProfileId, + Optional? filmId, String? note, bool? canSave, bool? isLoading, @@ -46,6 +52,8 @@ class LogbookPhotoEditState { nd: nd, aperture: aperture != null ? aperture.value : this.aperture, shutterSpeed: shutterSpeed != null ? shutterSpeed.value : this.shutterSpeed, + equipmentProfileId: equipmentProfileId != null ? equipmentProfileId.value : this.equipmentProfileId, + filmId: filmId != null ? filmId.value : this.filmId, note: note ?? this.note, canSave: canSave ?? this.canSave, isLoading: isLoading ?? this.isLoading,