#68 settings: show/hide motion photo icon on thumbnails
This commit is contained in:
parent
466d150e49
commit
db863d68e3
9 changed files with 69 additions and 31 deletions
|
@ -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",
|
||||||
|
|
|
@ -314,6 +314,7 @@
|
||||||
|
|
||||||
"settingsSectionThumbnails": "섬네일",
|
"settingsSectionThumbnails": "섬네일",
|
||||||
"settingsThumbnailShowLocationIcon": "위치 아이콘 표시",
|
"settingsThumbnailShowLocationIcon": "위치 아이콘 표시",
|
||||||
|
"settingsThumbnailShowMotionPhotoIcon": "모션 포토 아이콘 표시",
|
||||||
"settingsThumbnailShowRawIcon": "Raw 아이콘 표시",
|
"settingsThumbnailShowRawIcon": "Raw 아이콘 표시",
|
||||||
"settingsThumbnailShowVideoDuration": "동영상 길이 표시",
|
"settingsThumbnailShowVideoDuration": "동영상 길이 표시",
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue