#448 #449 show description on viewer overlay; editing description clears related exif fields

This commit is contained in:
Thibault Deckers 2022-12-29 12:28:14 +01:00
parent 1ef9d75b0b
commit 6014677451
14 changed files with 182 additions and 23 deletions

View file

@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased] ## <a id="unreleased"></a>[Unreleased]
### Added
- Viewer: optionally show description on overlay
### Changed
- editing description writes XMP `dc:description`, and clears Exif `ImageDescription` / `UserComment`
## <a id="v1.7.8"></a>[v1.7.8] - 2022-12-20 ## <a id="v1.7.8"></a>[v1.7.8] - 2022-12-20
### Added ### Added

View file

@ -615,7 +615,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
if (!metadataMap.containsKey(KEY_XMP_TITLE) || !metadataMap.containsKey(KEY_XMP_SUBJECTS)) { if (!metadataMap.containsKey(KEY_XMP_TITLE) || !metadataMap.containsKey(KEY_XMP_SUBJECTS)) {
for (dir in metadata.getDirectoriesOfType(IptcDirectory::class.java)) { for (dir in metadata.getDirectoriesOfType(IptcDirectory::class.java)) {
if (!metadataMap.containsKey(KEY_XMP_TITLE)) { if (!metadataMap.containsKey(KEY_XMP_TITLE)) {
dir.getSafeString(IptcDirectory.TAG_OBJECT_NAME) { metadataMap[KEY_XMP_TITLE] = it } dir.getSafeString(IptcDirectory.TAG_OBJECT_NAME, acceptBlank = false) { metadataMap[KEY_XMP_TITLE] = it }
} }
if (!metadataMap.containsKey(KEY_XMP_SUBJECTS)) { if (!metadataMap.containsKey(KEY_XMP_SUBJECTS)) {
dir.keywords?.let { metadataMap[KEY_XMP_SUBJECTS] = it.joinToString(XMP_SUBJECTS_SEPARATOR) } dir.keywords?.let { metadataMap[KEY_XMP_SUBJECTS] = it.joinToString(XMP_SUBJECTS_SEPARATOR) }
@ -1151,6 +1151,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
// return description from these fields (by precedence): // return description from these fields (by precedence):
// - XMP / dc:description // - XMP / dc:description
// - IPTC / caption-abstract // - IPTC / caption-abstract
// - Exif / UserComment
// - Exif / ImageDescription // - Exif / ImageDescription
private fun getDescription(call: MethodCall, result: MethodChannel.Result) { private fun getDescription(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument<String>("mimeType") val mimeType = call.argument<String>("mimeType")
@ -1171,7 +1172,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
val xmpMeta = dir.xmpMeta val xmpMeta = dir.xmpMeta
try { try {
if (xmpMeta.doesPropExist(XMP.DC_DESCRIPTION_PROP_NAME)) { if (xmpMeta.doesPropExist(XMP.DC_DESCRIPTION_PROP_NAME)) {
xmpMeta.getSafeLocalizedText(XMP.DC_DESCRIPTION_PROP_NAME) { description = it } xmpMeta.getSafeLocalizedText(XMP.DC_DESCRIPTION_PROP_NAME, acceptBlank = false) { description = it }
} }
} catch (e: XMPException) { } catch (e: XMPException) {
Log.w(LOG_TAG, "failed to read XMP directory for uri=$uri", e) Log.w(LOG_TAG, "failed to read XMP directory for uri=$uri", e)
@ -1179,12 +1180,23 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
} }
if (description == null) { if (description == null) {
for (dir in metadata.getDirectoriesOfType(IptcDirectory::class.java)) { for (dir in metadata.getDirectoriesOfType(IptcDirectory::class.java)) {
dir.getSafeString(IptcDirectory.TAG_CAPTION) { description = it } dir.getSafeString(IptcDirectory.TAG_CAPTION, acceptBlank = false) { description = it }
}
}
if (description == null) {
for (dir in metadata.getDirectoriesOfType(ExifSubIFDDirectory::class.java)) {
// user comment field specifies encoding, unlike other string fields
if (dir.containsTag(ExifSubIFDDirectory.TAG_USER_COMMENT)) {
val string = dir.getDescription(ExifSubIFDDirectory.TAG_USER_COMMENT)
if (string.isNotBlank()) {
description = string
}
}
} }
} }
if (description == null) { if (description == null) {
for (dir in metadata.getDirectoriesOfType(ExifIFD0Directory::class.java)) { for (dir in metadata.getDirectoriesOfType(ExifIFD0Directory::class.java)) {
dir.getSafeString(ExifIFD0Directory.TAG_IMAGE_DESCRIPTION) { description = it } dir.getSafeString(ExifIFD0Directory.TAG_IMAGE_DESCRIPTION, acceptBlank = false) { description = it }
} }
} }
} }

View file

@ -117,8 +117,13 @@ object Helper {
// extensions // extensions
fun Directory.getSafeString(tag: Int, save: (value: String) -> Unit) { fun Directory.getSafeString(tag: Int, acceptBlank: Boolean = true, save: (value: String) -> Unit) {
if (this.containsTag(tag)) save(this.getString(tag)) if (this.containsTag(tag)) {
val string = this.getString(tag)
if (acceptBlank || string.isNotBlank()) {
save(string)
}
}
} }
fun Directory.getSafeBoolean(tag: Int, save: (value: Boolean) -> Unit) { fun Directory.getSafeBoolean(tag: Int, save: (value: Boolean) -> Unit) {

View file

@ -731,6 +731,7 @@
"settingsViewerShowInformationSubtitle": "Show title, date, location, etc.", "settingsViewerShowInformationSubtitle": "Show title, date, location, etc.",
"settingsViewerShowRatingTags": "Show rating & tags", "settingsViewerShowRatingTags": "Show rating & tags",
"settingsViewerShowShootingDetails": "Show shooting details", "settingsViewerShowShootingDetails": "Show shooting details",
"settingsViewerShowDescription": "Show description",
"settingsViewerShowOverlayThumbnails": "Show thumbnails", "settingsViewerShowOverlayThumbnails": "Show thumbnails",
"settingsViewerEnableOverlayBlurEffect": "Blur effect", "settingsViewerEnableOverlayBlurEffect": "Blur effect",

View file

@ -235,7 +235,10 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final description = fields[DescriptionField.description]; final description = fields[DescriptionField.description];
if (canEditExif && editDescription) { if (canEditExif && editDescription) {
metadata[MetadataType.exif] = {MetadataField.exifImageDescription.toPlatform!: description}; metadata[MetadataType.exif] = {
MetadataField.exifImageDescription.toPlatform!: null,
MetadataField.exifUserComment.toPlatform!: null,
};
} }
if (canEditIptc) { if (canEditIptc) {

View file

@ -37,6 +37,7 @@ enum MetadataField {
exifGpsTrackRef, exifGpsTrackRef,
exifGpsVersionId, exifGpsVersionId,
exifImageDescription, exifImageDescription,
exifUserComment,
mp4GpsCoordinates, mp4GpsCoordinates,
mp4RotationDegrees, mp4RotationDegrees,
mp4Xmp, mp4Xmp,
@ -119,6 +120,7 @@ extension ExtraMetadataField on MetadataField {
case MetadataField.exifGpsTrackRef: case MetadataField.exifGpsTrackRef:
case MetadataField.exifGpsVersionId: case MetadataField.exifGpsVersionId:
case MetadataField.exifImageDescription: case MetadataField.exifImageDescription:
case MetadataField.exifUserComment:
return MetadataType.exif; return MetadataType.exif;
case MetadataField.mp4GpsCoordinates: case MetadataField.mp4GpsCoordinates:
case MetadataField.mp4RotationDegrees: case MetadataField.mp4RotationDegrees:
@ -220,6 +222,8 @@ extension ExtraMetadataField on MetadataField {
return 'GPSVersionID'; return 'GPSVersionID';
case MetadataField.exifImageDescription: case MetadataField.exifImageDescription:
return 'ImageDescription'; return 'ImageDescription';
case MetadataField.exifUserComment:
return 'UserComment';
default: default:
return null; return null;
} }

View file

@ -79,6 +79,7 @@ class SettingsDefaults {
static const showOverlayOnOpening = true; static const showOverlayOnOpening = true;
static const showOverlayMinimap = false; static const showOverlayMinimap = false;
static const showOverlayInfo = true; static const showOverlayInfo = true;
static const showOverlayDescription = false;
static const showOverlayRatingTags = false; static const showOverlayRatingTags = false;
static const showOverlayShootingDetails = false; static const showOverlayShootingDetails = false;
static const showOverlayThumbnailPreview = false; static const showOverlayThumbnailPreview = false;

View file

@ -115,6 +115,7 @@ class Settings extends ChangeNotifier {
static const showOverlayOnOpeningKey = 'show_overlay_on_opening'; static const showOverlayOnOpeningKey = 'show_overlay_on_opening';
static const showOverlayMinimapKey = 'show_overlay_minimap'; static const showOverlayMinimapKey = 'show_overlay_minimap';
static const showOverlayInfoKey = 'show_overlay_info'; static const showOverlayInfoKey = 'show_overlay_info';
static const showOverlayDescriptionKey = 'show_overlay_description';
static const showOverlayRatingTagsKey = 'show_overlay_rating_tags'; static const showOverlayRatingTagsKey = 'show_overlay_rating_tags';
static const showOverlayShootingDetailsKey = 'show_overlay_shooting_details'; static const showOverlayShootingDetailsKey = 'show_overlay_shooting_details';
static const showOverlayThumbnailPreviewKey = 'show_overlay_thumbnail_preview'; static const showOverlayThumbnailPreviewKey = 'show_overlay_thumbnail_preview';
@ -563,6 +564,10 @@ class Settings extends ChangeNotifier {
set showOverlayInfo(bool newValue) => setAndNotify(showOverlayInfoKey, newValue); set showOverlayInfo(bool newValue) => setAndNotify(showOverlayInfoKey, newValue);
bool get showOverlayDescription => getBool(showOverlayDescriptionKey) ?? SettingsDefaults.showOverlayDescription;
set showOverlayDescription(bool newValue) => setAndNotify(showOverlayDescriptionKey, newValue);
bool get showOverlayRatingTags => getBool(showOverlayRatingTagsKey) ?? SettingsDefaults.showOverlayRatingTags; bool get showOverlayRatingTags => getBool(showOverlayRatingTagsKey) ?? SettingsDefaults.showOverlayRatingTags;
set showOverlayRatingTags(bool newValue) => setAndNotify(showOverlayRatingTagsKey, newValue); set showOverlayRatingTags(bool newValue) => setAndNotify(showOverlayRatingTagsKey, newValue);
@ -1002,6 +1007,7 @@ class Settings extends ChangeNotifier {
case showOverlayOnOpeningKey: case showOverlayOnOpeningKey:
case showOverlayMinimapKey: case showOverlayMinimapKey:
case showOverlayInfoKey: case showOverlayInfoKey:
case showOverlayDescriptionKey:
case showOverlayRatingTagsKey: case showOverlayRatingTagsKey:
case showOverlayShootingDetailsKey: case showOverlayShootingDetailsKey:
case showOverlayThumbnailPreviewKey: case showOverlayThumbnailPreviewKey:

View file

@ -56,6 +56,18 @@ class ViewerOverlayPage extends StatelessWidget {
); );
}, },
), ),
Selector<Settings, Tuple2<bool, bool>>(
selector: (context, s) => Tuple2(s.showOverlayInfo, s.showOverlayDescription),
builder: (context, s, child) {
final showInfo = s.item1;
final current = s.item2;
return SwitchListTile(
value: current,
onChanged: showInfo ? (v) => settings.showOverlayDescription = v : null,
title: Text(context.l10n.settingsViewerShowDescription),
);
},
),
if (!device.isTelevision) if (!device.isTelevision)
SettingsSwitchListTile( SettingsSwitchListTile(
selector: (context, s) => s.showOverlayMinimap, selector: (context, s) => s.showOverlayMinimap,

View file

@ -0,0 +1,25 @@
import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/viewer/overlay/details/details.dart';
import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart';
class OverlayDescriptionRow extends StatelessWidget {
final String description;
const OverlayDescriptionRow({
super.key,
required this.description,
});
@override
Widget build(BuildContext context) {
return Row(
children: [
DecoratedIcon(AIcons.description, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)),
const SizedBox(width: ViewerDetailOverlayContent.iconPadding),
Expanded(child: Text(description, strutStyle: Constants.overflowStrutStyle)),
],
);
}
}

View file

@ -8,6 +8,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/viewer/multipage/controller.dart'; import 'package:aves/widgets/viewer/multipage/controller.dart';
import 'package:aves/widgets/viewer/overlay/details/date.dart'; import 'package:aves/widgets/viewer/overlay/details/date.dart';
import 'package:aves/widgets/viewer/overlay/details/description.dart';
import 'package:aves/widgets/viewer/overlay/details/location.dart'; import 'package:aves/widgets/viewer/overlay/details/location.dart';
import 'package:aves/widgets/viewer/overlay/details/position_title.dart'; import 'package:aves/widgets/viewer/overlay/details/position_title.dart';
import 'package:aves/widgets/viewer/overlay/details/rating_tags.dart'; import 'package:aves/widgets/viewer/overlay/details/rating_tags.dart';
@ -43,9 +44,9 @@ class _ViewerDetailOverlayState extends State<ViewerDetailOverlay> {
return index < entries.length ? entries[index] : null; return index < entries.length ? entries[index] : null;
} }
late Future<OverlayMetadata?> _detailLoader; late Future<List<dynamic>?> _detailLoader;
AvesEntry? _lastEntry; AvesEntry? _lastEntry;
OverlayMetadata? _lastDetails; List<dynamic>? _lastDetails;
@override @override
void initState() { void initState() {
@ -63,7 +64,14 @@ class _ViewerDetailOverlayState extends State<ViewerDetailOverlay> {
void _initDetailLoader() { void _initDetailLoader() {
final requestEntry = entry; final requestEntry = entry;
_detailLoader = requestEntry != null ? metadataFetchService.getOverlayMetadata(requestEntry) : SynchronousFuture(null); if (requestEntry == null) {
_detailLoader = SynchronousFuture(null);
} else {
_detailLoader = Future.wait([
settings.showOverlayShootingDetails ? metadataFetchService.getOverlayMetadata(requestEntry) : Future.value(null),
settings.showOverlayDescription ? metadataFetchService.getDescription(requestEntry) : Future.value(null),
]);
}
} }
@override @override
@ -75,7 +83,7 @@ class _ViewerDetailOverlayState extends State<ViewerDetailOverlay> {
builder: (context, constraints) { builder: (context, constraints) {
final availableWidth = constraints.maxWidth; final availableWidth = constraints.maxWidth;
return FutureBuilder<OverlayMetadata?>( return FutureBuilder<List<dynamic>?>(
future: _detailLoader, future: _detailLoader,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) { if (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) {
@ -85,10 +93,14 @@ class _ViewerDetailOverlayState extends State<ViewerDetailOverlay> {
if (_lastEntry == null) return const SizedBox(); if (_lastEntry == null) return const SizedBox();
final mainEntry = _lastEntry!; final mainEntry = _lastEntry!;
final shootingDetails = _lastDetails![0];
final description = _lastDetails![1];
final multiPageController = widget.multiPageController; final multiPageController = widget.multiPageController;
Widget _buildContent({AvesEntry? pageEntry}) => ViewerDetailOverlayContent( Widget _buildContent({AvesEntry? pageEntry}) => ViewerDetailOverlayContent(
pageEntry: pageEntry ?? mainEntry, pageEntry: pageEntry ?? mainEntry,
details: _lastDetails, shootingDetails: shootingDetails,
description: description,
position: widget.hasCollection ? '${widget.index + 1}/${entries.length}' : null, position: widget.hasCollection ? '${widget.index + 1}/${entries.length}' : null,
availableWidth: availableWidth, availableWidth: availableWidth,
multiPageController: multiPageController, multiPageController: multiPageController,
@ -110,7 +122,8 @@ class _ViewerDetailOverlayState extends State<ViewerDetailOverlay> {
class ViewerDetailOverlayContent extends StatelessWidget { class ViewerDetailOverlayContent extends StatelessWidget {
final AvesEntry pageEntry; final AvesEntry pageEntry;
final OverlayMetadata? details; final OverlayMetadata? shootingDetails;
final String? description;
final String? position; final String? position;
final double availableWidth; final double availableWidth;
final MultiPageController? multiPageController; final MultiPageController? multiPageController;
@ -126,7 +139,8 @@ class ViewerDetailOverlayContent extends StatelessWidget {
const ViewerDetailOverlayContent({ const ViewerDetailOverlayContent({
super.key, super.key,
required this.pageEntry, required this.pageEntry,
required this.details, required this.shootingDetails,
required this.description,
required this.position, required this.position,
required this.availableWidth, required this.availableWidth,
required this.multiPageController, required this.multiPageController,
@ -136,7 +150,8 @@ class ViewerDetailOverlayContent extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final infoMaxWidth = availableWidth - padding.horizontal; final infoMaxWidth = availableWidth - padding.horizontal;
final showRatingTags = settings.showOverlayRatingTags; final showRatingTags = settings.showOverlayRatingTags;
final showShooting = settings.showOverlayShootingDetails; final showShootingDetails = settings.showOverlayShootingDetails;
final showDescription = settings.showOverlayDescription;
return AnimatedBuilder( return AnimatedBuilder(
animation: pageEntry.metadataChangeNotifier, animation: pageEntry.metadataChangeNotifier,
@ -156,8 +171,8 @@ class ViewerDetailOverlayContent extends StatelessWidget {
builder: (context, orientation, child) { builder: (context, orientation, child) {
final twoColumns = orientation == Orientation.landscape && infoMaxWidth / 2 > _subRowMinWidth; final twoColumns = orientation == Orientation.landscape && infoMaxWidth / 2 > _subRowMinWidth;
final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth; final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth;
final collapsedShooting = twoColumns && showShooting; final collapsedShooting = twoColumns && showShootingDetails;
final collapsedLocation = twoColumns && !showShooting; final collapsedLocation = twoColumns && !showShootingDetails;
final rows = <Widget>[]; final rows = <Widget>[];
if (positionTitle.isNotEmpty) { if (positionTitle.isNotEmpty) {
@ -176,7 +191,7 @@ class ViewerDetailOverlayContent extends StatelessWidget {
); );
} else { } else {
rows.add(_buildDateSubRow(subRowWidth)); rows.add(_buildDateSubRow(subRowWidth));
if (showShooting) { if (showShootingDetails) {
rows.add(_buildShootingFullRow(context, subRowWidth)); rows.add(_buildShootingFullRow(context, subRowWidth));
} }
} }
@ -186,6 +201,9 @@ class ViewerDetailOverlayContent extends StatelessWidget {
if (showRatingTags) { if (showRatingTags) {
rows.add(_buildRatingTagsFullRow(context)); rows.add(_buildRatingTagsFullRow(context));
} }
if (showDescription) {
rows.add(_buildDescriptionFullRow(context));
}
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -214,20 +232,26 @@ class ViewerDetailOverlayContent extends StatelessWidget {
builder: (context) => OverlayRatingTagsRow(entry: pageEntry), builder: (context) => OverlayRatingTagsRow(entry: pageEntry),
); );
Widget _buildDescriptionFullRow(BuildContext context) => _buildFullRowSwitcher(
context: context,
visible: description != null,
builder: (context) => OverlayDescriptionRow(description: description!),
);
Widget _buildShootingFullRow(BuildContext context, double subRowWidth) => _buildFullRowSwitcher( Widget _buildShootingFullRow(BuildContext context, double subRowWidth) => _buildFullRowSwitcher(
context: context, context: context,
visible: details != null && details!.isNotEmpty, visible: shootingDetails != null && shootingDetails!.isNotEmpty,
builder: (context) => SizedBox( builder: (context) => SizedBox(
width: subRowWidth, width: subRowWidth,
child: OverlayShootingRow(details: details!), child: OverlayShootingRow(details: shootingDetails!),
), ),
); );
Widget _buildShootingSubRow(BuildContext context, double subRowWidth) => _buildSubRowSwitcher( Widget _buildShootingSubRow(BuildContext context, double subRowWidth) => _buildSubRowSwitcher(
context: context, context: context,
subRowWidth: subRowWidth, subRowWidth: subRowWidth,
visible: details != null && details!.isNotEmpty, visible: shootingDetails != null && shootingDetails!.isNotEmpty,
builder: (context) => OverlayShootingRow(details: details!), builder: (context) => OverlayShootingRow(details: shootingDetails!),
); );
Widget _buildLocationFullRow(BuildContext context) => _buildFullRowSwitcher( Widget _buildLocationFullRow(BuildContext context) => _buildFullRowSwitcher(

View file

@ -10,7 +10,10 @@ import 'package:intl/intl.dart';
class OverlayShootingRow extends StatelessWidget { class OverlayShootingRow extends StatelessWidget {
final OverlayMetadata details; final OverlayMetadata details;
const OverlayShootingRow({super.key, required this.details}); const OverlayShootingRow({
super.key,
required this.details,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -47,6 +47,7 @@ Future<void> configureAndLaunch() async {
..showOverlayOnOpening = true ..showOverlayOnOpening = true
..showOverlayMinimap = false ..showOverlayMinimap = false
..showOverlayInfo = true ..showOverlayInfo = true
..showOverlayDescription = false
..showOverlayRatingTags = false ..showOverlayRatingTags = false
..showOverlayShootingDetails = false ..showOverlayShootingDetails = false
..showOverlayThumbnailPreview = false ..showOverlayThumbnailPreview = false

View file

@ -452,6 +452,7 @@
"settingsViewerShowInformationSubtitle", "settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails", "settingsViewerShowShootingDetails",
"settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails", "settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect", "settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -592,9 +593,18 @@
"de": [ "de": [
"columnCount", "columnCount",
"settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives" "settingsAccessibilityShowPinchGestureAlternatives"
], ],
"el": [
"settingsViewerShowDescription"
],
"es": [
"settingsViewerShowDescription"
],
"fa": [ "fa": [
"columnCount", "columnCount",
"clearTooltip", "clearTooltip",
@ -914,6 +924,7 @@
"settingsViewerShowInformationSubtitle", "settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails", "settingsViewerShowShootingDetails",
"settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails", "settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect", "settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -1059,6 +1070,10 @@
"filePickerUseThisFolder" "filePickerUseThisFolder"
], ],
"fr": [
"settingsViewerShowDescription"
],
"gl": [ "gl": [
"columnCount", "columnCount",
"entryActionShareImageOnly", "entryActionShareImageOnly",
@ -1379,6 +1394,7 @@
"settingsViewerShowInformationSubtitle", "settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails", "settingsViewerShowShootingDetails",
"settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails", "settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect", "settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -1526,6 +1542,14 @@
"filePickerUseThisFolder" "filePickerUseThisFolder"
], ],
"id": [
"settingsViewerShowDescription"
],
"it": [
"settingsViewerShowDescription"
],
"ja": [ "ja": [
"columnCount", "columnCount",
"chipActionFilterIn", "chipActionFilterIn",
@ -1535,13 +1559,19 @@
"keepScreenOnVideoPlayback", "keepScreenOnVideoPlayback",
"subtitlePositionTop", "subtitlePositionTop",
"subtitlePositionBottom", "subtitlePositionBottom",
"settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives", "settingsAccessibilityShowPinchGestureAlternatives",
"settingsWidgetDisplayedItem" "settingsWidgetDisplayedItem"
], ],
"ko": [
"settingsViewerShowDescription"
],
"lt": [ "lt": [
"columnCount", "columnCount",
"keepScreenOnVideoPlayback", "keepScreenOnVideoPlayback",
"settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives" "settingsAccessibilityShowPinchGestureAlternatives"
], ],
@ -1551,6 +1581,7 @@
"entryActionShareVideoOnly", "entryActionShareVideoOnly",
"entryInfoActionRemoveLocation", "entryInfoActionRemoveLocation",
"keepScreenOnVideoPlayback", "keepScreenOnVideoPlayback",
"settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives" "settingsAccessibilityShowPinchGestureAlternatives"
], ],
@ -1569,6 +1600,7 @@
"widgetDisplayedItemRandom", "widgetDisplayedItemRandom",
"widgetDisplayedItemMostRecent", "widgetDisplayedItemMostRecent",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowDescription",
"settingsSubtitleThemeTextPositionTile", "settingsSubtitleThemeTextPositionTile",
"settingsSubtitleThemeTextPositionDialogTitle", "settingsSubtitleThemeTextPositionDialogTitle",
"settingsAccessibilityShowPinchGestureAlternatives", "settingsAccessibilityShowPinchGestureAlternatives",
@ -1878,6 +1910,7 @@
"settingsViewerShowInformationSubtitle", "settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails", "settingsViewerShowShootingDetails",
"settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails", "settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect", "settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -2385,6 +2418,7 @@
"settingsViewerShowInformationSubtitle", "settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails", "settingsViewerShowShootingDetails",
"settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails", "settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect", "settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -2547,12 +2581,21 @@
"widgetDisplayedItemRandom", "widgetDisplayedItemRandom",
"widgetDisplayedItemMostRecent", "widgetDisplayedItemMostRecent",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowDescription",
"settingsSubtitleThemeTextPositionTile", "settingsSubtitleThemeTextPositionTile",
"settingsSubtitleThemeTextPositionDialogTitle", "settingsSubtitleThemeTextPositionDialogTitle",
"settingsAccessibilityShowPinchGestureAlternatives", "settingsAccessibilityShowPinchGestureAlternatives",
"settingsWidgetDisplayedItem" "settingsWidgetDisplayedItem"
], ],
"ro": [
"settingsViewerShowDescription"
],
"ru": [
"settingsViewerShowDescription"
],
"th": [ "th": [
"itemCount", "itemCount",
"columnCount", "columnCount",
@ -2748,6 +2791,7 @@
"settingsViewerShowInformationSubtitle", "settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags", "settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails", "settingsViewerShowShootingDetails",
"settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails", "settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect", "settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile", "settingsViewerSlideshowTile",
@ -2895,12 +2939,22 @@
"filePickerUseThisFolder" "filePickerUseThisFolder"
], ],
"tr": [
"settingsViewerShowDescription"
],
"uk": [
"settingsViewerShowDescription"
],
"zh": [ "zh": [
"settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives" "settingsAccessibilityShowPinchGestureAlternatives"
], ],
"zh_Hant": [ "zh_Hant": [
"columnCount", "columnCount",
"settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives" "settingsAccessibilityShowPinchGestureAlternatives"
] ]
} }