#543 vaults: custom pattern lock

This commit is contained in:
Thibault Deckers 2023-03-03 20:27:12 +01:00
parent e82d042fc7
commit 2183ff7cd7
12 changed files with 286 additions and 53 deletions

View file

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
## <a id="unreleased"></a>[Unreleased] ## <a id="unreleased"></a>[Unreleased]
### Added
- Vaults: custom pattern lock
### Changed ### Changed
- upgraded Flutter to stable v3.7.6 - upgraded Flutter to stable v3.7.6

View file

@ -226,7 +226,8 @@
"unitSystemMetric": "Metric", "unitSystemMetric": "Metric",
"unitSystemImperial": "Imperial", "unitSystemImperial": "Imperial",
"vaultLockTypePin": "Pin", "vaultLockTypePattern": "Pattern",
"vaultLockTypePin": "PIN",
"vaultLockTypePassword": "Password", "vaultLockTypePassword": "Password",
"videoControlsPlay": "Play", "videoControlsPlay": "Play",
@ -384,8 +385,11 @@
"vaultDialogLockModeWhenScreenOff": "Lock when screen turns off", "vaultDialogLockModeWhenScreenOff": "Lock when screen turns off",
"vaultDialogLockTypeLabel": "Lock type", "vaultDialogLockTypeLabel": "Lock type",
"pinDialogEnter": "Enter pin", "patternDialogEnter": "Enter pattern",
"pinDialogConfirm": "Confirm pin", "patternDialogConfirm": "Confirm pattern",
"pinDialogEnter": "Enter PIN",
"pinDialogConfirm": "Confirm PIN",
"passwordDialogEnter": "Enter password", "passwordDialogEnter": "Enter password",
"passwordDialogConfirm": "Confirm password", "passwordDialogConfirm": "Confirm password",

View file

@ -1,13 +1,15 @@
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
enum VaultLockType { system, pin, password } enum VaultLockType { system, pattern, pin, password }
extension ExtraVaultLockType on VaultLockType { extension ExtraVaultLockType on VaultLockType {
String getText(BuildContext context) { String getText(BuildContext context) {
switch (this) { switch (this) {
case VaultLockType.system: case VaultLockType.system:
return context.l10n.settingsSystemDefault; return context.l10n.settingsSystemDefault;
case VaultLockType.pattern:
return context.l10n.vaultLockTypePattern;
case VaultLockType.pin: case VaultLockType.pin:
return context.l10n.vaultLockTypePin; return context.l10n.vaultLockTypePin;
case VaultLockType.password: case VaultLockType.password:

View file

@ -7,6 +7,7 @@ import 'package:aves/services/common/services.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/filter_editors/password_dialog.dart'; import 'package:aves/widgets/dialogs/filter_editors/password_dialog.dart';
import 'package:aves/widgets/dialogs/filter_editors/pattern_dialog.dart';
import 'package:aves/widgets/dialogs/filter_editors/pin_dialog.dart'; import 'package:aves/widgets/dialogs/filter_editors/pin_dialog.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -160,6 +161,16 @@ class Vaults extends ChangeNotifier {
} }
} }
break; break;
case VaultLockType.pattern:
final pattern = await showDialog<String>(
context: context,
builder: (context) => const PatternDialog(needConfirmation: false),
routeSettings: const RouteSettings(name: PatternDialog.routeName),
);
if (pattern != null) {
confirmed = pattern == await securityService.readValue(details.passKey);
}
break;
case VaultLockType.pin: case VaultLockType.pin:
final pin = await showDialog<String>( final pin = await showDialog<String>(
context: context, context: context,
@ -211,6 +222,16 @@ class Vaults extends ChangeNotifier {
} }
} }
break; break;
case VaultLockType.pattern:
final pattern = await showDialog<String>(
context: context,
builder: (context) => const PatternDialog(needConfirmation: true),
routeSettings: const RouteSettings(name: PatternDialog.routeName),
);
if (pattern != null) {
return await securityService.writeValue(details.passKey, pattern);
}
break;
case VaultLockType.pin: case VaultLockType.pin:
final pin = await showDialog<String>( final pin = await showDialog<String>(
context: context, context: context,

View file

@ -260,6 +260,11 @@ class Dependencies {
license: apache2, license: apache2,
sourceUrl: 'https://github.com/zesage/panorama', sourceUrl: 'https://github.com/zesage/panorama',
), ),
Dependency(
name: 'Pattern Lock',
license: apache2,
sourceUrl: 'https://github.com/qwert2603/pattern_lock',
),
Dependency( Dependency(
name: 'Percent Indicator', name: 'Percent Indicator',
license: bsd2, license: bsd2,

View file

@ -39,6 +39,7 @@ class _EditVaultDialogState extends State<EditVaultDialog> {
final List<VaultLockType> _lockTypeOptions = [ final List<VaultLockType> _lockTypeOptions = [
if (device.canAuthenticateUser) VaultLockType.system, if (device.canAuthenticateUser) VaultLockType.system,
if (device.canUseCrypto) ...[ if (device.canUseCrypto) ...[
VaultLockType.pattern,
VaultLockType.pin, VaultLockType.pin,
VaultLockType.password, VaultLockType.password,
], ],

View file

@ -41,31 +41,7 @@ class _PasswordDialogState extends State<PasswordDialog> {
controller: _controller, controller: _controller,
focusNode: _focusNode, focusNode: _focusNode,
obscureText: true, obscureText: true,
onSubmitted: (password) { onSubmitted: _submit,
if (widget.needConfirmation) {
if (_confirming) {
final match = _firstPassword == password;
Navigator.maybeOf(context)?.pop<String>(match ? password : null);
if (!match) {
showDialog(
context: context,
builder: (context) => AvesDialog(
content: Text(context.l10n.genericFailureFeedback),
actions: const [OkButton()],
),
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
);
}
} else {
_firstPassword = password;
_controller.clear();
setState(() => _confirming = true);
WidgetsBinding.instance.addPostFrameCallback((_) => _focusNode.requestFocus());
}
} else {
Navigator.maybeOf(context)?.pop<String>(password);
}
},
autofillHints: const [AutofillHints.password], autofillHints: const [AutofillHints.password],
), ),
), ),
@ -73,4 +49,30 @@ class _PasswordDialogState extends State<PasswordDialog> {
), ),
); );
} }
void _submit(String password) {
if (widget.needConfirmation) {
if (_confirming) {
final match = _firstPassword == password;
Navigator.maybeOf(context)?.pop<String>(match ? password : null);
if (!match) {
showDialog(
context: context,
builder: (context) => AvesDialog(
content: Text(context.l10n.genericFailureFeedback),
actions: const [OkButton()],
),
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
);
}
} else {
_firstPassword = password;
_controller.clear();
setState(() => _confirming = true);
WidgetsBinding.instance.addPostFrameCallback((_) => _focusNode.requestFocus());
}
} else {
Navigator.maybeOf(context)?.pop<String>(password);
}
}
} }

View file

@ -0,0 +1,75 @@
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:flutter/material.dart';
import 'package:pattern_lock/pattern_lock.dart';
import 'package:provider/provider.dart';
class PatternDialog extends StatefulWidget {
static const routeName = '/dialog/pattern';
final bool needConfirmation;
const PatternDialog({
super.key,
required this.needConfirmation,
});
@override
State<PatternDialog> createState() => _PatternDialogState();
}
class _PatternDialogState extends State<PatternDialog> {
bool _confirming = false;
String? _firstPattern;
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return AvesDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(_confirming ? context.l10n.patternDialogConfirm : context.l10n.patternDialogEnter),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: SizedBox.square(
dimension: context.select<MediaQueryData, double>((mq) => mq.size.shortestSide / 2),
child: PatternLock(
relativePadding: .4,
selectedColor: colorScheme.secondary,
notSelectedColor: colorScheme.onBackground,
pointRadius: 8,
fillPoints: true,
onInputComplete: (input) => _submit(input.join()),
),
),
),
],
),
);
}
void _submit(String pattern) {
if (widget.needConfirmation) {
if (_confirming) {
final match = _firstPattern == pattern;
Navigator.maybeOf(context)?.pop<String>(match ? pattern : null);
if (!match) {
showDialog(
context: context,
builder: (context) => AvesDialog(
content: Text(context.l10n.genericFailureFeedback),
actions: const [OkButton()],
),
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
);
}
} else {
_firstPattern = pattern;
setState(() => _confirming = true);
}
} else {
Navigator.maybeOf(context)?.pop<String>(pattern);
}
}
}

View file

@ -38,30 +38,7 @@ class _PinDialogState extends State<PinDialog> {
controller: _controller, controller: _controller,
obscureText: true, obscureText: true,
onChanged: (v) {}, onChanged: (v) {},
onCompleted: (pin) { onCompleted: _submit,
if (widget.needConfirmation) {
if (_confirming) {
final match = _firstPin == pin;
Navigator.maybeOf(context)?.pop<String>(match ? pin : null);
if (!match) {
showDialog(
context: context,
builder: (context) => AvesDialog(
content: Text(context.l10n.genericFailureFeedback),
actions: const [OkButton()],
),
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
);
}
} else {
_firstPin = pin;
_controller.clear();
setState(() => _confirming = true);
}
} else {
Navigator.maybeOf(context)?.pop<String>(pin);
}
},
animationType: AnimationType.scale, animationType: AnimationType.scale,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
autoFocus: true, autoFocus: true,
@ -80,4 +57,29 @@ class _PinDialogState extends State<PinDialog> {
), ),
); );
} }
void _submit(String pin) {
if (widget.needConfirmation) {
if (_confirming) {
final match = _firstPin == pin;
Navigator.maybeOf(context)?.pop<String>(match ? pin : null);
if (!match) {
showDialog(
context: context,
builder: (context) => AvesDialog(
content: Text(context.l10n.genericFailureFeedback),
actions: const [OkButton()],
),
routeSettings: const RouteSettings(name: AvesDialog.warningRouteName),
);
}
} else {
_firstPin = pin;
_controller.clear();
setState(() => _confirming = true);
}
} else {
Navigator.maybeOf(context)?.pop<String>(pin);
}
}
} }

View file

@ -853,6 +853,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
pattern_lock:
dependency: "direct main"
description:
name: pattern_lock
sha256: "7929f877bcc82744ba2c0d55aaad1ff7cf09744f516b4853363fd29a1d7f539f"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
pdf: pdf:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -80,6 +80,7 @@ dependencies:
url: https://github.com/deckerst/aves_panorama.git url: https://github.com/deckerst/aves_panorama.git
ref: aves ref: aves
path: path:
pattern_lock:
pdf: pdf:
percent_indicator: percent_indicator:
permission_handler: permission_handler:

View file

@ -136,6 +136,7 @@
"themeBrightnessBlack", "themeBrightnessBlack",
"unitSystemMetric", "unitSystemMetric",
"unitSystemImperial", "unitSystemImperial",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"videoControlsPlay", "videoControlsPlay",
@ -195,6 +196,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -688,6 +691,7 @@
"themeBrightnessBlack", "themeBrightnessBlack",
"unitSystemMetric", "unitSystemMetric",
"unitSystemImperial", "unitSystemImperial",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"videoControlsPlay", "videoControlsPlay",
@ -747,6 +751,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -1170,6 +1176,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -1177,6 +1184,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -1200,6 +1209,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -1207,6 +1217,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -1224,12 +1236,27 @@
"el": [ "el": [
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"drawerPlacePage", "drawerPlacePage",
"placePageTitle", "placePageTitle",
"placeEmpty" "placeEmpty"
], ],
"es": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"eu": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"fa": [ "fa": [
"clearTooltip", "clearTooltip",
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
@ -1269,6 +1296,7 @@
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"nameConflictStrategySkip", "nameConflictStrategySkip",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"videoControlsNone", "videoControlsNone",
@ -1315,6 +1343,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -1698,6 +1728,12 @@
"filePickerUseThisFolder" "filePickerUseThisFolder"
], ],
"fr": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"gl": [ "gl": [
"columnCount", "columnCount",
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
@ -1731,6 +1767,7 @@
"themeBrightnessLight", "themeBrightnessLight",
"themeBrightnessDark", "themeBrightnessDark",
"themeBrightnessBlack", "themeBrightnessBlack",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"videoPlaybackSkip", "videoPlaybackSkip",
@ -1783,6 +1820,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -2353,6 +2392,7 @@
"themeBrightnessBlack", "themeBrightnessBlack",
"unitSystemMetric", "unitSystemMetric",
"unitSystemImperial", "unitSystemImperial",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"videoControlsPlay", "videoControlsPlay",
@ -2412,6 +2452,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -2827,10 +2869,19 @@
"filePickerUseThisFolder" "filePickerUseThisFolder"
], ],
"id": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"it": [ "it": [
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"drawerPlacePage", "drawerPlacePage",
"placePageTitle", "placePageTitle",
@ -2855,6 +2906,7 @@
"lengthUnitPercent", "lengthUnitPercent",
"subtitlePositionTop", "subtitlePositionTop",
"subtitlePositionBottom", "subtitlePositionBottom",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -2862,6 +2914,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -2884,6 +2938,12 @@
"settingsWidgetDisplayedItem" "settingsWidgetDisplayedItem"
], ],
"ko": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"lt": [ "lt": [
"columnCount", "columnCount",
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
@ -2896,6 +2956,7 @@
"keepScreenOnVideoPlayback", "keepScreenOnVideoPlayback",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -2903,6 +2964,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -2932,6 +2995,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -2939,6 +3003,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -2975,6 +3041,7 @@
"lengthUnitPercent", "lengthUnitPercent",
"subtitlePositionTop", "subtitlePositionTop",
"subtitlePositionBottom", "subtitlePositionBottom",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"widgetDisplayedItemRandom", "widgetDisplayedItemRandom",
@ -2984,6 +3051,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -3026,6 +3095,7 @@
"displayRefreshRatePreferLowest", "displayRefreshRatePreferLowest",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"wallpaperTargetHome", "wallpaperTargetHome",
@ -3036,6 +3106,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -3323,6 +3395,12 @@
"wallpaperUseScrollEffect" "wallpaperUseScrollEffect"
], ],
"pl": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"pt": [ "pt": [
"columnCount", "columnCount",
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
@ -3331,8 +3409,11 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
"patternDialogEnter",
"patternDialogConfirm",
"passwordDialogConfirm", "passwordDialogConfirm",
"authenticateToConfigureVault", "authenticateToConfigureVault",
"authenticateToUnlockVault", "authenticateToUnlockVault",
@ -3351,6 +3432,9 @@
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
"drawerPlacePage", "drawerPlacePage",
"placePageTitle", "placePageTitle",
@ -3363,6 +3447,9 @@
"filterLocatedLabel", "filterLocatedLabel",
"filterTaggedLabel", "filterTaggedLabel",
"lengthUnitPixel", "lengthUnitPixel",
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm",
"authenticateToConfigureVault", "authenticateToConfigureVault",
"authenticateToUnlockVault", "authenticateToUnlockVault",
"exportEntryDialogWriteMetadata", "exportEntryDialogWriteMetadata",
@ -3390,6 +3477,7 @@
"coordinateDms", "coordinateDms",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"otherDirectoryDescription", "otherDirectoryDescription",
@ -3404,6 +3492,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -3808,6 +3898,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -3815,6 +3906,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -4153,6 +4246,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -4160,6 +4254,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -4175,6 +4271,12 @@
"settingsDisablingBinWarningDialogMessage" "settingsDisablingBinWarningDialogMessage"
], ],
"uk": [
"vaultLockTypePattern",
"patternDialogEnter",
"patternDialogConfirm"
],
"zh": [ "zh": [
"chipActionGoToPlacePage", "chipActionGoToPlacePage",
"chipActionLock", "chipActionLock",
@ -4185,6 +4287,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -4192,6 +4295,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",
@ -4224,6 +4329,7 @@
"albumTierVaults", "albumTierVaults",
"lengthUnitPixel", "lengthUnitPixel",
"lengthUnitPercent", "lengthUnitPercent",
"vaultLockTypePattern",
"vaultLockTypePin", "vaultLockTypePin",
"vaultLockTypePassword", "vaultLockTypePassword",
"newVaultWarningDialogMessage", "newVaultWarningDialogMessage",
@ -4231,6 +4337,8 @@
"configureVaultDialogTitle", "configureVaultDialogTitle",
"vaultDialogLockModeWhenScreenOff", "vaultDialogLockModeWhenScreenOff",
"vaultDialogLockTypeLabel", "vaultDialogLockTypeLabel",
"patternDialogEnter",
"patternDialogConfirm",
"pinDialogEnter", "pinDialogEnter",
"pinDialogConfirm", "pinDialogConfirm",
"passwordDialogEnter", "passwordDialogEnter",