#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": {},
"settingsThumbnailShowLocationIcon": "Show location icon",
"@settingsThumbnailShowLocationIcon": {},
"settingsThumbnailShowMotionPhotoIcon": "Show motion photo icon",
"@settingsThumbnailShowMotionPhotoIcon": {},
"settingsThumbnailShowRawIcon": "Show raw icon",
"@settingsThumbnailShowRawIcon": {},
"settingsThumbnailShowVideoDuration": "Show video duration",

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -31,7 +31,10 @@ class ThumbnailEntryOverlay extends StatelessWidget {
if (entry.isGeotiff) const GeotiffIcon(),
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.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/widgets/common/extensions/build_context.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/thumbnails/selection_actions_editor.dart';
import 'package:flutter/material.dart';
@ -20,6 +21,7 @@ class ThumbnailsSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
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 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(
value: currentShowThumbnailRaw,
onChanged: (v) => settings.showThumbnailRaw = v,