#383 optional media management permission
This commit is contained in:
parent
c89f17fe8a
commit
22149ffca2
8 changed files with 138 additions and 2 deletions
|
@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Info: edit location by copying from other item
|
- Info: edit location by copying from other item
|
||||||
- Info: edit tags with dynamic placeholders for country / place
|
- Info: edit tags with dynamic placeholders for country / place
|
||||||
- Widget: option to open collection on tap
|
- Widget: option to open collection on tap
|
||||||
|
- optional MANAGE_MEDIA permission to modify media without asking
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,14 @@ This change eventually prevents building the app with Flutter v3.3.3.
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="29"
|
android:maxSdkVersion="29"
|
||||||
tools:ignore="ScopedStorage" />
|
tools:ignore="ScopedStorage" />
|
||||||
|
|
||||||
|
<!-- from Android 12 (API 31), users can optionally grant access to the media management special permission -->
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.MANAGE_MEDIA"
|
||||||
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<!-- to show foreground service progress via notification -->
|
<!-- to show foreground service progress via notification -->
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
|
|
@ -3,7 +3,10 @@ package deckers.thibault.aves.channel.calls
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import android.provider.Settings
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
||||||
import deckers.thibault.aves.model.FieldMap
|
import deckers.thibault.aves.model.FieldMap
|
||||||
|
@ -15,15 +18,21 @@ import java.util.*
|
||||||
class DeviceHandler(private val context: Context) : MethodCallHandler {
|
class DeviceHandler(private val context: Context) : MethodCallHandler {
|
||||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||||
when (call.method) {
|
when (call.method) {
|
||||||
|
"canManageMedia" -> safe(call, result, ::canManageMedia)
|
||||||
"getCapabilities" -> safe(call, result, ::getCapabilities)
|
"getCapabilities" -> safe(call, result, ::getCapabilities)
|
||||||
"getDefaultTimeZone" -> safe(call, result, ::getDefaultTimeZone)
|
"getDefaultTimeZone" -> safe(call, result, ::getDefaultTimeZone)
|
||||||
"getLocales" -> safe(call, result, ::getLocales)
|
"getLocales" -> safe(call, result, ::getLocales)
|
||||||
"getPerformanceClass" -> safe(call, result, ::getPerformanceClass)
|
"getPerformanceClass" -> safe(call, result, ::getPerformanceClass)
|
||||||
"isSystemFilePickerEnabled" -> safe(call, result, ::isSystemFilePickerEnabled)
|
"isSystemFilePickerEnabled" -> safe(call, result, ::isSystemFilePickerEnabled)
|
||||||
|
"requestMediaManagePermission" -> safe(call, result, ::requestMediaManagePermission)
|
||||||
else -> result.notImplemented()
|
else -> result.notImplemented()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun canManageMedia(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
||||||
|
result.success(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) MediaStore.canManageMedia(context) else false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getCapabilities(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
private fun getCapabilities(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
||||||
val sdkInt = Build.VERSION.SDK_INT
|
val sdkInt = Build.VERSION.SDK_INT
|
||||||
result.success(
|
result.success(
|
||||||
|
@ -32,6 +41,7 @@ class DeviceHandler(private val context: Context) : MethodCallHandler {
|
||||||
"canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context),
|
"canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context),
|
||||||
"canPrint" to (sdkInt >= Build.VERSION_CODES.KITKAT),
|
"canPrint" to (sdkInt >= Build.VERSION_CODES.KITKAT),
|
||||||
"canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP),
|
"canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP),
|
||||||
|
"canRequestManageMedia" to (sdkInt >= Build.VERSION_CODES.S),
|
||||||
"canSetLockScreenWallpaper" to (sdkInt >= Build.VERSION_CODES.N),
|
"canSetLockScreenWallpaper" to (sdkInt >= Build.VERSION_CODES.N),
|
||||||
"isDynamicColorAvailable" to (sdkInt >= Build.VERSION_CODES.S),
|
"isDynamicColorAvailable" to (sdkInt >= Build.VERSION_CODES.S),
|
||||||
"showPinShortcutFeedback" to (sdkInt >= Build.VERSION_CODES.O),
|
"showPinShortcutFeedback" to (sdkInt >= Build.VERSION_CODES.O),
|
||||||
|
@ -90,6 +100,17 @@ class DeviceHandler(private val context: Context) : MethodCallHandler {
|
||||||
result.success(enabled)
|
result.success(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun requestMediaManagePermission(@Suppress("unused_parameter") call: MethodCall, result: MethodChannel.Result) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
|
result.error("requestMediaManagePermission-unsupported", "media management permission is not available before Android 12", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val intent = Intent(Settings.ACTION_REQUEST_MANAGE_MEDIA, Uri.parse("package:${context.packageName}"))
|
||||||
|
context.startActivity(intent)
|
||||||
|
result.success(true)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val CHANNEL = "deckers.thibault/aves/device"
|
const val CHANNEL = "deckers.thibault/aves/device"
|
||||||
}
|
}
|
||||||
|
|
|
@ -760,6 +760,7 @@
|
||||||
"settingsSaveSearchHistory": "Save search history",
|
"settingsSaveSearchHistory": "Save search history",
|
||||||
"settingsEnableBin": "Use recycle bin",
|
"settingsEnableBin": "Use recycle bin",
|
||||||
"settingsEnableBinSubtitle": "Keep deleted items for 30 days",
|
"settingsEnableBinSubtitle": "Keep deleted items for 30 days",
|
||||||
|
"settingsAllowMediaManagement": "Allow media management",
|
||||||
|
|
||||||
"settingsHiddenItemsTile": "Hidden items",
|
"settingsHiddenItemsTile": "Hidden items",
|
||||||
"settingsHiddenItemsPageTitle": "Hidden Items",
|
"settingsHiddenItemsPageTitle": "Hidden Items",
|
||||||
|
|
|
@ -5,7 +5,7 @@ final Device device = Device._private();
|
||||||
|
|
||||||
class Device {
|
class Device {
|
||||||
late final String _userAgent;
|
late final String _userAgent;
|
||||||
late final bool _canGrantDirectoryAccess, _canPinShortcut, _canPrint, _canRenderFlagEmojis, _canSetLockScreenWallpaper;
|
late final bool _canGrantDirectoryAccess, _canPinShortcut, _canPrint, _canRenderFlagEmojis, _canRequestManageMedia, _canSetLockScreenWallpaper;
|
||||||
late final bool _isDynamicColorAvailable, _showPinShortcutFeedback, _supportEdgeToEdgeUIMode;
|
late final bool _isDynamicColorAvailable, _showPinShortcutFeedback, _supportEdgeToEdgeUIMode;
|
||||||
|
|
||||||
String get userAgent => _userAgent;
|
String get userAgent => _userAgent;
|
||||||
|
@ -18,6 +18,8 @@ class Device {
|
||||||
|
|
||||||
bool get canRenderFlagEmojis => _canRenderFlagEmojis;
|
bool get canRenderFlagEmojis => _canRenderFlagEmojis;
|
||||||
|
|
||||||
|
bool get canRequestManageMedia => _canRequestManageMedia;
|
||||||
|
|
||||||
bool get canSetLockScreenWallpaper => _canSetLockScreenWallpaper;
|
bool get canSetLockScreenWallpaper => _canSetLockScreenWallpaper;
|
||||||
|
|
||||||
bool get isDynamicColorAvailable => _isDynamicColorAvailable;
|
bool get isDynamicColorAvailable => _isDynamicColorAvailable;
|
||||||
|
@ -37,6 +39,7 @@ class Device {
|
||||||
_canPinShortcut = capabilities['canPinShortcut'] ?? false;
|
_canPinShortcut = capabilities['canPinShortcut'] ?? false;
|
||||||
_canPrint = capabilities['canPrint'] ?? false;
|
_canPrint = capabilities['canPrint'] ?? false;
|
||||||
_canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false;
|
_canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false;
|
||||||
|
_canRequestManageMedia = capabilities['canRequestManageMedia'] ?? false;
|
||||||
_canSetLockScreenWallpaper = capabilities['canSetLockScreenWallpaper'] ?? false;
|
_canSetLockScreenWallpaper = capabilities['canSetLockScreenWallpaper'] ?? false;
|
||||||
_isDynamicColorAvailable = capabilities['isDynamicColorAvailable'] ?? false;
|
_isDynamicColorAvailable = capabilities['isDynamicColorAvailable'] ?? false;
|
||||||
_showPinShortcutFeedback = capabilities['showPinShortcutFeedback'] ?? false;
|
_showPinShortcutFeedback = capabilities['showPinShortcutFeedback'] ?? false;
|
||||||
|
|
|
@ -4,6 +4,8 @@ import 'package:aves/services/common/services.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
abstract class DeviceService {
|
abstract class DeviceService {
|
||||||
|
Future<bool> canManageMedia();
|
||||||
|
|
||||||
Future<Map<String, dynamic>> getCapabilities();
|
Future<Map<String, dynamic>> getCapabilities();
|
||||||
|
|
||||||
Future<String?> getDefaultTimeZone();
|
Future<String?> getDefaultTimeZone();
|
||||||
|
@ -13,11 +15,24 @@ abstract class DeviceService {
|
||||||
Future<int> getPerformanceClass();
|
Future<int> getPerformanceClass();
|
||||||
|
|
||||||
Future<bool> isSystemFilePickerEnabled();
|
Future<bool> isSystemFilePickerEnabled();
|
||||||
|
|
||||||
|
Future<void> requestMediaManagePermission();
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlatformDeviceService implements DeviceService {
|
class PlatformDeviceService implements DeviceService {
|
||||||
static const _platform = MethodChannel('deckers.thibault/aves/device');
|
static const _platform = MethodChannel('deckers.thibault/aves/device');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> canManageMedia() async {
|
||||||
|
try {
|
||||||
|
final result = await _platform.invokeMethod('canManageMedia');
|
||||||
|
if (result != null) return result as bool;
|
||||||
|
} on PlatformException catch (e, stack) {
|
||||||
|
await reportService.recordError(e, stack);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, dynamic>> getCapabilities() async {
|
Future<Map<String, dynamic>> getCapabilities() async {
|
||||||
try {
|
try {
|
||||||
|
@ -80,4 +95,13 @@ class PlatformDeviceService implements DeviceService {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> requestMediaManagePermission() async {
|
||||||
|
try {
|
||||||
|
await _platform.invokeMethod('requestMediaManagePermission');
|
||||||
|
} on PlatformException catch (e, stack) {
|
||||||
|
await reportService.recordError(e, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:async';
|
||||||
import 'package:aves/app_flavor.dart';
|
import 'package:aves/app_flavor.dart';
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/device.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/theme/colors.dart';
|
import 'package:aves/theme/colors.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
@ -33,6 +34,7 @@ class PrivacySection extends SettingsSection {
|
||||||
return [
|
return [
|
||||||
SettingsTilePrivacyAllowInstalledAppAccess(),
|
SettingsTilePrivacyAllowInstalledAppAccess(),
|
||||||
if (canEnableErrorReporting) SettingsTilePrivacyAllowErrorReporting(),
|
if (canEnableErrorReporting) SettingsTilePrivacyAllowErrorReporting(),
|
||||||
|
if (device.canRequestManageMedia) SettingsTilePrivacyManageMedia(),
|
||||||
SettingsTilePrivacySaveSearchHistory(),
|
SettingsTilePrivacySaveSearchHistory(),
|
||||||
SettingsTilePrivacyEnableBin(),
|
SettingsTilePrivacyEnableBin(),
|
||||||
SettingsTilePrivacyHiddenItems(),
|
SettingsTilePrivacyHiddenItems(),
|
||||||
|
@ -124,3 +126,65 @@ class SettingsTilePrivacyStorageAccess extends SettingsTile {
|
||||||
builder: (context) => const StorageAccessPage(),
|
builder: (context) => const StorageAccessPage(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SettingsTilePrivacyManageMedia extends SettingsTile {
|
||||||
|
@override
|
||||||
|
String title(BuildContext context) => context.l10n.settingsAllowMediaManagement;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => _ManageMediaTile(title: title(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ManageMediaTile extends StatefulWidget {
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
const _ManageMediaTile({
|
||||||
|
required this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_ManageMediaTile> createState() => _ManageMediaTileState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ManageMediaTileState extends State<_ManageMediaTile> with WidgetsBindingObserver {
|
||||||
|
late Future<bool> _loader;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_initLoader();
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _initLoader() => _loader = deviceService.canManageMedia();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
|
if (state == AppLifecycleState.resumed) {
|
||||||
|
_initLoader();
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder<bool>(
|
||||||
|
future: _loader,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final loading = snapshot.connectionState != ConnectionState.done;
|
||||||
|
final current = snapshot.data ?? false;
|
||||||
|
return SwitchListTile(
|
||||||
|
value: current,
|
||||||
|
onChanged: loading ? null : (v) => deviceService.requestMediaManagePermission(),
|
||||||
|
title: Text(widget.title),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"de": [
|
"de": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
|
|
||||||
"el": [
|
"el": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -18,6 +20,7 @@
|
||||||
"widgetOpenPageCollection",
|
"widgetOpenPageCollection",
|
||||||
"widgetOpenPageViewer",
|
"widgetOpenPageViewer",
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -507,6 +510,7 @@
|
||||||
"settingsSaveSearchHistory",
|
"settingsSaveSearchHistory",
|
||||||
"settingsEnableBin",
|
"settingsEnableBin",
|
||||||
"settingsEnableBinSubtitle",
|
"settingsEnableBinSubtitle",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsHiddenItemsTile",
|
"settingsHiddenItemsTile",
|
||||||
"settingsHiddenItemsPageTitle",
|
"settingsHiddenItemsPageTitle",
|
||||||
"settingsHiddenItemsTabFilters",
|
"settingsHiddenItemsTabFilters",
|
||||||
|
@ -606,6 +610,7 @@
|
||||||
|
|
||||||
"fr": [
|
"fr": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -962,6 +967,7 @@
|
||||||
"settingsSaveSearchHistory",
|
"settingsSaveSearchHistory",
|
||||||
"settingsEnableBin",
|
"settingsEnableBin",
|
||||||
"settingsEnableBinSubtitle",
|
"settingsEnableBinSubtitle",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsHiddenItemsTile",
|
"settingsHiddenItemsTile",
|
||||||
"settingsHiddenItemsPageTitle",
|
"settingsHiddenItemsPageTitle",
|
||||||
"settingsHiddenItemsTabFilters",
|
"settingsHiddenItemsTabFilters",
|
||||||
|
@ -1073,6 +1079,7 @@
|
||||||
"albumMimeTypeMixed",
|
"albumMimeTypeMixed",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
"settingsSlideshowAnimatedZoomEffect",
|
"settingsSlideshowAnimatedZoomEffect",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsWidgetOpenPage",
|
"settingsWidgetOpenPage",
|
||||||
"statsTopAlbumsSectionTitle",
|
"statsTopAlbumsSectionTitle",
|
||||||
"wallpaperUseScrollEffect",
|
"wallpaperUseScrollEffect",
|
||||||
|
@ -1083,6 +1090,7 @@
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -1118,6 +1126,7 @@
|
||||||
"settingsConfirmationAfterMoveToBinItems",
|
"settingsConfirmationAfterMoveToBinItems",
|
||||||
"settingsViewerGestureSideTapNext",
|
"settingsViewerGestureSideTapNext",
|
||||||
"settingsSlideshowAnimatedZoomEffect",
|
"settingsSlideshowAnimatedZoomEffect",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsWidgetOpenPage",
|
"settingsWidgetOpenPage",
|
||||||
"statsTopAlbumsSectionTitle",
|
"statsTopAlbumsSectionTitle",
|
||||||
"viewerInfoLabelDescription",
|
"viewerInfoLabelDescription",
|
||||||
|
@ -1129,6 +1138,7 @@
|
||||||
|
|
||||||
"ko": [
|
"ko": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -1222,6 +1232,7 @@
|
||||||
"settingsSlideshowShuffle",
|
"settingsSlideshowShuffle",
|
||||||
"settingsSubtitleThemeSample",
|
"settingsSubtitleThemeSample",
|
||||||
"settingsAllowInstalledAppAccess",
|
"settingsAllowInstalledAppAccess",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsHiddenFiltersBanner",
|
"settingsHiddenFiltersBanner",
|
||||||
"settingsHiddenFiltersEmpty",
|
"settingsHiddenFiltersEmpty",
|
||||||
"settingsHiddenItemsTabPaths",
|
"settingsHiddenItemsTabPaths",
|
||||||
|
@ -1253,6 +1264,7 @@
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
"aboutLinkPolicy",
|
"aboutLinkPolicy",
|
||||||
"policyPageTitle",
|
"policyPageTitle",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -1649,6 +1661,7 @@
|
||||||
"settingsSaveSearchHistory",
|
"settingsSaveSearchHistory",
|
||||||
"settingsEnableBin",
|
"settingsEnableBin",
|
||||||
"settingsEnableBinSubtitle",
|
"settingsEnableBinSubtitle",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsHiddenItemsTile",
|
"settingsHiddenItemsTile",
|
||||||
"settingsHiddenItemsPageTitle",
|
"settingsHiddenItemsPageTitle",
|
||||||
"settingsHiddenItemsTabFilters",
|
"settingsHiddenItemsTabFilters",
|
||||||
|
@ -1748,6 +1761,7 @@
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -1755,6 +1769,7 @@
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
@ -1813,6 +1828,7 @@
|
||||||
"settingsSlideshowIntervalTile",
|
"settingsSlideshowIntervalTile",
|
||||||
"settingsSlideshowVideoPlaybackTile",
|
"settingsSlideshowVideoPlaybackTile",
|
||||||
"settingsSlideshowVideoPlaybackDialogTitle",
|
"settingsSlideshowVideoPlaybackDialogTitle",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"settingsScreenSaverPageTitle",
|
"settingsScreenSaverPageTitle",
|
||||||
"settingsWidgetShowOutline",
|
"settingsWidgetShowOutline",
|
||||||
"settingsWidgetOpenPage",
|
"settingsWidgetOpenPage",
|
||||||
|
@ -1827,6 +1843,7 @@
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"editEntryLocationDialogSetCustom",
|
"editEntryLocationDialogSetCustom",
|
||||||
|
"settingsAllowMediaManagement",
|
||||||
"tagEditorSectionPlaceholders",
|
"tagEditorSectionPlaceholders",
|
||||||
"tagPlaceholderCountry",
|
"tagPlaceholderCountry",
|
||||||
"tagPlaceholderPlace"
|
"tagPlaceholderPlace"
|
||||||
|
|
Loading…
Reference in a new issue