diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91bdb7498..245dfd2bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
+### Added
+
+- Viewer: optionally show description on overlay
+
+### Changed
+
+- editing description writes XMP `dc:description`, and clears Exif `ImageDescription` / `UserComment`
+
## [v1.7.8] - 2022-12-20
### Added
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt
index c23c7d85a..619e090a5 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt
@@ -615,7 +615,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
if (!metadataMap.containsKey(KEY_XMP_TITLE) || !metadataMap.containsKey(KEY_XMP_SUBJECTS)) {
for (dir in metadata.getDirectoriesOfType(IptcDirectory::class.java)) {
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)) {
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):
// - XMP / dc:description
// - IPTC / caption-abstract
+ // - Exif / UserComment
// - Exif / ImageDescription
private fun getDescription(call: MethodCall, result: MethodChannel.Result) {
val mimeType = call.argument("mimeType")
@@ -1171,7 +1172,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
val xmpMeta = dir.xmpMeta
try {
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) {
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) {
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) {
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 }
}
}
}
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt
index 8f6672ce9..ed247f4cf 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt
@@ -117,8 +117,13 @@ object Helper {
// extensions
- fun Directory.getSafeString(tag: Int, save: (value: String) -> Unit) {
- if (this.containsTag(tag)) save(this.getString(tag))
+ fun Directory.getSafeString(tag: Int, acceptBlank: Boolean = true, save: (value: String) -> Unit) {
+ if (this.containsTag(tag)) {
+ val string = this.getString(tag)
+ if (acceptBlank || string.isNotBlank()) {
+ save(string)
+ }
+ }
}
fun Directory.getSafeBoolean(tag: Int, save: (value: Boolean) -> Unit) {
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index 8f1c08b35..6c9d93587 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -731,6 +731,7 @@
"settingsViewerShowInformationSubtitle": "Show title, date, location, etc.",
"settingsViewerShowRatingTags": "Show rating & tags",
"settingsViewerShowShootingDetails": "Show shooting details",
+ "settingsViewerShowDescription": "Show description",
"settingsViewerShowOverlayThumbnails": "Show thumbnails",
"settingsViewerEnableOverlayBlurEffect": "Blur effect",
diff --git a/lib/model/entry_metadata_edition.dart b/lib/model/entry_metadata_edition.dart
index 21ba5d001..7aa91fae6 100644
--- a/lib/model/entry_metadata_edition.dart
+++ b/lib/model/entry_metadata_edition.dart
@@ -235,7 +235,10 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
final description = fields[DescriptionField.description];
if (canEditExif && editDescription) {
- metadata[MetadataType.exif] = {MetadataField.exifImageDescription.toPlatform!: description};
+ metadata[MetadataType.exif] = {
+ MetadataField.exifImageDescription.toPlatform!: null,
+ MetadataField.exifUserComment.toPlatform!: null,
+ };
}
if (canEditIptc) {
diff --git a/lib/model/metadata/fields.dart b/lib/model/metadata/fields.dart
index 552909243..17a344aa6 100644
--- a/lib/model/metadata/fields.dart
+++ b/lib/model/metadata/fields.dart
@@ -37,6 +37,7 @@ enum MetadataField {
exifGpsTrackRef,
exifGpsVersionId,
exifImageDescription,
+ exifUserComment,
mp4GpsCoordinates,
mp4RotationDegrees,
mp4Xmp,
@@ -119,6 +120,7 @@ extension ExtraMetadataField on MetadataField {
case MetadataField.exifGpsTrackRef:
case MetadataField.exifGpsVersionId:
case MetadataField.exifImageDescription:
+ case MetadataField.exifUserComment:
return MetadataType.exif;
case MetadataField.mp4GpsCoordinates:
case MetadataField.mp4RotationDegrees:
@@ -220,6 +222,8 @@ extension ExtraMetadataField on MetadataField {
return 'GPSVersionID';
case MetadataField.exifImageDescription:
return 'ImageDescription';
+ case MetadataField.exifUserComment:
+ return 'UserComment';
default:
return null;
}
diff --git a/lib/model/settings/defaults.dart b/lib/model/settings/defaults.dart
index db0c59c8d..9317cd1f0 100644
--- a/lib/model/settings/defaults.dart
+++ b/lib/model/settings/defaults.dart
@@ -79,6 +79,7 @@ class SettingsDefaults {
static const showOverlayOnOpening = true;
static const showOverlayMinimap = false;
static const showOverlayInfo = true;
+ static const showOverlayDescription = false;
static const showOverlayRatingTags = false;
static const showOverlayShootingDetails = false;
static const showOverlayThumbnailPreview = false;
diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart
index aa747b127..124408268 100644
--- a/lib/model/settings/settings.dart
+++ b/lib/model/settings/settings.dart
@@ -115,6 +115,7 @@ class Settings extends ChangeNotifier {
static const showOverlayOnOpeningKey = 'show_overlay_on_opening';
static const showOverlayMinimapKey = 'show_overlay_minimap';
static const showOverlayInfoKey = 'show_overlay_info';
+ static const showOverlayDescriptionKey = 'show_overlay_description';
static const showOverlayRatingTagsKey = 'show_overlay_rating_tags';
static const showOverlayShootingDetailsKey = 'show_overlay_shooting_details';
static const showOverlayThumbnailPreviewKey = 'show_overlay_thumbnail_preview';
@@ -563,6 +564,10 @@ class Settings extends ChangeNotifier {
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;
set showOverlayRatingTags(bool newValue) => setAndNotify(showOverlayRatingTagsKey, newValue);
@@ -1002,6 +1007,7 @@ class Settings extends ChangeNotifier {
case showOverlayOnOpeningKey:
case showOverlayMinimapKey:
case showOverlayInfoKey:
+ case showOverlayDescriptionKey:
case showOverlayRatingTagsKey:
case showOverlayShootingDetailsKey:
case showOverlayThumbnailPreviewKey:
diff --git a/lib/widgets/settings/viewer/overlay.dart b/lib/widgets/settings/viewer/overlay.dart
index dab35532b..cf76ca7f1 100644
--- a/lib/widgets/settings/viewer/overlay.dart
+++ b/lib/widgets/settings/viewer/overlay.dart
@@ -56,6 +56,18 @@ class ViewerOverlayPage extends StatelessWidget {
);
},
),
+ Selector>(
+ 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)
SettingsSwitchListTile(
selector: (context, s) => s.showOverlayMinimap,
diff --git a/lib/widgets/viewer/overlay/details/description.dart b/lib/widgets/viewer/overlay/details/description.dart
new file mode 100644
index 000000000..02a476fdf
--- /dev/null
+++ b/lib/widgets/viewer/overlay/details/description.dart
@@ -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)),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/viewer/overlay/details/details.dart b/lib/widgets/viewer/overlay/details/details.dart
index 38ff26049..fe0414169 100644
--- a/lib/widgets/viewer/overlay/details/details.dart
+++ b/lib/widgets/viewer/overlay/details/details.dart
@@ -8,6 +8,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.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/description.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/rating_tags.dart';
@@ -43,9 +44,9 @@ class _ViewerDetailOverlayState extends State {
return index < entries.length ? entries[index] : null;
}
- late Future _detailLoader;
+ late Future?> _detailLoader;
AvesEntry? _lastEntry;
- OverlayMetadata? _lastDetails;
+ List? _lastDetails;
@override
void initState() {
@@ -63,7 +64,14 @@ class _ViewerDetailOverlayState extends State {
void _initDetailLoader() {
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
@@ -75,7 +83,7 @@ class _ViewerDetailOverlayState extends State {
builder: (context, constraints) {
final availableWidth = constraints.maxWidth;
- return FutureBuilder(
+ return FutureBuilder?>(
future: _detailLoader,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) {
@@ -85,10 +93,14 @@ class _ViewerDetailOverlayState extends State {
if (_lastEntry == null) return const SizedBox();
final mainEntry = _lastEntry!;
+ final shootingDetails = _lastDetails![0];
+ final description = _lastDetails![1];
+
final multiPageController = widget.multiPageController;
Widget _buildContent({AvesEntry? pageEntry}) => ViewerDetailOverlayContent(
pageEntry: pageEntry ?? mainEntry,
- details: _lastDetails,
+ shootingDetails: shootingDetails,
+ description: description,
position: widget.hasCollection ? '${widget.index + 1}/${entries.length}' : null,
availableWidth: availableWidth,
multiPageController: multiPageController,
@@ -110,7 +122,8 @@ class _ViewerDetailOverlayState extends State {
class ViewerDetailOverlayContent extends StatelessWidget {
final AvesEntry pageEntry;
- final OverlayMetadata? details;
+ final OverlayMetadata? shootingDetails;
+ final String? description;
final String? position;
final double availableWidth;
final MultiPageController? multiPageController;
@@ -126,7 +139,8 @@ class ViewerDetailOverlayContent extends StatelessWidget {
const ViewerDetailOverlayContent({
super.key,
required this.pageEntry,
- required this.details,
+ required this.shootingDetails,
+ required this.description,
required this.position,
required this.availableWidth,
required this.multiPageController,
@@ -136,7 +150,8 @@ class ViewerDetailOverlayContent extends StatelessWidget {
Widget build(BuildContext context) {
final infoMaxWidth = availableWidth - padding.horizontal;
final showRatingTags = settings.showOverlayRatingTags;
- final showShooting = settings.showOverlayShootingDetails;
+ final showShootingDetails = settings.showOverlayShootingDetails;
+ final showDescription = settings.showOverlayDescription;
return AnimatedBuilder(
animation: pageEntry.metadataChangeNotifier,
@@ -156,8 +171,8 @@ class ViewerDetailOverlayContent extends StatelessWidget {
builder: (context, orientation, child) {
final twoColumns = orientation == Orientation.landscape && infoMaxWidth / 2 > _subRowMinWidth;
final subRowWidth = twoColumns ? min(_subRowMinWidth, infoMaxWidth / 2) : infoMaxWidth;
- final collapsedShooting = twoColumns && showShooting;
- final collapsedLocation = twoColumns && !showShooting;
+ final collapsedShooting = twoColumns && showShootingDetails;
+ final collapsedLocation = twoColumns && !showShootingDetails;
final rows = [];
if (positionTitle.isNotEmpty) {
@@ -176,7 +191,7 @@ class ViewerDetailOverlayContent extends StatelessWidget {
);
} else {
rows.add(_buildDateSubRow(subRowWidth));
- if (showShooting) {
+ if (showShootingDetails) {
rows.add(_buildShootingFullRow(context, subRowWidth));
}
}
@@ -186,6 +201,9 @@ class ViewerDetailOverlayContent extends StatelessWidget {
if (showRatingTags) {
rows.add(_buildRatingTagsFullRow(context));
}
+ if (showDescription) {
+ rows.add(_buildDescriptionFullRow(context));
+ }
return Column(
mainAxisSize: MainAxisSize.min,
@@ -214,20 +232,26 @@ class ViewerDetailOverlayContent extends StatelessWidget {
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(
context: context,
- visible: details != null && details!.isNotEmpty,
+ visible: shootingDetails != null && shootingDetails!.isNotEmpty,
builder: (context) => SizedBox(
width: subRowWidth,
- child: OverlayShootingRow(details: details!),
+ child: OverlayShootingRow(details: shootingDetails!),
),
);
Widget _buildShootingSubRow(BuildContext context, double subRowWidth) => _buildSubRowSwitcher(
context: context,
subRowWidth: subRowWidth,
- visible: details != null && details!.isNotEmpty,
- builder: (context) => OverlayShootingRow(details: details!),
+ visible: shootingDetails != null && shootingDetails!.isNotEmpty,
+ builder: (context) => OverlayShootingRow(details: shootingDetails!),
);
Widget _buildLocationFullRow(BuildContext context) => _buildFullRowSwitcher(
diff --git a/lib/widgets/viewer/overlay/details/shooting.dart b/lib/widgets/viewer/overlay/details/shooting.dart
index e28dfb7c8..0d8ea39b9 100644
--- a/lib/widgets/viewer/overlay/details/shooting.dart
+++ b/lib/widgets/viewer/overlay/details/shooting.dart
@@ -10,7 +10,10 @@ import 'package:intl/intl.dart';
class OverlayShootingRow extends StatelessWidget {
final OverlayMetadata details;
- const OverlayShootingRow({super.key, required this.details});
+ const OverlayShootingRow({
+ super.key,
+ required this.details,
+ });
@override
Widget build(BuildContext context) {
diff --git a/test_driver/driver_screenshots.dart b/test_driver/driver_screenshots.dart
index bad37cb77..672e2bf73 100644
--- a/test_driver/driver_screenshots.dart
+++ b/test_driver/driver_screenshots.dart
@@ -47,6 +47,7 @@ Future configureAndLaunch() async {
..showOverlayOnOpening = true
..showOverlayMinimap = false
..showOverlayInfo = true
+ ..showOverlayDescription = false
..showOverlayRatingTags = false
..showOverlayShootingDetails = false
..showOverlayThumbnailPreview = false
diff --git a/untranslated.json b/untranslated.json
index 917f19c09..5e9326135 100644
--- a/untranslated.json
+++ b/untranslated.json
@@ -452,6 +452,7 @@
"settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails",
+ "settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile",
@@ -592,9 +593,18 @@
"de": [
"columnCount",
+ "settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives"
],
+ "el": [
+ "settingsViewerShowDescription"
+ ],
+
+ "es": [
+ "settingsViewerShowDescription"
+ ],
+
"fa": [
"columnCount",
"clearTooltip",
@@ -914,6 +924,7 @@
"settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails",
+ "settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile",
@@ -1059,6 +1070,10 @@
"filePickerUseThisFolder"
],
+ "fr": [
+ "settingsViewerShowDescription"
+ ],
+
"gl": [
"columnCount",
"entryActionShareImageOnly",
@@ -1379,6 +1394,7 @@
"settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails",
+ "settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile",
@@ -1526,6 +1542,14 @@
"filePickerUseThisFolder"
],
+ "id": [
+ "settingsViewerShowDescription"
+ ],
+
+ "it": [
+ "settingsViewerShowDescription"
+ ],
+
"ja": [
"columnCount",
"chipActionFilterIn",
@@ -1535,13 +1559,19 @@
"keepScreenOnVideoPlayback",
"subtitlePositionTop",
"subtitlePositionBottom",
+ "settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives",
"settingsWidgetDisplayedItem"
],
+ "ko": [
+ "settingsViewerShowDescription"
+ ],
+
"lt": [
"columnCount",
"keepScreenOnVideoPlayback",
+ "settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives"
],
@@ -1551,6 +1581,7 @@
"entryActionShareVideoOnly",
"entryInfoActionRemoveLocation",
"keepScreenOnVideoPlayback",
+ "settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives"
],
@@ -1569,6 +1600,7 @@
"widgetDisplayedItemRandom",
"widgetDisplayedItemMostRecent",
"settingsViewerShowRatingTags",
+ "settingsViewerShowDescription",
"settingsSubtitleThemeTextPositionTile",
"settingsSubtitleThemeTextPositionDialogTitle",
"settingsAccessibilityShowPinchGestureAlternatives",
@@ -1878,6 +1910,7 @@
"settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails",
+ "settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile",
@@ -2385,6 +2418,7 @@
"settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails",
+ "settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile",
@@ -2547,12 +2581,21 @@
"widgetDisplayedItemRandom",
"widgetDisplayedItemMostRecent",
"settingsViewerShowRatingTags",
+ "settingsViewerShowDescription",
"settingsSubtitleThemeTextPositionTile",
"settingsSubtitleThemeTextPositionDialogTitle",
"settingsAccessibilityShowPinchGestureAlternatives",
"settingsWidgetDisplayedItem"
],
+ "ro": [
+ "settingsViewerShowDescription"
+ ],
+
+ "ru": [
+ "settingsViewerShowDescription"
+ ],
+
"th": [
"itemCount",
"columnCount",
@@ -2748,6 +2791,7 @@
"settingsViewerShowInformationSubtitle",
"settingsViewerShowRatingTags",
"settingsViewerShowShootingDetails",
+ "settingsViewerShowDescription",
"settingsViewerShowOverlayThumbnails",
"settingsViewerEnableOverlayBlurEffect",
"settingsViewerSlideshowTile",
@@ -2895,12 +2939,22 @@
"filePickerUseThisFolder"
],
+ "tr": [
+ "settingsViewerShowDescription"
+ ],
+
+ "uk": [
+ "settingsViewerShowDescription"
+ ],
+
"zh": [
+ "settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives"
],
"zh_Hant": [
"columnCount",
+ "settingsViewerShowDescription",
"settingsAccessibilityShowPinchGestureAlternatives"
]
}