handle TransactionTooLargeException when sharing
This commit is contained in:
parent
c276ac904b
commit
d8a1d21f6c
36 changed files with 272 additions and 307 deletions
|
@ -10,6 +10,7 @@ import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.os.TransactionTooLargeException
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
|
@ -280,7 +281,7 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
|
||||||
val title = call.argument<String>("title")
|
val title = call.argument<String>("title")
|
||||||
val urisByMimeType = call.argument<Map<String, List<String>>>("urisByMimeType")
|
val urisByMimeType = call.argument<Map<String, List<String>>>("urisByMimeType")
|
||||||
if (urisByMimeType == null) {
|
if (urisByMimeType == null) {
|
||||||
result.error("setAs-args", "missing arguments", null)
|
result.error("share-args", "missing arguments", null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,15 +289,14 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
|
||||||
val mimeTypes = urisByMimeType.keys.toTypedArray()
|
val mimeTypes = urisByMimeType.keys.toTypedArray()
|
||||||
|
|
||||||
// simplify share intent for a single item, as some apps can handle one item but not more
|
// simplify share intent for a single item, as some apps can handle one item but not more
|
||||||
val started = if (uriList.size == 1) {
|
val intent = if (uriList.size == 1) {
|
||||||
val uri = uriList.first()
|
val uri = uriList.first()
|
||||||
val mimeType = mimeTypes.first()
|
val mimeType = mimeTypes.first()
|
||||||
|
|
||||||
val intent = Intent(Intent.ACTION_SEND)
|
Intent(Intent.ACTION_SEND)
|
||||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
.setType(mimeType)
|
.setType(mimeType)
|
||||||
.putExtra(Intent.EXTRA_STREAM, getShareableUri(context, uri))
|
.putExtra(Intent.EXTRA_STREAM, getShareableUri(context, uri))
|
||||||
safeStartActivityChooser(title, intent)
|
|
||||||
} else {
|
} else {
|
||||||
var mimeType = "*/*"
|
var mimeType = "*/*"
|
||||||
if (mimeTypes.size == 1) {
|
if (mimeTypes.size == 1) {
|
||||||
|
@ -311,14 +311,21 @@ class AppAdapterHandler(private val context: Context) : MethodCallHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val intent = Intent(Intent.ACTION_SEND_MULTIPLE)
|
Intent(Intent.ACTION_SEND_MULTIPLE)
|
||||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList)
|
.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList)
|
||||||
.setType(mimeType)
|
.setType(mimeType)
|
||||||
safeStartActivityChooser(title, intent)
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
val started = safeStartActivityChooser(title, intent)
|
||||||
result.success(started)
|
result.success(started)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (e is TransactionTooLargeException || e.cause is TransactionTooLargeException) {
|
||||||
|
result.error("share-large", "transaction too large with ${uriList.size} URIs", e)
|
||||||
|
} else {
|
||||||
|
result.error("share-exception", "failed to share ${uriList.size} URIs", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun safeStartActivity(intent: Intent): Boolean {
|
private fun safeStartActivity(intent: Intent): Boolean {
|
||||||
|
|
|
@ -438,6 +438,8 @@
|
||||||
"genericFailureFeedback": "Failed",
|
"genericFailureFeedback": "Failed",
|
||||||
"genericDangerWarningDialogMessage": "Are you sure?",
|
"genericDangerWarningDialogMessage": "Are you sure?",
|
||||||
|
|
||||||
|
"tooManyItemsErrorDialogMessage": "Try again with fewer items.",
|
||||||
|
|
||||||
"menuActionConfigureView": "View",
|
"menuActionConfigureView": "View",
|
||||||
"menuActionSelect": "Select",
|
"menuActionSelect": "Select",
|
||||||
"menuActionSelectAll": "Select all",
|
"menuActionSelectAll": "Select all",
|
||||||
|
|
|
@ -148,32 +148,34 @@ class PlatformAndroidAppService implements AndroidAppService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> shareEntries(Iterable<AvesEntry> entries) async {
|
Future<bool> shareEntries(Iterable<AvesEntry> entries) {
|
||||||
|
return _share(groupBy<AvesEntry, String>(
|
||||||
|
entries,
|
||||||
// loosen MIME type to a generic one, so we can share with badly defined apps
|
// loosen MIME type to a generic one, so we can share with badly defined apps
|
||||||
// e.g. Google Lens declares receiving "image/jpeg" only, but it can actually handle more formats
|
// e.g. Google Lens declares receiving "image/jpeg" only, but it can actually handle more formats
|
||||||
final urisByMimeType = groupBy<AvesEntry, String>(entries, (e) => e.mimeTypeAnySubtype).map((k, v) => MapEntry(k, v.map((e) => e.uri).toList()));
|
(e) => e.mimeTypeAnySubtype,
|
||||||
|
).map((k, v) => MapEntry(k, v.map((e) => e.uri).toList())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> shareSingle(String uri, String mimeType) {
|
||||||
|
return _share({
|
||||||
|
mimeType: [uri]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _share(Map<String, List<String>> urisByMimeType) async {
|
||||||
try {
|
try {
|
||||||
final result = await _platform.invokeMethod('share', <String, dynamic>{
|
final result = await _platform.invokeMethod('share', <String, dynamic>{
|
||||||
'urisByMimeType': urisByMimeType,
|
'urisByMimeType': urisByMimeType,
|
||||||
});
|
});
|
||||||
if (result != null) return result as bool;
|
if (result != null) return result as bool;
|
||||||
} on PlatformException catch (e, stack) {
|
} on PlatformException catch (e, stack) {
|
||||||
|
if (e.code == 'share-large') {
|
||||||
|
throw TooManyItemsException();
|
||||||
|
} else {
|
||||||
await reportService.recordError(e, stack);
|
await reportService.recordError(e, stack);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> shareSingle(String uri, String mimeType) async {
|
|
||||||
try {
|
|
||||||
final result = await _platform.invokeMethod('share', <String, dynamic>{
|
|
||||||
'urisByMimeType': {
|
|
||||||
mimeType: [uri]
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (result != null) return result as bool;
|
|
||||||
} on PlatformException catch (e, stack) {
|
|
||||||
await reportService.recordError(e, stack);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -207,3 +209,5 @@ class PlatformAndroidAppService implements AndroidAppService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TooManyItemsException implements Exception {}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/analysis_controller.dart';
|
import 'package:aves/model/source/analysis_controller.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
|
import 'package:aves/services/android_app_service.dart';
|
||||||
import 'package:aves/services/common/image_op_events.dart';
|
import 'package:aves/services/common/image_op_events.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
|
@ -252,11 +253,21 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
return groupedEntries.expand((entry) => entry.burstEntries ?? {entry}).toSet();
|
return groupedEntries.expand((entry) => entry.burstEntries ?? {entry}).toSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _share(BuildContext context) {
|
Future<void> _share(BuildContext context) async {
|
||||||
final entries = _getTargetItems(context);
|
final entries = _getTargetItems(context);
|
||||||
androidAppService.shareEntries(entries).then((success) {
|
try {
|
||||||
if (!success) showNoMatchingAppDialog(context);
|
if (!await androidAppService.shareEntries(entries)) {
|
||||||
});
|
await showNoMatchingAppDialog(context);
|
||||||
|
}
|
||||||
|
} on TooManyItemsException catch (_) {
|
||||||
|
await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AvesDialog(
|
||||||
|
content: Text(context.l10n.tooManyItemsErrorDialogMessage),
|
||||||
|
actions: const [OkButton()],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _rescan(BuildContext context) {
|
void _rescan(BuildContext context) {
|
||||||
|
@ -447,25 +458,20 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
if (unsupported.isEmpty) return supported;
|
if (unsupported.isEmpty) return supported;
|
||||||
|
|
||||||
final unsupportedTypes = unsupported.map((entry) => entry.mimeType).toSet().map(MimeUtils.displayType).toList()..sort();
|
final unsupportedTypes = unsupported.map((entry) => entry.mimeType).toSet().map(MimeUtils.displayType).toList()..sort();
|
||||||
|
final l10n = context.l10n;
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
final l10n = context.l10n;
|
|
||||||
return AvesDialog(
|
|
||||||
content: Text(l10n.unsupportedTypeDialogMessage(unsupportedTypes.length, unsupportedTypes.join(', '))),
|
content: Text(l10n.unsupportedTypeDialogMessage(unsupportedTypes.length, unsupportedTypes.join(', '))),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
if (supported.isNotEmpty)
|
if (supported.isNotEmpty)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(l10n.continueButtonLabel),
|
child: Text(l10n.continueButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return null;
|
if (confirmed == null || !confirmed) return null;
|
||||||
|
|
||||||
|
@ -536,21 +542,16 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
Future<void> removeLocation(BuildContext context, Set<AvesEntry> entries) async {
|
Future<void> removeLocation(BuildContext context, Set<AvesEntry> entries) async {
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.genericDangerWarningDialogMessage),
|
content: Text(context.l10n.genericDangerWarningDialogMessage),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -123,21 +123,16 @@ mixin EntryEditorMixin {
|
||||||
if (entries.any((entry) => entry.isMotionPhoto) && types.contains(MetadataType.xmp)) {
|
if (entries.any((entry) => entry.isMotionPhoto) && types.contains(MetadataType.xmp)) {
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.removeEntryMetadataMotionPhotoXmpWarningDialogMessage),
|
content: Text(context.l10n.removeEntryMetadataMotionPhotoXmpWarningDialogMessage),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return null;
|
if (confirmed == null || !confirmed) return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,8 +136,8 @@ mixin FeedbackMixin {
|
||||||
int? itemCount,
|
int? itemCount,
|
||||||
VoidCallback? onCancel,
|
VoidCallback? onCancel,
|
||||||
void Function(Set<T> processed)? onDone,
|
void Function(Set<T> processed)? onDone,
|
||||||
}) {
|
}) =>
|
||||||
return showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (context) => ReportOverlay<T>(
|
builder: (context) => ReportOverlay<T>(
|
||||||
|
@ -151,7 +151,6 @@ mixin FeedbackMixin {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class ReportOverlay<T> extends StatefulWidget {
|
class ReportOverlay<T> extends StatefulWidget {
|
||||||
final Stream<T> opStream;
|
final Stream<T> opStream;
|
||||||
|
|
|
@ -54,10 +54,7 @@ mixin PermissionAwareMixin {
|
||||||
return AvesDialog(
|
return AvesDialog(
|
||||||
content: Text(l10n.storageAccessDialogMessage(directory, volume)),
|
content: Text(l10n.storageAccessDialogMessage(directory, volume)),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
||||||
|
@ -72,17 +69,10 @@ mixin PermissionAwareMixin {
|
||||||
if (!await deviceService.isSystemFilePickerEnabled()) {
|
if (!await deviceService.isSystemFilePickerEnabled()) {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.missingSystemFilePickerDialogMessage),
|
content: Text(context.l10n.missingSystemFilePickerDialogMessage),
|
||||||
actions: [
|
actions: const [OkButton()],
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
|
||||||
),
|
),
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -103,12 +93,7 @@ mixin PermissionAwareMixin {
|
||||||
final volume = dir.getVolumeDescription(context);
|
final volume = dir.getVolumeDescription(context);
|
||||||
return AvesDialog(
|
return AvesDialog(
|
||||||
content: Text(context.l10n.restrictedAccessDialogMessage(directory, volume)),
|
content: Text(context.l10n.restrictedAccessDialogMessage(directory, volume)),
|
||||||
actions: [
|
actions: const [OkButton()],
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -85,12 +85,7 @@ mixin SizeAwareMixin {
|
||||||
final volume = destinationVolume.getDescription(context);
|
final volume = destinationVolume.getDescription(context);
|
||||||
return AvesDialog(
|
return AvesDialog(
|
||||||
content: Text(l10n.notEnoughSpaceDialogMessage(neededSize, freeSize, volume)),
|
content: Text(l10n.notEnoughSpaceDialogMessage(neededSize, freeSize, volume)),
|
||||||
actions: [
|
actions: const [OkButton()],
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -94,10 +94,7 @@ class _ColorPickerDialogState extends State<ColorPickerDialog> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, color),
|
onPressed: () => Navigator.pop(context, color),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
|
|
|
@ -87,10 +87,7 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -110,10 +110,7 @@ class _AvesConfirmationDialogState extends State<_AvesConfirmationDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_skip.value) {
|
if (_skip.value) {
|
||||||
|
|
|
@ -152,19 +152,34 @@ class DialogTitle extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showNoMatchingAppDialog(BuildContext context) {
|
Future<void> showNoMatchingAppDialog(BuildContext context) => showDialog(
|
||||||
showDialog(
|
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.noMatchingAppDialogMessage),
|
content: Text(context.l10n.noMatchingAppDialogMessage),
|
||||||
actions: [
|
actions: const [OkButton()],
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
|
||||||
),
|
),
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
|
||||||
|
class CancelButton extends StatelessWidget {
|
||||||
|
const CancelButton({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OkButton extends StatelessWidget {
|
||||||
|
const OkButton({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(MaterialLocalizations.of(context).okButtonLabel),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -86,10 +86,7 @@ class _AvesSelectionDialogState<T> extends State<AvesSelectionDialog<T>> {
|
||||||
if (verticalPadding != 0) SizedBox(height: verticalPadding),
|
if (verticalPadding != 0) SizedBox(height: verticalPadding),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
if (needConfirmation)
|
if (needConfirmation)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, _selectedValue),
|
onPressed: () => Navigator.pop(context, _selectedValue),
|
||||||
|
|
|
@ -88,10 +88,7 @@ class _DurationDialogState extends State<DurationDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
AnimatedBuilder(
|
AnimatedBuilder(
|
||||||
animation: Listenable.merge([_minutes, _seconds]),
|
animation: Listenable.merge([_minutes, _seconds]),
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
|
|
|
@ -112,10 +112,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => _submit(context),
|
onPressed: () => _submit(context),
|
||||||
child: Text(l10n.applyButtonLabel),
|
child: Text(l10n.applyButtonLabel),
|
||||||
|
|
|
@ -44,10 +44,7 @@ class _EditEntryTitleDescriptionDialogState extends State<EditEntryTitleDescript
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: fields.isEmpty ? null : () => _submit(context),
|
onPressed: fields.isEmpty ? null : () => _submit(context),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
|
|
|
@ -126,10 +126,7 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -99,10 +99,7 @@ class _EditEntryRatingDialogState extends State<EditEntryRatingDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: isValid ? () => _submit(context) : null,
|
onPressed: isValid ? () => _submit(context) : null,
|
||||||
child: Text(l10n.applyButtonLabel),
|
child: Text(l10n.applyButtonLabel),
|
||||||
|
|
|
@ -80,10 +80,7 @@ class _RemoveEntryMetadataDialogState extends State<RemoveEntryMetadataDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -58,10 +58,7 @@ class _RenameEntryDialogState extends State<RenameEntryDialog> {
|
||||||
onSubmitted: (_) => _submit(context),
|
onSubmitted: (_) => _submit(context),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -114,10 +114,7 @@ class _ExportEntryDialogState extends State<ExportEntryDialog> {
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -155,10 +155,7 @@ class _CoverSelectionDialogState extends State<CoverSelectionDialog> {
|
||||||
spacing: AvesDialog.buttonPadding.horizontal / 2,
|
spacing: AvesDialog.buttonPadding.horizontal / 2,
|
||||||
overflowAlignment: OverflowBarAlignment.end,
|
overflowAlignment: OverflowBarAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final entry = _isCustomEntry ? _customEntry : null;
|
final entry = _isCustomEntry ? _customEntry : null;
|
||||||
|
|
|
@ -90,10 +90,7 @@ class _CreateAlbumDialogState extends State<CreateAlbumDialog> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -57,10 +57,7 @@ class _RenameAlbumDialogState extends State<RenameAlbumDialog> {
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
ValueListenableBuilder<bool>(
|
ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isValidNotifier,
|
valueListenable: _isValidNotifier,
|
||||||
builder: (context, isValid, child) {
|
builder: (context, isValid, child) {
|
||||||
|
|
|
@ -145,10 +145,7 @@ class _TileViewDialogState<S, G, L> extends State<TileViewDialog<S, G, L>> with
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
key: const Key('button-apply'),
|
key: const Key('button-apply'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
|
@ -57,10 +57,7 @@ class _VideoSpeedDialogState extends State<VideoSpeedDialog> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => _submit(context),
|
onPressed: () => _submit(context),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
|
|
|
@ -80,10 +80,7 @@ class _VideoStreamSelectionDialogState extends State<VideoStreamSelectionDialog>
|
||||||
]
|
]
|
||||||
: null,
|
: null,
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
if (canSelect)
|
if (canSelect)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => _submit(context),
|
onPressed: () => _submit(context),
|
||||||
|
|
|
@ -39,10 +39,7 @@ class _WallpaperSettingsDialogState extends State<WallpaperSettingsDialog> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, Tuple2<WallpaperTarget, bool>(_selectedTarget, _useScrollEffect)),
|
onPressed: () => Navigator.pop(context, Tuple2<WallpaperTarget, bool>(_selectedTarget, _useScrollEffect)),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
|
|
|
@ -234,21 +234,16 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate<AlbumFilter> with
|
||||||
|
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(filters.length == 1 ? l10n.deleteSingleAlbumConfirmationDialogMessage(todoCount) : l10n.deleteMultiAlbumConfirmationDialogMessage(todoCount)),
|
content: Text(filters.length == 1 ? l10n.deleteSingleAlbumConfirmationDialogMessage(todoCount) : l10n.deleteMultiAlbumConfirmationDialogMessage(todoCount)),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(l10n.deleteButtonLabel),
|
child: Text(l10n.deleteButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -53,21 +53,16 @@ class ChipActionDelegate {
|
||||||
Future<void> _hide(BuildContext context, CollectionFilter filter) async {
|
Future<void> _hide(BuildContext context, CollectionFilter filter) async {
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.hideFilterConfirmationDialogMessage),
|
content: Text(context.l10n.hideFilterConfirmationDialogMessage),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(context.l10n.hideButtonLabel),
|
child: Text(context.l10n.hideButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -304,21 +304,16 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
Future<void> _hide(BuildContext context, Set<T> filters) async {
|
Future<void> _hide(BuildContext context, Set<T> filters) async {
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.hideFilterConfirmationDialogMessage),
|
content: Text(context.l10n.hideFilterConfirmationDialogMessage),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(context.l10n.hideButtonLabel),
|
child: Text(context.l10n.hideButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -54,10 +54,7 @@ class _AppExportItemSelectionDialogState extends State<AppExportItemSelectionDia
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: _selectedItems.isEmpty ? null : () => Navigator.pop(context, _selectedItems),
|
onPressed: _selectedItems.isEmpty ? null : () => Navigator.pop(context, _selectedItems),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
|
|
|
@ -114,27 +114,22 @@ class SettingsTileDisplayForceTvLayout extends SettingsTile {
|
||||||
selector: (context, s) => s.forceTvLayout,
|
selector: (context, s) => s.forceTvLayout,
|
||||||
onChanged: (v) async {
|
onChanged: (v) async {
|
||||||
if (v) {
|
if (v) {
|
||||||
|
final l10n = context.l10n;
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
final l10n = context.l10n;
|
|
||||||
return AvesDialog(
|
|
||||||
content: Text([
|
content: Text([
|
||||||
l10n.settingsModificationWarningDialogMessage,
|
l10n.settingsModificationWarningDialogMessage,
|
||||||
l10n.genericDangerWarningDialogMessage,
|
l10n.genericDangerWarningDialogMessage,
|
||||||
].join('\n\n')),
|
].join('\n\n')),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(l10n.applyButtonLabel),
|
child: Text(l10n.applyButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,21 +229,16 @@ class EntryInfoActionDelegate with FeedbackMixin, PermissionAwareMixin, EntryEdi
|
||||||
Future<void> _convertMotionPhotoToStillImage(BuildContext context, AvesEntry targetEntry) async {
|
Future<void> _convertMotionPhotoToStillImage(BuildContext context, AvesEntry targetEntry) async {
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.genericDangerWarningDialogMessage),
|
content: Text(context.l10n.genericDangerWarningDialogMessage),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
const CancelButton(),
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
|
||||||
),
|
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, true),
|
onPressed: () => Navigator.pop(context, true),
|
||||||
child: Text(context.l10n.applyButtonLabel),
|
child: Text(context.l10n.applyButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (confirmed == null || !confirmed) return;
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@ abstract class AvesVideoController {
|
||||||
|
|
||||||
final resume = await showDialog<bool>(
|
final resume = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) => AvesDialog(
|
||||||
return AvesDialog(
|
|
||||||
content: Text(context.l10n.videoResumeDialogMessage(formatFriendlyDuration(Duration(milliseconds: resumeTime)))),
|
content: Text(context.l10n.videoResumeDialogMessage(formatFriendlyDuration(Duration(milliseconds: resumeTime)))),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
|
@ -79,8 +78,7 @@ abstract class AvesVideoController {
|
||||||
child: Text(context.l10n.videoResumeButtonLabel),
|
child: Text(context.l10n.videoResumeButtonLabel),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if (resume == null || !resume) return 0;
|
if (resume == null || !resume) return 0;
|
||||||
return resumeTime;
|
return resumeTime;
|
||||||
|
|
|
@ -226,6 +226,7 @@
|
||||||
"genericSuccessFeedback",
|
"genericSuccessFeedback",
|
||||||
"genericFailureFeedback",
|
"genericFailureFeedback",
|
||||||
"genericDangerWarningDialogMessage",
|
"genericDangerWarningDialogMessage",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"menuActionConfigureView",
|
"menuActionConfigureView",
|
||||||
"menuActionSelect",
|
"menuActionSelect",
|
||||||
"menuActionSelectAll",
|
"menuActionSelectAll",
|
||||||
|
@ -572,6 +573,7 @@
|
||||||
"cs": [
|
"cs": [
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsDisplayUseTvInterface"
|
"settingsDisplayUseTvInterface"
|
||||||
|
@ -581,6 +583,7 @@
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
@ -590,11 +593,16 @@
|
||||||
"el": [
|
"el": [
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsDisplayUseTvInterface"
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"es": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
"clearTooltip",
|
"clearTooltip",
|
||||||
"videoActionPause",
|
"videoActionPause",
|
||||||
|
@ -708,6 +716,7 @@
|
||||||
"genericSuccessFeedback",
|
"genericSuccessFeedback",
|
||||||
"genericFailureFeedback",
|
"genericFailureFeedback",
|
||||||
"genericDangerWarningDialogMessage",
|
"genericDangerWarningDialogMessage",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"menuActionConfigureView",
|
"menuActionConfigureView",
|
||||||
"menuActionSelect",
|
"menuActionSelect",
|
||||||
"menuActionSelectAll",
|
"menuActionSelectAll",
|
||||||
|
@ -1035,6 +1044,10 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"gl": [
|
"gl": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"entryActionShareImageOnly",
|
"entryActionShareImageOnly",
|
||||||
|
@ -1151,6 +1164,7 @@
|
||||||
"genericSuccessFeedback",
|
"genericSuccessFeedback",
|
||||||
"genericFailureFeedback",
|
"genericFailureFeedback",
|
||||||
"genericDangerWarningDialogMessage",
|
"genericDangerWarningDialogMessage",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"menuActionConfigureView",
|
"menuActionConfigureView",
|
||||||
"menuActionSelect",
|
"menuActionSelect",
|
||||||
"menuActionSelectAll",
|
"menuActionSelectAll",
|
||||||
|
@ -1507,9 +1521,14 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"id": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsDisplayUseTvInterface"
|
"settingsDisplayUseTvInterface"
|
||||||
|
@ -1526,6 +1545,7 @@
|
||||||
"keepScreenOnVideoPlayback",
|
"keepScreenOnVideoPlayback",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
@ -1533,11 +1553,16 @@
|
||||||
"settingsWidgetDisplayedItem"
|
"settingsWidgetDisplayedItem"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ko": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"lt": [
|
"lt": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
"keepScreenOnVideoPlayback",
|
"keepScreenOnVideoPlayback",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
@ -1552,6 +1577,7 @@
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
"keepScreenOnVideoPlayback",
|
"keepScreenOnVideoPlayback",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
@ -1574,6 +1600,7 @@
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"widgetDisplayedItemRandom",
|
"widgetDisplayedItemRandom",
|
||||||
"widgetDisplayedItemMostRecent",
|
"widgetDisplayedItemMostRecent",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
|
@ -1603,6 +1630,7 @@
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
"locationPickerUseThisLocationButton",
|
"locationPickerUseThisLocationButton",
|
||||||
"removeEntryMetadataMotionPhotoXmpWarningDialogMessage",
|
"removeEntryMetadataMotionPhotoXmpWarningDialogMessage",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"viewDialogSortSectionTitle",
|
"viewDialogSortSectionTitle",
|
||||||
"viewDialogReverseSortOrder",
|
"viewDialogReverseSortOrder",
|
||||||
"aboutLinkPolicy",
|
"aboutLinkPolicy",
|
||||||
|
@ -1870,20 +1898,30 @@
|
||||||
"wallpaperUseScrollEffect"
|
"wallpaperUseScrollEffect"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"pl": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
"widgetDisplayedItemMostRecent",
|
"widgetDisplayedItemMostRecent",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
"settingsDisplayUseTvInterface"
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ro": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsDisplayUseTvInterface"
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
@ -1922,6 +1960,7 @@
|
||||||
"editEntryDateDialogExtractFromTitle",
|
"editEntryDateDialogExtractFromTitle",
|
||||||
"editEntryDateDialogShift",
|
"editEntryDateDialogShift",
|
||||||
"removeEntryMetadataDialogTitle",
|
"removeEntryMetadataDialogTitle",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"collectionActionShowTitleSearch",
|
"collectionActionShowTitleSearch",
|
||||||
"collectionActionHideTitleSearch",
|
"collectionActionHideTitleSearch",
|
||||||
"collectionActionAddShortcut",
|
"collectionActionAddShortcut",
|
||||||
|
@ -2235,9 +2274,18 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"tr": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
|
"uk": [
|
||||||
|
"tooManyItemsErrorDialogMessage"
|
||||||
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
@ -2248,6 +2296,7 @@
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"filterLocatedLabel",
|
"filterLocatedLabel",
|
||||||
"filterTaggedLabel",
|
"filterTaggedLabel",
|
||||||
|
"tooManyItemsErrorDialogMessage",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
|
Loading…
Reference in a new issue