#68 settings: show/hide motion photo icon on thumbnails

This commit is contained in:
Thibault Deckers 2021-09-13 17:14:36 +09:00
parent 466d150e49
commit db863d68e3
9 changed files with 69 additions and 31 deletions

View file

@ -652,6 +652,8 @@
"@settingsSectionThumbnails": {}, "@settingsSectionThumbnails": {},
"settingsThumbnailShowLocationIcon": "Show location icon", "settingsThumbnailShowLocationIcon": "Show location icon",
"@settingsThumbnailShowLocationIcon": {}, "@settingsThumbnailShowLocationIcon": {},
"settingsThumbnailShowMotionPhotoIcon": "Show motion photo icon",
"@settingsThumbnailShowMotionPhotoIcon": {},
"settingsThumbnailShowRawIcon": "Show raw icon", "settingsThumbnailShowRawIcon": "Show raw icon",
"@settingsThumbnailShowRawIcon": {}, "@settingsThumbnailShowRawIcon": {},
"settingsThumbnailShowVideoDuration": "Show video duration", "settingsThumbnailShowVideoDuration": "Show video duration",

View file

@ -314,6 +314,7 @@
"settingsSectionThumbnails": "섬네일", "settingsSectionThumbnails": "섬네일",
"settingsThumbnailShowLocationIcon": "위치 아이콘 표시", "settingsThumbnailShowLocationIcon": "위치 아이콘 표시",
"settingsThumbnailShowMotionPhotoIcon": "모션 포토 아이콘 표시",
"settingsThumbnailShowRawIcon": "Raw 아이콘 표시", "settingsThumbnailShowRawIcon": "Raw 아이콘 표시",
"settingsThumbnailShowVideoDuration": "동영상 길이 표시", "settingsThumbnailShowVideoDuration": "동영상 길이 표시",

View file

@ -38,6 +38,7 @@ class SettingsDefaults {
EntrySetAction.delete, EntrySetAction.delete,
]; ];
static const showThumbnailLocation = true; static const showThumbnailLocation = true;
static const showThumbnailMotionPhoto = true;
static const showThumbnailRaw = true; static const showThumbnailRaw = true;
static const showThumbnailVideoDuration = true; static const showThumbnailVideoDuration = true;

View file

@ -57,6 +57,7 @@ class Settings extends ChangeNotifier {
static const collectionSortFactorKey = 'collection_sort_factor'; static const collectionSortFactorKey = 'collection_sort_factor';
static const collectionSelectionQuickActionsKey = 'collection_selection_quick_actions'; static const collectionSelectionQuickActionsKey = 'collection_selection_quick_actions';
static const showThumbnailLocationKey = 'show_thumbnail_location'; static const showThumbnailLocationKey = 'show_thumbnail_location';
static const showThumbnailMotionPhotoKey = 'show_thumbnail_motion_photo';
static const showThumbnailRawKey = 'show_thumbnail_raw'; static const showThumbnailRawKey = 'show_thumbnail_raw';
static const showThumbnailVideoDurationKey = 'show_thumbnail_video_duration'; static const showThumbnailVideoDurationKey = 'show_thumbnail_video_duration';
@ -241,6 +242,10 @@ class Settings extends ChangeNotifier {
set showThumbnailLocation(bool newValue) => setAndNotify(showThumbnailLocationKey, newValue); set showThumbnailLocation(bool newValue) => setAndNotify(showThumbnailLocationKey, newValue);
bool get showThumbnailMotionPhoto => getBoolOrDefault(showThumbnailMotionPhotoKey, SettingsDefaults.showThumbnailMotionPhoto);
set showThumbnailMotionPhoto(bool newValue) => setAndNotify(showThumbnailMotionPhotoKey, newValue);
bool get showThumbnailRaw => getBoolOrDefault(showThumbnailRawKey, SettingsDefaults.showThumbnailRaw); bool get showThumbnailRaw => getBoolOrDefault(showThumbnailRawKey, SettingsDefaults.showThumbnailRaw);
set showThumbnailRaw(bool newValue) => setAndNotify(showThumbnailRawKey, newValue); set showThumbnailRaw(bool newValue) => setAndNotify(showThumbnailRawKey, newValue);
@ -494,6 +499,7 @@ class Settings extends ChangeNotifier {
case isCrashlyticsEnabledKey: case isCrashlyticsEnabledKey:
case mustBackTwiceToExitKey: case mustBackTwiceToExitKey:
case showThumbnailLocationKey: case showThumbnailLocationKey:
case showThumbnailMotionPhotoKey:
case showThumbnailRawKey: case showThumbnailRawKey:
case showThumbnailVideoDurationKey: case showThumbnailVideoDurationKey:
case showOverlayMinimapKey: case showOverlayMinimapKey:

View file

@ -1,7 +1,6 @@
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/grid/theme.dart';
import 'package:aves/widgets/common/identity/aves_icons.dart'; import 'package:aves/widgets/common/identity/aves_icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -31,7 +30,6 @@ class GridItemSelectionOverlay<T> extends StatelessWidget {
? OverlayIcon( ? OverlayIcon(
key: ValueKey(isSelected), key: ValueKey(isSelected),
icon: isSelected ? AIcons.selected : AIcons.unselected, icon: isSelected ? AIcons.selected : AIcons.unselected,
size: context.select<GridThemeData, double>((t) => t.iconSize),
) )
: const SizedBox.shrink(); : const SizedBox.shrink();
child = AnimatedSwitcher( child = AnimatedSwitcher(

View file

@ -28,6 +28,7 @@ class GridTheme extends StatelessWidget {
fontSize: fontSize, fontSize: fontSize,
highlightBorderWidth: highlightBorderWidth, highlightBorderWidth: highlightBorderWidth,
showLocation: showLocation ?? settings.showThumbnailLocation, showLocation: showLocation ?? settings.showThumbnailLocation,
showMotionPhoto: settings.showThumbnailMotionPhoto,
showRaw: settings.showThumbnailRaw, showRaw: settings.showThumbnailRaw,
showVideoDuration: settings.showThumbnailVideoDuration, showVideoDuration: settings.showThumbnailVideoDuration,
); );
@ -39,13 +40,14 @@ class GridTheme extends StatelessWidget {
class GridThemeData { class GridThemeData {
final double iconSize, fontSize, highlightBorderWidth; final double iconSize, fontSize, highlightBorderWidth;
final bool showLocation, showRaw, showVideoDuration; final bool showLocation, showMotionPhoto, showRaw, showVideoDuration;
const GridThemeData({ const GridThemeData({
required this.iconSize, required this.iconSize,
required this.fontSize, required this.fontSize,
required this.highlightBorderWidth, required this.highlightBorderWidth,
required this.showLocation, required this.showLocation,
required this.showMotionPhoto,
required this.showRaw, required this.showRaw,
required this.showVideoDuration, required this.showVideoDuration,
}); });

View file

@ -24,7 +24,6 @@ class VideoIcon extends StatelessWidget {
final showDuration = gridTheme.showVideoDuration; final showDuration = gridTheme.showVideoDuration;
Widget child = OverlayIcon( Widget child = OverlayIcon(
icon: entry.is360 ? AIcons.threeSixty : AIcons.videoThumb, icon: entry.is360 ? AIcons.threeSixty : AIcons.videoThumb,
size: gridTheme.iconSize,
text: showDuration ? entry.durationText : null, text: showDuration ? entry.durationText : null,
iconScale: entry.is360 && showDuration ? .9 : 1, iconScale: entry.is360 && showDuration ? .9 : 1,
); );
@ -44,12 +43,13 @@ class VideoIcon extends StatelessWidget {
class AnimatedImageIcon extends StatelessWidget { class AnimatedImageIcon extends StatelessWidget {
const AnimatedImageIcon({Key? key}) : super(key: key); const AnimatedImageIcon({Key? key}) : super(key: key);
static const scale = .8;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OverlayIcon( return const OverlayIcon(
icon: AIcons.animated, icon: AIcons.animated,
size: context.select<GridThemeData, double>((t) => t.iconSize), iconScale: scale,
iconScale: .8,
); );
} }
} }
@ -59,9 +59,8 @@ class GeotiffIcon extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OverlayIcon( return const OverlayIcon(
icon: AIcons.geo, icon: AIcons.geo,
size: context.select<GridThemeData, double>((t) => t.iconSize),
); );
} }
} }
@ -71,9 +70,8 @@ class SphericalImageIcon extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OverlayIcon( return const OverlayIcon(
icon: AIcons.threeSixty, icon: AIcons.threeSixty,
size: context.select<GridThemeData, double>((t) => t.iconSize),
); );
} }
} }
@ -83,9 +81,8 @@ class GpsIcon extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OverlayIcon( return const OverlayIcon(
icon: AIcons.location, icon: AIcons.location,
size: context.select<GridThemeData, double>((t) => t.iconSize),
); );
} }
} }
@ -95,9 +92,22 @@ class RawIcon extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OverlayIcon( return const OverlayIcon(
icon: AIcons.raw, icon: AIcons.raw,
size: context.select<GridThemeData, double>((t) => t.iconSize), );
}
}
class MotionPhotoIcon extends StatelessWidget {
const MotionPhotoIcon({Key? key}) : super(key: key);
static const scale = .8;
@override
Widget build(BuildContext context) {
return const OverlayIcon(
icon: AIcons.motionPhoto,
iconScale: scale,
); );
} }
} }
@ -105,6 +115,8 @@ class RawIcon extends StatelessWidget {
class MultiPageIcon extends StatelessWidget { class MultiPageIcon extends StatelessWidget {
final AvesEntry entry; final AvesEntry entry;
static const scale = .8;
const MultiPageIcon({ const MultiPageIcon({
Key? key, Key? key,
required this.entry, required this.entry,
@ -112,27 +124,19 @@ class MultiPageIcon extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
IconData icon;
String? text; String? text;
if (entry.isMotionPhoto) {
icon = AIcons.motionPhoto;
} else {
if (entry.isBurst) { if (entry.isBurst) {
text = '${entry.burstEntries?.length}'; text = '${entry.burstEntries?.length}';
} }
icon = AIcons.multiPage;
}
final gridTheme = context.watch<GridThemeData>();
final child = OverlayIcon( final child = OverlayIcon(
icon: icon, icon: AIcons.multiPage,
size: gridTheme.iconSize, iconScale: scale,
iconScale: .8,
text: text, text: text,
); );
return DefaultTextStyle( return DefaultTextStyle(
style: TextStyle( style: TextStyle(
color: Colors.grey.shade200, color: Colors.grey.shade200,
fontSize: gridTheme.fontSize, fontSize: context.select<GridThemeData, double>((t) => t.fontSize),
), ),
child: child, child: child,
); );
@ -141,20 +145,19 @@ class MultiPageIcon extends StatelessWidget {
class OverlayIcon extends StatelessWidget { class OverlayIcon extends StatelessWidget {
final IconData icon; final IconData icon;
final double size;
final String? text; final String? text;
final double iconScale; final double iconScale;
const OverlayIcon({ const OverlayIcon({
Key? key, Key? key,
required this.icon, required this.icon,
required this.size,
this.iconScale = 1, this.iconScale = 1,
this.text, this.text,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = context.select<GridThemeData, double>((t) => t.iconSize);
final iconChild = Icon(icon, size: size); final iconChild = Icon(icon, size: size);
final iconBox = SizedBox( final iconBox = SizedBox(
width: size, width: size,

View file

@ -31,7 +31,10 @@ class ThumbnailEntryOverlay extends StatelessWidget {
if (entry.isGeotiff) const GeotiffIcon(), if (entry.isGeotiff) const GeotiffIcon(),
if (entry.is360) const SphericalImageIcon(), if (entry.is360) const SphericalImageIcon(),
], ],
if (entry.isMultiPage) MultiPageIcon(entry: entry), if (entry.isMultiPage) ...[
if (entry.isMotionPhoto && context.select<GridThemeData, bool>((t) => t.showMotionPhoto)) const MotionPhotoIcon(),
if (!entry.isMotionPhoto) MultiPageIcon(entry: entry),
],
]; ];
if (children.isEmpty) return const SizedBox.shrink(); if (children.isEmpty) return const SizedBox.shrink();
if (children.length == 1) return children.first; if (children.length == 1) return children.first;

View file

@ -4,6 +4,7 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/utils/color_utils.dart'; import 'package:aves/utils/color_utils.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/common/identity/aves_icons.dart';
import 'package:aves/widgets/settings/common/tile_leading.dart'; import 'package:aves/widgets/settings/common/tile_leading.dart';
import 'package:aves/widgets/settings/thumbnails/selection_actions_editor.dart'; import 'package:aves/widgets/settings/thumbnails/selection_actions_editor.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,6 +21,7 @@ class ThumbnailsSection extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final currentShowThumbnailLocation = context.select<Settings, bool>((s) => s.showThumbnailLocation); final currentShowThumbnailLocation = context.select<Settings, bool>((s) => s.showThumbnailLocation);
final currentShowThumbnailMotionPhoto = context.select<Settings, bool>((s) => s.showThumbnailMotionPhoto);
final currentShowThumbnailRaw = context.select<Settings, bool>((s) => s.showThumbnailRaw); final currentShowThumbnailRaw = context.select<Settings, bool>((s) => s.showThumbnailRaw);
final currentShowThumbnailVideoDuration = context.select<Settings, bool>((s) => s.showThumbnailVideoDuration); final currentShowThumbnailVideoDuration = context.select<Settings, bool>((s) => s.showThumbnailVideoDuration);
@ -53,6 +55,26 @@ class ThumbnailsSection extends StatelessWidget {
], ],
), ),
), ),
SwitchListTile(
value: currentShowThumbnailMotionPhoto,
onChanged: (v) => settings.showThumbnailMotionPhoto = v,
title: Row(
children: [
Expanded(child: Text(context.l10n.settingsThumbnailShowMotionPhotoIcon)),
AnimatedOpacity(
opacity: opacityFor(currentShowThumbnailMotionPhoto),
duration: Durations.toggleableTransitionAnimation,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: iconSize * (1 - MotionPhotoIcon.scale) / 2),
child: Icon(
AIcons.motionPhoto,
size: iconSize * MotionPhotoIcon.scale,
),
),
),
],
),
),
SwitchListTile( SwitchListTile(
value: currentShowThumbnailRaw, value: currentShowThumbnailRaw,
onChanged: (v) => settings.showThumbnailRaw = v, onChanged: (v) => settings.showThumbnailRaw = v,