mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-08-01 10:46:44 +00:00

* typos * added `LogbookPhotosProvider` * implemented `LogbookScreen` * implemented `LogbookPhotoEditScreen` * added photo update * save geolocation * added `CameraSettingsSection` * adjusted logbook grid * added hero animation * fixed logbook list updates * added empty logbook state * added `saveLogbookPhotos` option * fixed updating photos * made `DialogPicker` content scrollable * added tests for `LogbookPhotosProvider` * made image preview full-width * made note field multiline * wip * migrated to new iap service * fixed unit tests * typo * fixed arb formatting * stub logbook photos for tests * implemented integration test for logbook * moved date to title * redundant bottom padding * added logbook photo screen to screenshots generator * Update settings.gradle * aligned iap stub with iap release * sync * made logbook iap * debug screenshots * Update runner.dart * fixed dialog picker of optional values * added bottom padding to logbook edit screen * fixed tests * Create camera_stub_image.jpg * Update films_provider_test.dart * rename * Update pubspec.yaml * added logbook to pro features
130 lines
4.1 KiB
Dart
130 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:lightmeter/generated/l10n.dart';
|
|
import 'package:lightmeter/navigation/routes.dart';
|
|
import 'package:lightmeter/platform_config.dart';
|
|
import 'package:lightmeter/providers/logbook_photos_provider.dart';
|
|
import 'package:lightmeter/res/dimens.dart';
|
|
import 'package:lightmeter/screens/logbook_photos/components/grid_tile/widget_grid_tile_logbook_photo.dart';
|
|
import 'package:lightmeter/screens/shared/icon_placeholder/widget_icon_placeholder.dart';
|
|
import 'package:lightmeter/screens/shared/sliver_screen/screen_sliver.dart';
|
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|
|
|
class LogbookPhotosScreen extends StatefulWidget {
|
|
const LogbookPhotosScreen({super.key});
|
|
|
|
@override
|
|
State<LogbookPhotosScreen> createState() => _LogbookPhotosScreenState();
|
|
}
|
|
|
|
class _LogbookPhotosScreenState extends State<LogbookPhotosScreen> with SingleTickerProviderStateMixin {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SliverScreen(
|
|
title: Text(S.of(context).logbook),
|
|
slivers: [
|
|
SliverToBoxAdapter(
|
|
child: Card(
|
|
margin: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: Dimens.paddingM),
|
|
child: SwitchListTile(
|
|
secondary: const Icon(Icons.book_outlined),
|
|
title: Text(S.of(context).saveNewPhotos),
|
|
value: LogbookPhotos.isEnabledOf(context),
|
|
onChanged: LogbookPhotosProvider.of(context).saveLogbookPhotos,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
_PicturesGridBuilder(
|
|
values: LogbookPhotos.of(context),
|
|
onEdit: _editProfile,
|
|
),
|
|
SliverToBoxAdapter(
|
|
child: SizedBox(height: MediaQuery.paddingOf(context).bottom),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
void _editProfile(LogbookPhoto photo) {
|
|
Navigator.of(context).pushNamed(
|
|
NavigationRoutes.logbookPhotoEditScreen.name,
|
|
arguments: photo,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _PicturesGridBuilder extends StatefulWidget {
|
|
final List<LogbookPhoto> values;
|
|
final void Function(LogbookPhoto photo) onEdit;
|
|
|
|
static const int _crossAxisCount = 3;
|
|
|
|
const _PicturesGridBuilder({
|
|
required this.values,
|
|
required this.onEdit,
|
|
});
|
|
|
|
@override
|
|
State<_PicturesGridBuilder> createState() => _PicturesGridBuilderState();
|
|
}
|
|
|
|
class _PicturesGridBuilderState extends State<_PicturesGridBuilder> {
|
|
late Map<String, GlobalKey> _keys = _generateKeys();
|
|
|
|
@override
|
|
void didUpdateWidget(_PicturesGridBuilder oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
_keys = _generateKeys();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (widget.values.isEmpty) {
|
|
return SliverFillRemaining(
|
|
hasScrollBody: false,
|
|
child: Center(
|
|
child: IconPlaceholder(
|
|
icon: Icons.photo_outlined,
|
|
text: S.of(context).noPhotos,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
return SliverPadding(
|
|
padding: const EdgeInsets.all(Dimens.paddingM),
|
|
sliver: SliverGrid(
|
|
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
|
maxCrossAxisExtent: (MediaQuery.sizeOf(context).width -
|
|
Dimens.paddingS * (_PicturesGridBuilder._crossAxisCount - 1) -
|
|
Dimens.paddingM * 2) /
|
|
_PicturesGridBuilder._crossAxisCount,
|
|
mainAxisSpacing: Dimens.paddingS,
|
|
crossAxisSpacing: Dimens.paddingS,
|
|
childAspectRatio: PlatformConfig.cameraPreviewAspectRatio,
|
|
),
|
|
delegate: SliverChildBuilderDelegate(
|
|
//TODO: fix jumping after the photo is edited
|
|
(_, int index) => LogbookPhotoGridTile(
|
|
key: _keys[widget.values[index].id],
|
|
photo: widget.values[index],
|
|
onTap: () => widget.onEdit(widget.values[index]),
|
|
),
|
|
childCount: widget.values.length,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Map<String, GlobalKey> _generateKeys() {
|
|
return Map.fromEntries(
|
|
widget.values.map(
|
|
(photo) => MapEntry(
|
|
photo.id,
|
|
GlobalKey(debugLabel: photo.id),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|