diff --git a/lib/geo/states.dart b/lib/geo/states.dart index 01892ee5b..c7b01b3e8 100644 --- a/lib/geo/states.dart +++ b/lib/geo/states.dart @@ -2,12 +2,24 @@ import 'package:aves/ref/unicode.dart'; import 'package:country_code/country_code.dart'; class GeoStates { + static final aus = CountryCode.AU.alpha2; + static final gbr = CountryCode.GB.alpha2; + static final ind = CountryCode.IN.alpha2; + static final usa = CountryCode.US.alpha2; + static final Set stateCountryCodes = { - CountryCode.AU, - CountryCode.GB, - CountryCode.IN, - CountryCode.US, - }.map((v) => v.alpha2).toSet(); + aus, + gbr, + ind, + usa, + }; + + static final stateCodesByCountryCode = { + aus: EmojiStateCodes.aus, + gbr: EmojiStateCodes.gbr, + ind: EmojiStateCodes.ind, + usa: EmojiStateCodes.usa, + }; static const stateCodeByName = { ..._australiaEnglish, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index cd2b1a034..f28f4b79e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -84,6 +84,7 @@ "chipActionUnpin": "Unpin from top", "chipActionRename": "Rename", "chipActionSetCover": "Set cover", + "chipActionShowCountryStates": "Show states", "chipActionCreateAlbum": "Create album", "chipActionCreateVault": "Create vault", "chipActionConfigureVault": "Configure vault", @@ -679,6 +680,9 @@ "countryPageTitle": "Countries", "countryEmpty": "No countries", + "statePageTitle": "States", + "stateEmpty": "No states", + "placePageTitle": "Places", "placeEmpty": "No places", diff --git a/lib/model/actions/chip_set.dart b/lib/model/actions/chip_set.dart index 7e2efa418..c92be8892 100644 --- a/lib/model/actions/chip_set.dart +++ b/lib/model/actions/chip_set.dart @@ -23,6 +23,7 @@ enum ChipSetAction { pin, unpin, lockVault, + showCountryStates, // selecting (single filter) rename, setCover, @@ -57,6 +58,7 @@ class ChipSetActions { ChipSetAction.unpin, ChipSetAction.delete, ChipSetAction.rename, + ChipSetAction.showCountryStates, ChipSetAction.hide, null, ChipSetAction.map, @@ -108,6 +110,8 @@ extension ExtraChipSetAction on ChipSetAction { return context.l10n.chipActionUnpin; case ChipSetAction.lockVault: return context.l10n.chipActionLock; + case ChipSetAction.showCountryStates: + return context.l10n.chipActionShowCountryStates; // selecting (single filter) case ChipSetAction.rename: return context.l10n.chipActionRename; @@ -159,6 +163,8 @@ extension ExtraChipSetAction on ChipSetAction { return AIcons.unpin; case ChipSetAction.lockVault: return AIcons.vaultLock; + case ChipSetAction.showCountryStates: + return AIcons.state; // selecting (single filter) case ChipSetAction.rename: return AIcons.name; diff --git a/lib/model/settings/defaults.dart b/lib/model/settings/defaults.dart index 1c18f3d89..55d5db091 100644 --- a/lib/model/settings/defaults.dart +++ b/lib/model/settings/defaults.dart @@ -66,10 +66,7 @@ class SettingsDefaults { // filter grids static const albumGroupFactor = AlbumChipGroupFactor.importance; - static const albumSortFactor = ChipSortFactor.name; - static const countrySortFactor = ChipSortFactor.name; - static const placeSortFactor = ChipSortFactor.name; - static const tagSortFactor = ChipSortFactor.name; + static const chipListSortFactor = ChipSortFactor.name; // viewer static const viewerQuickActions = [ diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 0b57d64f5..09ef0332c 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -110,10 +110,12 @@ class Settings extends ChangeNotifier { static const albumGroupFactorKey = 'album_group_factor'; static const albumSortFactorKey = 'album_sort_factor'; static const countrySortFactorKey = 'country_sort_factor'; + static const stateSortFactorKey = 'state_sort_factor'; static const placeSortFactorKey = 'place_sort_factor'; static const tagSortFactorKey = 'tag_sort_factor'; static const albumSortReverseKey = 'album_sort_reverse'; static const countrySortReverseKey = 'country_sort_reverse'; + static const stateSortReverseKey = 'state_sort_reverse'; static const placeSortReverseKey = 'place_sort_reverse'; static const tagSortReverseKey = 'tag_sort_reverse'; static const pinnedFiltersKey = 'pinned_filters'; @@ -560,19 +562,23 @@ class Settings extends ChangeNotifier { set albumGroupFactor(AlbumChipGroupFactor newValue) => _set(albumGroupFactorKey, newValue.toString()); - ChipSortFactor get albumSortFactor => getEnumOrDefault(albumSortFactorKey, SettingsDefaults.albumSortFactor, ChipSortFactor.values); + ChipSortFactor get albumSortFactor => getEnumOrDefault(albumSortFactorKey, SettingsDefaults.chipListSortFactor, ChipSortFactor.values); set albumSortFactor(ChipSortFactor newValue) => _set(albumSortFactorKey, newValue.toString()); - ChipSortFactor get countrySortFactor => getEnumOrDefault(countrySortFactorKey, SettingsDefaults.countrySortFactor, ChipSortFactor.values); + ChipSortFactor get countrySortFactor => getEnumOrDefault(countrySortFactorKey, SettingsDefaults.chipListSortFactor, ChipSortFactor.values); set countrySortFactor(ChipSortFactor newValue) => _set(countrySortFactorKey, newValue.toString()); - ChipSortFactor get placeSortFactor => getEnumOrDefault(placeSortFactorKey, SettingsDefaults.placeSortFactor, ChipSortFactor.values); + ChipSortFactor get stateSortFactor => getEnumOrDefault(stateSortFactorKey, SettingsDefaults.chipListSortFactor, ChipSortFactor.values); + + set stateSortFactor(ChipSortFactor newValue) => _set(stateSortFactorKey, newValue.toString()); + + ChipSortFactor get placeSortFactor => getEnumOrDefault(placeSortFactorKey, SettingsDefaults.chipListSortFactor, ChipSortFactor.values); set placeSortFactor(ChipSortFactor newValue) => _set(placeSortFactorKey, newValue.toString()); - ChipSortFactor get tagSortFactor => getEnumOrDefault(tagSortFactorKey, SettingsDefaults.tagSortFactor, ChipSortFactor.values); + ChipSortFactor get tagSortFactor => getEnumOrDefault(tagSortFactorKey, SettingsDefaults.chipListSortFactor, ChipSortFactor.values); set tagSortFactor(ChipSortFactor newValue) => _set(tagSortFactorKey, newValue.toString()); @@ -584,6 +590,10 @@ class Settings extends ChangeNotifier { set countrySortReverse(bool newValue) => _set(countrySortReverseKey, newValue); + bool get stateSortReverse => getBool(stateSortReverseKey) ?? false; + + set stateSortReverse(bool newValue) => _set(stateSortReverseKey, newValue); + bool get placeSortReverse => getBool(placeSortReverseKey) ?? false; set placeSortReverse(bool newValue) => _set(placeSortReverseKey, newValue); @@ -1085,6 +1095,7 @@ class Settings extends ChangeNotifier { case showThumbnailVideoDurationKey: case albumSortReverseKey: case countrySortReverseKey: + case stateSortReverseKey: case placeSortReverseKey: case tagSortReverseKey: case showOverlayOnOpeningKey: @@ -1133,6 +1144,7 @@ class Settings extends ChangeNotifier { case albumGroupFactorKey: case albumSortFactorKey: case countrySortFactorKey: + case stateSortFactorKey: case placeSortFactorKey: case tagSortFactorKey: case imageBackgroundKey: diff --git a/lib/ref/unicode.dart b/lib/ref/unicode.dart index a3ecc32c6..9220d9fb2 100644 --- a/lib/ref/unicode.dart +++ b/lib/ref/unicode.dart @@ -34,12 +34,30 @@ class EmojiStateCodes { static const auVictoria = 'auvic'; static const auWesternAustralia = 'auwa'; + static const aus = { + auAustralianCapitalTerritory, + auNewSouthWales, + auNorthernTerritory, + auQueensland, + auSouthAustralia, + auTasmania, + auVictoria, + auWesternAustralia, + }; + // GB static const gbEngland = 'gbeng'; static const gbNorthernIreland = 'gbnir'; static const gbScotland = 'gbsct'; static const gbWales = 'gbwls'; + static const gbr = { + gbEngland, + gbNorthernIreland, + gbScotland, + gbWales, + }; + // IN static const inAndamanAndNicobarIslands = 'inan'; static const inAndhraPradesh = 'inap'; @@ -78,6 +96,45 @@ class EmojiStateCodes { static const inUttarakhand = 'inut'; static const inWestBengal = 'inwb'; + static const ind = { + inAndamanAndNicobarIslands, + inAndhraPradesh, + inArunachalPradesh, + inAssam, + inBihar, + inChandigarh, + inChhattisgarh, + inDamanAndDiu, + inDelhi, + inDadraAndNagarHaveli, + inGoa, + inGujarat, + inHimachalPradesh, + inHaryana, + inJharkhand, + inJammuAndKashmir, + inKarnataka, + inKerala, + inLakshadweep, + inMaharashtra, + inMeghalaya, + inManipur, + inMadhyaPradesh, + inMizoram, + inNagaland, + inOdisha, + inPunjab, + inPuducherry, + inRajasthan, + inSikkim, + inTelangana, + inTamilNadu, + inTripura, + inUttarPradesh, + inUttarakhand, + inWestBengal, + }; + // US static const usAlabama = 'usal'; static const usAlaska = 'usak'; @@ -129,4 +186,57 @@ class EmojiStateCodes { static const usWestVirginia = 'uswv'; static const usWisconsin = 'uswi'; static const usWyoming = 'uswy'; + + static const usa = { + usAlabama, + usAlaska, + usArizona, + usArkansas, + usCalifornia, + usColorado, + usConnecticut, + usDelaware, + usFlorida, + usGeorgia, + usHawaii, + usIdaho, + usIllinois, + usIndiana, + usIowa, + usKansas, + usKentucky, + usLouisiana, + usMaine, + usMaryland, + usMassachusetts, + usMichigan, + usMinnesota, + usMississippi, + usMissouri, + usMontana, + usNebraska, + usNevada, + usNewHampshire, + usNewJersey, + usNewMexico, + usNewYork, + usNorthCarolina, + usNorthDakota, + usOhio, + usOklahoma, + usOregon, + usPennsylvania, + usRhodeIsland, + usSouthCarolina, + usSouthDakota, + usTennessee, + usUtah, + usVermont, + usVirginia, + usWashington, + usWashingtonDC, + usWestVirginia, + usWisconsin, + usWyoming, + }; } diff --git a/lib/widgets/filter_grids/common/action_delegates/album_set.dart b/lib/widgets/filter_grids/common/action_delegates/album_set.dart index 49b8204ac..6e02dfa6b 100644 --- a/lib/widgets/filter_grids/common/action_delegates/album_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/album_set.dart @@ -8,7 +8,6 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/highlight.dart'; -import 'package:aves/model/selection.dart'; import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_source.dart'; @@ -162,7 +161,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with break; case ChipSetAction.lockVault: lockFilters(filters); - _browse(context); + browse(context); break; // single filter case ChipSetAction.rename: @@ -177,8 +176,6 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with super.onActionSelected(context, filters, action); } - void _browse(BuildContext context) => context.read>>().browse(); - @override Future configureView(BuildContext context) async { final initialValue = Tuple4( @@ -284,7 +281,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with filters: kv.value.toSet(), enableBin: kv.key, )); - _browse(context); + browse(context); } Future _doDelete({ @@ -308,7 +305,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with onSuccess: () { source.forgetNewAlbums(todoAlbums); source.cleanEmptyAlbums(emptyAlbums); - _browse(context); + browse(context); }, ); return; @@ -370,7 +367,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with final deletedOps = successOps.where((e) => !e.skipped).toSet(); final deletedUris = deletedOps.map((event) => event.uri).toSet(); await source.removeEntries(deletedUris, includeTrash: true); - _browse(context); + browse(context); source.resumeMonitoring(); final successCount = successOps.length; @@ -449,7 +446,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with final successOps = processed.where((e) => e.success).toSet(); final movedOps = successOps.where((e) => !e.skipped).toSet(); await source.renameAlbum(album, destinationAlbum, todoEntries, movedOps); - _browse(context); + browse(context); source.resumeMonitoring(); final successCount = successOps.length; @@ -495,7 +492,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with await _doRename(context, filter, newName); } else { await vaults.update(newDetails); - _browse(context); + browse(context); } } } diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index 85f6049db..76ea16b92 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -105,6 +105,7 @@ abstract class ChipSetActionDelegate with FeedbackMi return hasSelection && settings.pinnedFilters.containsAll(selectedFilters); case ChipSetAction.delete: case ChipSetAction.lockVault: + case ChipSetAction.showCountryStates: return false; // selecting (single filter) case ChipSetAction.setCover: @@ -148,6 +149,7 @@ abstract class ChipSetActionDelegate with FeedbackMi case ChipSetAction.pin: case ChipSetAction.unpin: case ChipSetAction.lockVault: + case ChipSetAction.showCountryStates: return hasSelection; // selecting (single filter) case ChipSetAction.rename: @@ -199,14 +201,15 @@ abstract class ChipSetActionDelegate with FeedbackMi break; case ChipSetAction.pin: settings.pinnedFilters = settings.pinnedFilters..addAll(filters); - _browse(context); + browse(context); break; case ChipSetAction.unpin: settings.pinnedFilters = settings.pinnedFilters..removeAll(filters); - _browse(context); + browse(context); break; case ChipSetAction.delete: case ChipSetAction.lockVault: + case ChipSetAction.showCountryStates: break; // selecting (single filter) case ChipSetAction.setCover: @@ -218,9 +221,7 @@ abstract class ChipSetActionDelegate with FeedbackMi } } - void _browse(BuildContext context) { - context.read>?>()?.browse(); - } + void browse(BuildContext context) => context.read>?>()?.browse(); Iterable _selectedEntries(BuildContext context, Set filters) { final source = context.read(); @@ -332,7 +333,7 @@ abstract class ChipSetActionDelegate with FeedbackMi settings.changeFilterVisibility(filters, false); - _browse(context); + browse(context); } void _setCover(BuildContext context, T filter) async { @@ -367,6 +368,6 @@ abstract class ChipSetActionDelegate with FeedbackMi color: selectedColor, ); - _browse(context); + browse(context); } } diff --git a/lib/widgets/filter_grids/common/action_delegates/country_set.dart b/lib/widgets/filter_grids/common/action_delegates/country_set.dart index 1e2ea6a31..ff2a22aac 100644 --- a/lib/widgets/filter_grids/common/action_delegates/country_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/country_set.dart @@ -1,9 +1,16 @@ +import 'package:aves/app_mode.dart'; +import 'package:aves/geo/states.dart'; +import 'package:aves/model/actions/chip_set.dart'; import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/location.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/enums/enums.dart'; +import 'package:aves/services/common/services.dart'; import 'package:aves/widgets/filter_grids/common/action_delegates/chip_set.dart'; import 'package:aves/widgets/filter_grids/countries_page.dart'; +import 'package:aves/widgets/filter_grids/states_page.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; class CountryChipSetActionDelegate extends ChipSetActionDelegate { final Iterable> _items; @@ -30,4 +37,71 @@ class CountryChipSetActionDelegate extends ChipSetActionDelegate @override set tileLayout(TileLayout tileLayout) => settings.setTileLayout(CountryListPage.routeName, tileLayout); + + @override + bool isVisible( + ChipSetAction action, { + required AppMode appMode, + required bool isSelecting, + required int itemCount, + required Set selectedFilters, + }) { + switch (action) { + case ChipSetAction.showCountryStates: + return isSelecting; + default: + return super.isVisible( + action, + appMode: appMode, + isSelecting: isSelecting, + itemCount: itemCount, + selectedFilters: selectedFilters, + ); + } + } + + @override + bool canApply( + ChipSetAction action, { + required bool isSelecting, + required int itemCount, + required Set selectedFilters, + }) { + switch (action) { + case ChipSetAction.showCountryStates: + return selectedFilters.any((v) => GeoStates.stateCountryCodes.contains(v.code)); + default: + return super.canApply( + action, + isSelecting: isSelecting, + itemCount: itemCount, + selectedFilters: selectedFilters, + ); + } + } + + @override + void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + reportService.log('$action'); + switch (action) { + // single/multiple filters + case ChipSetAction.showCountryStates: + _showStates(context, filters); + browse(context); + break; + default: + break; + } + super.onActionSelected(context, filters, action); + } + + void _showStates(BuildContext context, Set filters) { + final countryCodes = filters.map((v) => v.code).where(GeoStates.stateCountryCodes.contains).whereNotNull().toSet(); + Navigator.maybeOf(context)?.push( + MaterialPageRoute( + settings: const RouteSettings(name: StateListPage.routeName), + builder: (_) => StateListPage(countryCodes: countryCodes), + ), + ); + } } diff --git a/lib/widgets/filter_grids/common/action_delegates/state_set.dart b/lib/widgets/filter_grids/common/action_delegates/state_set.dart new file mode 100644 index 000000000..abe60d978 --- /dev/null +++ b/lib/widgets/filter_grids/common/action_delegates/state_set.dart @@ -0,0 +1,33 @@ +import 'package:aves/model/filters/filters.dart'; +import 'package:aves/model/filters/location.dart'; +import 'package:aves/model/settings/settings.dart'; +import 'package:aves/model/source/enums/enums.dart'; +import 'package:aves/widgets/filter_grids/common/action_delegates/chip_set.dart'; +import 'package:aves/widgets/filter_grids/states_page.dart'; + +class StateChipSetActionDelegate extends ChipSetActionDelegate { + final Iterable> _items; + + StateChipSetActionDelegate(Iterable> items) : _items = items; + + @override + Iterable> get allItems => _items; + + @override + ChipSortFactor get sortFactor => settings.stateSortFactor; + + @override + set sortFactor(ChipSortFactor factor) => settings.stateSortFactor = factor; + + @override + bool get sortReverse => settings.stateSortReverse; + + @override + set sortReverse(bool value) => settings.stateSortReverse = value; + + @override + TileLayout get tileLayout => settings.getTileLayout(StateListPage.routeName); + + @override + set tileLayout(TileLayout tileLayout) => settings.setTileLayout(StateListPage.routeName, tileLayout); +} diff --git a/lib/widgets/filter_grids/states_page.dart b/lib/widgets/filter_grids/states_page.dart new file mode 100644 index 000000000..c213518e0 --- /dev/null +++ b/lib/widgets/filter_grids/states_page.dart @@ -0,0 +1,87 @@ +import 'package:aves/geo/states.dart'; +import 'package:aves/model/filters/filters.dart'; +import 'package:aves/model/filters/location.dart'; +import 'package:aves/model/settings/settings.dart'; +import 'package:aves/model/source/collection_source.dart'; +import 'package:aves/model/source/enums/enums.dart'; +import 'package:aves/model/source/location/place.dart'; +import 'package:aves/theme/icons.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/common/identity/empty.dart'; +import 'package:aves/widgets/filter_grids/common/action_delegates/state_set.dart'; +import 'package:aves/widgets/filter_grids/common/filter_nav_page.dart'; +import 'package:aves/widgets/filter_grids/common/section_keys.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:tuple/tuple.dart'; + +class StateListPage extends StatelessWidget { + static const routeName = '/states'; + + final Set countryCodes; + + const StateListPage({ + super.key, + required this.countryCodes, + }); + + @override + Widget build(BuildContext context) { + final source = context.read(); + return Selector>>( + selector: (context, s) => Tuple3(s.stateSortFactor, s.stateSortReverse, s.pinnedFilters), + shouldRebuild: (t1, t2) { + // `Selector` by default uses `DeepCollectionEquality`, which does not go deep in collections within `TupleN` + const eq = DeepCollectionEquality(); + return !(eq.equals(t1.item1, t2.item1) && eq.equals(t1.item2, t2.item2) && eq.equals(t1.item3, t2.item3)); + }, + builder: (context, s, child) { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) { + final gridItems = _getGridItems(source); + return FilterNavigationPage( + source: source, + title: context.l10n.statePageTitle, + sortFactor: settings.stateSortFactor, + actionDelegate: StateChipSetActionDelegate(gridItems), + filterSections: _groupToSections(gridItems), + applyQuery: applyQuery, + emptyBuilder: () => EmptyContent( + icon: AIcons.state, + text: context.l10n.stateEmpty, + ), + ); + }, + ); + }, + ); + } + + List> applyQuery(BuildContext context, List> filters, String query) { + return filters.where((item) => item.filter.getLabel(context).toUpperCase().contains(query)).toList(); + } + + List> _getGridItems(CollectionSource source) { + final selectedStateCodes = countryCodes.expand((v) => GeoStates.stateCodesByCountryCode[v] ?? {}).toSet(); + final filters = source.sortedStates.where((v) => selectedStateCodes.any(v.endsWith)).map((location) => LocationFilter(LocationLevel.state, location)).toSet(); + + return FilterNavigationPage.sort(settings.stateSortFactor, settings.stateSortReverse, source, filters); + } + + static Map>> _groupToSections(Iterable> sortedMapEntries) { + final pinned = settings.pinnedFilters.whereType(); + final byPin = groupBy, bool>(sortedMapEntries, (e) => pinned.contains(e.filter)); + final pinnedMapEntries = (byPin[true] ?? []); + final unpinnedMapEntries = (byPin[false] ?? []); + + return { + if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty) + const ChipSectionKey(): [ + ...pinnedMapEntries, + ...unpinnedMapEntries, + ], + }; + } +} diff --git a/untranslated.json b/untranslated.json index 228df0282..768eb4cf6 100644 --- a/untranslated.json +++ b/untranslated.json @@ -24,6 +24,7 @@ "chipActionUnpin", "chipActionRename", "chipActionSetCover", + "chipActionShowCountryStates", "chipActionCreateAlbum", "chipActionCreateVault", "chipActionConfigureVault", @@ -380,6 +381,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -610,6 +613,7 @@ "ckb": [ "chipActionGoToPlacePage", + "chipActionShowCountryStates", "entryActionRotateCCW", "entryActionRotateCW", "entryActionFlip", @@ -943,6 +947,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -1185,9 +1191,12 @@ ], "cs": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", "settingsVideoEnablePip", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "settingsVideoBackgroundMode", @@ -1198,6 +1207,7 @@ "de": [ "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -1225,6 +1235,8 @@ "vaultBinUsageDialogMessage", "exportEntryDialogWriteMetadata", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsConfirmationVaultDataLoss", @@ -1238,6 +1250,7 @@ "el": [ "chipActionGoToPlacePage", + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", "vaultLockTypePattern", @@ -1246,6 +1259,8 @@ "patternDialogConfirm", "exportEntryDialogWriteMetadata", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsCollectionBurstPatternsTile", @@ -1256,16 +1271,22 @@ ], "es": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" ], "eu": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" @@ -1275,6 +1296,7 @@ "clearTooltip", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "videoActionPause", @@ -1515,6 +1537,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -1751,8 +1775,11 @@ ], "fr": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "tagPlaceholderState" ], @@ -1760,6 +1787,7 @@ "columnCount", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "entryActionShareImageOnly", @@ -2026,6 +2054,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -2310,6 +2340,7 @@ "chipActionUnpin", "chipActionRename", "chipActionSetCover", + "chipActionShowCountryStates", "chipActionCreateAlbum", "chipActionCreateVault", "chipActionConfigureVault", @@ -2666,6 +2697,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -2930,6 +2963,7 @@ "chipActionUnpin", "chipActionRename", "chipActionSetCover", + "chipActionShowCountryStates", "chipActionCreateAlbum", "chipActionCreateVault", "chipActionConfigureVault", @@ -3286,6 +3320,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -3528,16 +3564,22 @@ ], "id": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" ], "it": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" @@ -3548,6 +3590,7 @@ "chipActionGoToPlacePage", "chipActionFilterIn", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -3584,6 +3627,8 @@ "exportEntryDialogWriteMetadata", "tooManyItemsErrorDialogMessage", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsModificationWarningDialogMessage", @@ -3602,8 +3647,11 @@ ], "ko": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "tagPlaceholderState" ], @@ -3611,6 +3659,7 @@ "columnCount", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -3642,6 +3691,8 @@ "exportEntryDialogWriteMetadata", "tooManyItemsErrorDialogMessage", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsModificationWarningDialogMessage", @@ -3659,12 +3710,15 @@ ], "nb": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", "vaultLockTypePattern", "settingsVideoEnablePip", "patternDialogEnter", "patternDialogConfirm", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "settingsVideoBackgroundMode", @@ -3676,6 +3730,7 @@ "columnCount", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "entryActionShareImageOnly", @@ -3718,6 +3773,8 @@ "exportEntryDialogWriteMetadata", "tooManyItemsErrorDialogMessage", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsModificationWarningDialogMessage", @@ -3743,6 +3800,7 @@ "sourceStateCataloguing", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -3886,6 +3944,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -4064,16 +4124,22 @@ ], "pl": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" ], "pt": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "settingsVideoBackgroundModeDialogTitle", @@ -4081,8 +4147,11 @@ ], "ro": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" @@ -4090,6 +4159,7 @@ "ru": [ "chipActionLock", + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", "vaultLockTypePattern", @@ -4101,6 +4171,8 @@ "exportEntryDialogWriteMetadata", "tooManyItemsErrorDialogMessage", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placeEmpty", "settingsConfirmationVaultDataLoss", "settingsCollectionBurstPatternsTile", @@ -4117,6 +4189,7 @@ "timeSeconds", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -4298,6 +4371,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -4549,6 +4624,7 @@ "applyButtonLabel", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -4661,6 +4737,8 @@ "newFilterBanner", "countryPageTitle", "countryEmpty", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "tagPageTitle", @@ -4905,6 +4983,7 @@ "tr": [ "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -4932,6 +5011,8 @@ "vaultBinUsageDialogMessage", "exportEntryDialogWriteMetadata", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsConfirmationVaultDataLoss", @@ -4944,8 +5025,11 @@ ], "uk": [ + "chipActionShowCountryStates", "viewerActionLock", "viewerActionUnlock", + "statePageTitle", + "stateEmpty", "settingsCollectionBurstPatternsTile", "settingsCollectionBurstPatternsNone", "tagPlaceholderState" @@ -4954,6 +5038,7 @@ "zh": [ "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -4984,6 +5069,8 @@ "exportEntryDialogWriteMetadata", "tooManyItemsErrorDialogMessage", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsModificationWarningDialogMessage", @@ -5004,6 +5091,7 @@ "columnCount", "chipActionGoToPlacePage", "chipActionLock", + "chipActionShowCountryStates", "chipActionCreateVault", "chipActionConfigureVault", "viewerActionLock", @@ -5034,6 +5122,8 @@ "exportEntryDialogWriteMetadata", "tooManyItemsErrorDialogMessage", "drawerPlacePage", + "statePageTitle", + "stateEmpty", "placePageTitle", "placeEmpty", "settingsModificationWarningDialogMessage",