settings: show/hide shooting details in viewer overlay
This commit is contained in:
parent
924e98f428
commit
bd2d65b699
3 changed files with 165 additions and 93 deletions
|
@ -44,6 +44,9 @@ class Settings extends ChangeNotifier {
|
|||
static const tagSortFactorKey = 'tag_sort_factor';
|
||||
static const pinnedFiltersKey = 'pinned_filters';
|
||||
|
||||
// viewer
|
||||
static const showOverlayShootingDetailsKey = 'show_overlay_shooting_details';
|
||||
|
||||
// info
|
||||
static const infoMapStyleKey = 'info_map_style';
|
||||
static const infoMapZoomKey = 'info_map_zoom';
|
||||
|
@ -150,6 +153,12 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
set pinnedFilters(Set<CollectionFilter> newValue) => setAndNotify(pinnedFiltersKey, newValue.map((filter) => filter.toJson()).toList());
|
||||
|
||||
// viewer
|
||||
|
||||
bool get showOverlayShootingDetails => getBoolOrDefault(showOverlayShootingDetailsKey, true);
|
||||
|
||||
set showOverlayShootingDetails(bool newValue) => setAndNotify(showOverlayShootingDetailsKey, newValue);
|
||||
|
||||
// info
|
||||
|
||||
EntryMapStyle get infoMapStyle => getEnumOrDefault(infoMapStyleKey, EntryMapStyle.stamenWatercolor, EntryMapStyle.values);
|
||||
|
|
|
@ -151,7 +151,7 @@ class _FullscreenBottomOverlayContent extends AnimatedWidget {
|
|||
if (position != null) position,
|
||||
if (entry.bestTitle != null) entry.bestTitle,
|
||||
].join(' – ');
|
||||
final hasShootingDetails = details != null && !details.isEmpty;
|
||||
final hasShootingDetails = details != null && !details.isEmpty && settings.showOverlayShootingDetails;
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/model/settings/home_page.dart';
|
|||
import 'package:aves/model/settings/screen_on.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/utils/constants.dart';
|
||||
import 'package:aves/widgets/common/aves_expansion_tile.dart';
|
||||
import 'package:aves/widgets/common/aves_selection_dialog.dart';
|
||||
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
||||
import 'package:aves/widgets/common/highlight_title.dart';
|
||||
|
@ -11,9 +12,16 @@ import 'package:aves/widgets/settings/svg_background.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class SettingsPage extends StatelessWidget {
|
||||
class SettingsPage extends StatefulWidget {
|
||||
static const routeName = '/settings';
|
||||
|
||||
@override
|
||||
_SettingsPageState createState() => _SettingsPageState();
|
||||
}
|
||||
|
||||
class _SettingsPageState extends State<SettingsPage> {
|
||||
final ValueNotifier<String> _expandedNotifier = ValueNotifier(null);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MediaQueryDataProvider(
|
||||
|
@ -26,98 +34,13 @@ class SettingsPage extends StatelessWidget {
|
|||
body: SafeArea(
|
||||
child: Consumer<Settings>(
|
||||
builder: (context, settings, child) => ListView(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
padding: EdgeInsets.all(8),
|
||||
children: [
|
||||
SectionTitle('Navigation'),
|
||||
ListTile(
|
||||
title: Text('Home'),
|
||||
subtitle: Text(settings.homePage.name),
|
||||
onTap: () async {
|
||||
final value = await showDialog<HomePageSetting>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<HomePageSetting>(
|
||||
initialValue: settings.homePage,
|
||||
options: Map.fromEntries(HomePageSetting.values.map((v) => MapEntry(v, v.name))),
|
||||
title: 'Home',
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
settings.homePage = value;
|
||||
}
|
||||
},
|
||||
),
|
||||
SwitchListTile(
|
||||
value: settings.mustBackTwiceToExit,
|
||||
onChanged: (v) => settings.mustBackTwiceToExit = v,
|
||||
title: Text('Tap “back” twice to exit'),
|
||||
),
|
||||
SectionTitle('Display'),
|
||||
ListTile(
|
||||
title: Text('Keep screen on'),
|
||||
subtitle: Text(settings.keepScreenOn.name),
|
||||
onTap: () async {
|
||||
final value = await showDialog<KeepScreenOn>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<KeepScreenOn>(
|
||||
initialValue: settings.keepScreenOn,
|
||||
options: Map.fromEntries(KeepScreenOn.values.map((v) => MapEntry(v, v.name))),
|
||||
title: 'Keep Screen On',
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
settings.keepScreenOn = value;
|
||||
}
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('SVG background'),
|
||||
trailing: SvgBackgroundSelector(),
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Coordinate format'),
|
||||
subtitle: Text(settings.coordinateFormat.name),
|
||||
onTap: () async {
|
||||
final value = await showDialog<CoordinateFormat>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<CoordinateFormat>(
|
||||
initialValue: settings.coordinateFormat,
|
||||
options: Map.fromEntries(CoordinateFormat.values.map((v) => MapEntry(v, v.name))),
|
||||
optionSubtitleBuilder: (dynamic value) {
|
||||
// dynamic declaration followed by cast, as workaround for generics limitation
|
||||
final formatter = (value as CoordinateFormat);
|
||||
return formatter.format(Constants.pointNemo);
|
||||
},
|
||||
title: 'Coordinate Format',
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
settings.coordinateFormat = value;
|
||||
}
|
||||
},
|
||||
),
|
||||
SectionTitle('Thumbnails'),
|
||||
SwitchListTile(
|
||||
value: settings.showThumbnailLocation,
|
||||
onChanged: (v) => settings.showThumbnailLocation = v,
|
||||
title: Text('Show location icon'),
|
||||
),
|
||||
SwitchListTile(
|
||||
value: settings.showThumbnailRaw,
|
||||
onChanged: (v) => settings.showThumbnailRaw = v,
|
||||
title: Text('Show raw icon'),
|
||||
),
|
||||
SwitchListTile(
|
||||
value: settings.showThumbnailVideoDuration,
|
||||
onChanged: (v) => settings.showThumbnailVideoDuration = v,
|
||||
title: Text('Show video duration'),
|
||||
),
|
||||
SectionTitle('Privacy'),
|
||||
SwitchListTile(
|
||||
value: settings.isCrashlyticsEnabled,
|
||||
onChanged: (v) => settings.isCrashlyticsEnabled = v,
|
||||
title: Text('Allow anonymous analytics and crash reporting'),
|
||||
),
|
||||
GrantedDirectories(),
|
||||
_buildNavigationSection(context),
|
||||
_buildDisplaySection(context),
|
||||
_buildThumbnailsSection(context),
|
||||
_buildViewerSection(context),
|
||||
_buildPrivacySection(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -126,6 +49,146 @@ class SettingsPage extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildNavigationSection(BuildContext context) {
|
||||
return AvesExpansionTile(
|
||||
title: 'Navigation',
|
||||
expandedNotifier: _expandedNotifier,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text('Home'),
|
||||
subtitle: Text(settings.homePage.name),
|
||||
onTap: () async {
|
||||
final value = await showDialog<HomePageSetting>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<HomePageSetting>(
|
||||
initialValue: settings.homePage,
|
||||
options: Map.fromEntries(HomePageSetting.values.map((v) => MapEntry(v, v.name))),
|
||||
title: 'Home',
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
settings.homePage = value;
|
||||
}
|
||||
},
|
||||
),
|
||||
SwitchListTile(
|
||||
value: settings.mustBackTwiceToExit,
|
||||
onChanged: (v) => settings.mustBackTwiceToExit = v,
|
||||
title: Text('Tap “back” twice to exit'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDisplaySection(BuildContext context) {
|
||||
return AvesExpansionTile(
|
||||
title: 'Display',
|
||||
expandedNotifier: _expandedNotifier,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text('Keep screen on'),
|
||||
subtitle: Text(settings.keepScreenOn.name),
|
||||
onTap: () async {
|
||||
final value = await showDialog<KeepScreenOn>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<KeepScreenOn>(
|
||||
initialValue: settings.keepScreenOn,
|
||||
options: Map.fromEntries(KeepScreenOn.values.map((v) => MapEntry(v, v.name))),
|
||||
title: 'Keep Screen On',
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
settings.keepScreenOn = value;
|
||||
}
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text('SVG background'),
|
||||
trailing: SvgBackgroundSelector(),
|
||||
),
|
||||
ListTile(
|
||||
title: Text('Coordinate format'),
|
||||
subtitle: Text(settings.coordinateFormat.name),
|
||||
onTap: () async {
|
||||
final value = await showDialog<CoordinateFormat>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<CoordinateFormat>(
|
||||
initialValue: settings.coordinateFormat,
|
||||
options: Map.fromEntries(CoordinateFormat.values.map((v) => MapEntry(v, v.name))),
|
||||
optionSubtitleBuilder: (dynamic value) {
|
||||
// dynamic declaration followed by cast, as workaround for generics limitation
|
||||
final formatter = (value as CoordinateFormat);
|
||||
return formatter.format(Constants.pointNemo);
|
||||
},
|
||||
title: 'Coordinate Format',
|
||||
),
|
||||
);
|
||||
if (value != null) {
|
||||
settings.coordinateFormat = value;
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildThumbnailsSection(BuildContext context) {
|
||||
return AvesExpansionTile(
|
||||
title: 'Thumbnails',
|
||||
expandedNotifier: _expandedNotifier,
|
||||
children: [
|
||||
SwitchListTile(
|
||||
value: settings.showThumbnailLocation,
|
||||
onChanged: (v) => settings.showThumbnailLocation = v,
|
||||
title: Text('Show location icon'),
|
||||
),
|
||||
SwitchListTile(
|
||||
value: settings.showThumbnailRaw,
|
||||
onChanged: (v) => settings.showThumbnailRaw = v,
|
||||
title: Text('Show raw icon'),
|
||||
),
|
||||
SwitchListTile(
|
||||
value: settings.showThumbnailVideoDuration,
|
||||
onChanged: (v) => settings.showThumbnailVideoDuration = v,
|
||||
title: Text('Show video duration'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildViewerSection(BuildContext context) {
|
||||
return AvesExpansionTile(
|
||||
title: 'Viewer',
|
||||
expandedNotifier: _expandedNotifier,
|
||||
children: [
|
||||
SwitchListTile(
|
||||
value: settings.showOverlayShootingDetails,
|
||||
onChanged: (v) => settings.showOverlayShootingDetails = v,
|
||||
title: Text('Show shooting details'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPrivacySection(BuildContext context) {
|
||||
return AvesExpansionTile(
|
||||
title: 'Privacy',
|
||||
expandedNotifier: _expandedNotifier,
|
||||
children: [
|
||||
SwitchListTile(
|
||||
value: settings.isCrashlyticsEnabled,
|
||||
onChanged: (v) => settings.isCrashlyticsEnabled = v,
|
||||
title: Text('Allow anonymous analytics and crash reporting'),
|
||||
),
|
||||
Container(
|
||||
alignment: AlignmentDirectional.topStart,
|
||||
padding: EdgeInsets.only(bottom: 16),
|
||||
child: GrantedDirectories(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SectionTitle extends StatelessWidget {
|
||||
|
|
Loading…
Reference in a new issue