#533 places: page, navigation
This commit is contained in:
parent
300ce4f1bd
commit
af6fd8f11b
27 changed files with 505 additions and 91 deletions
|
@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## <a id="unreleased"></a>[Unreleased]
|
## <a id="unreleased"></a>[Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Places: page & navigation entry
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- replacing when moving item to vault
|
||||||
|
- exporting item to vault
|
||||||
|
|
||||||
## <a id="v1.8.1"></a>[v1.8.1] - 2023-02-21
|
## <a id="v1.8.1"></a>[v1.8.1] - 2023-02-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
"chipActionDelete": "Delete",
|
"chipActionDelete": "Delete",
|
||||||
"chipActionGoToAlbumPage": "Show in Albums",
|
"chipActionGoToAlbumPage": "Show in Albums",
|
||||||
"chipActionGoToCountryPage": "Show in Countries",
|
"chipActionGoToCountryPage": "Show in Countries",
|
||||||
|
"chipActionGoToPlacePage": "Show in Places",
|
||||||
"chipActionGoToTagPage": "Show in Tags",
|
"chipActionGoToTagPage": "Show in Tags",
|
||||||
"chipActionFilterOut": "Filter out",
|
"chipActionFilterOut": "Filter out",
|
||||||
"chipActionFilterIn": "Filter in",
|
"chipActionFilterIn": "Filter in",
|
||||||
|
@ -621,6 +622,7 @@
|
||||||
"drawerCollectionSphericalVideos": "360° Videos",
|
"drawerCollectionSphericalVideos": "360° Videos",
|
||||||
"drawerAlbumPage": "Albums",
|
"drawerAlbumPage": "Albums",
|
||||||
"drawerCountryPage": "Countries",
|
"drawerCountryPage": "Countries",
|
||||||
|
"drawerPlacePage": "Places",
|
||||||
"drawerTagPage": "Tags",
|
"drawerTagPage": "Tags",
|
||||||
|
|
||||||
"sortByDate": "By date",
|
"sortByDate": "By date",
|
||||||
|
@ -665,6 +667,9 @@
|
||||||
"countryPageTitle": "Countries",
|
"countryPageTitle": "Countries",
|
||||||
"countryEmpty": "No countries",
|
"countryEmpty": "No countries",
|
||||||
|
|
||||||
|
"placePageTitle": "Places",
|
||||||
|
"placeEmpty": "No places",
|
||||||
|
|
||||||
"tagPageTitle": "Tags",
|
"tagPageTitle": "Tags",
|
||||||
"tagEmpty": "No tags",
|
"tagEmpty": "No tags",
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
|
||||||
enum ChipAction {
|
enum ChipAction {
|
||||||
goToAlbumPage,
|
goToAlbumPage,
|
||||||
goToCountryPage,
|
goToCountryPage,
|
||||||
|
goToPlacePage,
|
||||||
goToTagPage,
|
goToTagPage,
|
||||||
reverse,
|
reverse,
|
||||||
hide,
|
hide,
|
||||||
|
@ -18,6 +19,8 @@ extension ExtraChipAction on ChipAction {
|
||||||
return context.l10n.chipActionGoToAlbumPage;
|
return context.l10n.chipActionGoToAlbumPage;
|
||||||
case ChipAction.goToCountryPage:
|
case ChipAction.goToCountryPage:
|
||||||
return context.l10n.chipActionGoToCountryPage;
|
return context.l10n.chipActionGoToCountryPage;
|
||||||
|
case ChipAction.goToPlacePage:
|
||||||
|
return context.l10n.chipActionGoToPlacePage;
|
||||||
case ChipAction.goToTagPage:
|
case ChipAction.goToTagPage:
|
||||||
return context.l10n.chipActionGoToTagPage;
|
return context.l10n.chipActionGoToTagPage;
|
||||||
case ChipAction.reverse:
|
case ChipAction.reverse:
|
||||||
|
@ -37,7 +40,9 @@ extension ExtraChipAction on ChipAction {
|
||||||
case ChipAction.goToAlbumPage:
|
case ChipAction.goToAlbumPage:
|
||||||
return AIcons.album;
|
return AIcons.album;
|
||||||
case ChipAction.goToCountryPage:
|
case ChipAction.goToCountryPage:
|
||||||
return AIcons.location;
|
return AIcons.country;
|
||||||
|
case ChipAction.goToPlacePage:
|
||||||
|
return AIcons.place;
|
||||||
case ChipAction.goToTagPage:
|
case ChipAction.goToTagPage:
|
||||||
return AIcons.tag;
|
return AIcons.tag;
|
||||||
case ChipAction.reverse:
|
case ChipAction.reverse:
|
||||||
|
|
|
@ -51,6 +51,8 @@ class LocationFilter extends CoveredCollectionFilter {
|
||||||
|
|
||||||
String? get countryCode => _countryCode;
|
String? get countryCode => _countryCode;
|
||||||
|
|
||||||
|
String get place => _location;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
EntryFilter get positiveTest => _test;
|
EntryFilter get positiveTest => _test;
|
||||||
|
|
||||||
|
@ -65,17 +67,25 @@ class LocationFilter extends CoveredCollectionFilter {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) {
|
||||||
if (_countryCode != null && device.canRenderFlagEmojis) {
|
if (_location.isEmpty) {
|
||||||
final flag = countryCodeToFlag(_countryCode);
|
return Icon(AIcons.locationUnlocated, size: size);
|
||||||
if (flag != null) {
|
}
|
||||||
return Text(
|
switch (level) {
|
||||||
flag,
|
case LocationLevel.place:
|
||||||
style: TextStyle(fontSize: size),
|
return Icon(AIcons.place, size: size);
|
||||||
textScaleFactor: 1.0,
|
case LocationLevel.country:
|
||||||
);
|
if (_countryCode != null && device.canRenderFlagEmojis) {
|
||||||
}
|
final flag = countryCodeToFlag(_countryCode);
|
||||||
|
if (flag != null) {
|
||||||
|
return Text(
|
||||||
|
flag,
|
||||||
|
style: TextStyle(fontSize: size),
|
||||||
|
textScaleFactor: 1.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Icon(AIcons.country, size: size);
|
||||||
}
|
}
|
||||||
return Icon(_location.isEmpty ? AIcons.locationUnlocated : AIcons.location, size: size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -23,8 +23,10 @@ class PlaceholderFilter extends CollectionFilter {
|
||||||
PlaceholderFilter._private(this.placeholder) : super(reversed: false) {
|
PlaceholderFilter._private(this.placeholder) : super(reversed: false) {
|
||||||
switch (placeholder) {
|
switch (placeholder) {
|
||||||
case _country:
|
case _country:
|
||||||
|
_icon = AIcons.country;
|
||||||
|
break;
|
||||||
case _place:
|
case _place:
|
||||||
_icon = AIcons.location;
|
_icon = AIcons.place;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:aves/model/settings/enums/enums.dart';
|
||||||
import 'package:aves/model/source/enums/enums.dart';
|
import 'package:aves/model/source/enums/enums.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ class SettingsDefaults {
|
||||||
static const drawerPageBookmarks = [
|
static const drawerPageBookmarks = [
|
||||||
AlbumListPage.routeName,
|
AlbumListPage.routeName,
|
||||||
CountryListPage.routeName,
|
CountryListPage.routeName,
|
||||||
|
PlaceListPage.routeName,
|
||||||
TagListPage.routeName,
|
TagListPage.routeName,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -65,6 +67,7 @@ class SettingsDefaults {
|
||||||
static const albumGroupFactor = AlbumChipGroupFactor.importance;
|
static const albumGroupFactor = AlbumChipGroupFactor.importance;
|
||||||
static const albumSortFactor = ChipSortFactor.name;
|
static const albumSortFactor = ChipSortFactor.name;
|
||||||
static const countrySortFactor = ChipSortFactor.name;
|
static const countrySortFactor = ChipSortFactor.name;
|
||||||
|
static const placeSortFactor = ChipSortFactor.name;
|
||||||
static const tagSortFactor = ChipSortFactor.name;
|
static const tagSortFactor = ChipSortFactor.name;
|
||||||
|
|
||||||
// viewer
|
// viewer
|
||||||
|
|
|
@ -18,10 +18,9 @@ extension ExtraThumbnailOverlayLocationIcon on ThumbnailOverlayLocationIcon {
|
||||||
|
|
||||||
IconData getIcon(BuildContext context) {
|
IconData getIcon(BuildContext context) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ThumbnailOverlayLocationIcon.located:
|
|
||||||
return AIcons.location;
|
|
||||||
case ThumbnailOverlayLocationIcon.unlocated:
|
case ThumbnailOverlayLocationIcon.unlocated:
|
||||||
return AIcons.locationUnlocated;
|
return AIcons.locationUnlocated;
|
||||||
|
case ThumbnailOverlayLocationIcon.located:
|
||||||
case ThumbnailOverlayLocationIcon.none:
|
case ThumbnailOverlayLocationIcon.none:
|
||||||
return AIcons.location;
|
return AIcons.location;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import 'package:aves/widgets/aves_app.dart';
|
||||||
import 'package:aves/widgets/common/search/page.dart';
|
import 'package:aves/widgets/common/search/page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:aves_map/aves_map.dart';
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
@ -106,9 +107,11 @@ class Settings extends ChangeNotifier {
|
||||||
static const albumGroupFactorKey = 'album_group_factor';
|
static const albumGroupFactorKey = 'album_group_factor';
|
||||||
static const albumSortFactorKey = 'album_sort_factor';
|
static const albumSortFactorKey = 'album_sort_factor';
|
||||||
static const countrySortFactorKey = 'country_sort_factor';
|
static const countrySortFactorKey = 'country_sort_factor';
|
||||||
|
static const placeSortFactorKey = 'place_sort_factor';
|
||||||
static const tagSortFactorKey = 'tag_sort_factor';
|
static const tagSortFactorKey = 'tag_sort_factor';
|
||||||
static const albumSortReverseKey = 'album_sort_reverse';
|
static const albumSortReverseKey = 'album_sort_reverse';
|
||||||
static const countrySortReverseKey = 'country_sort_reverse';
|
static const countrySortReverseKey = 'country_sort_reverse';
|
||||||
|
static const placeSortReverseKey = 'place_sort_reverse';
|
||||||
static const tagSortReverseKey = 'tag_sort_reverse';
|
static const tagSortReverseKey = 'tag_sort_reverse';
|
||||||
static const pinnedFiltersKey = 'pinned_filters';
|
static const pinnedFiltersKey = 'pinned_filters';
|
||||||
static const hiddenFiltersKey = 'hidden_filters';
|
static const hiddenFiltersKey = 'hidden_filters';
|
||||||
|
@ -265,6 +268,7 @@ class Settings extends ChangeNotifier {
|
||||||
drawerPageBookmarks = [
|
drawerPageBookmarks = [
|
||||||
AlbumListPage.routeName,
|
AlbumListPage.routeName,
|
||||||
CountryListPage.routeName,
|
CountryListPage.routeName,
|
||||||
|
PlaceListPage.routeName,
|
||||||
TagListPage.routeName,
|
TagListPage.routeName,
|
||||||
SearchPage.routeName,
|
SearchPage.routeName,
|
||||||
];
|
];
|
||||||
|
@ -543,6 +547,10 @@ class Settings extends ChangeNotifier {
|
||||||
|
|
||||||
set countrySortFactor(ChipSortFactor newValue) => _set(countrySortFactorKey, newValue.toString());
|
set countrySortFactor(ChipSortFactor newValue) => _set(countrySortFactorKey, newValue.toString());
|
||||||
|
|
||||||
|
ChipSortFactor get placeSortFactor => getEnumOrDefault(placeSortFactorKey, SettingsDefaults.placeSortFactor, 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.tagSortFactor, ChipSortFactor.values);
|
||||||
|
|
||||||
set tagSortFactor(ChipSortFactor newValue) => _set(tagSortFactorKey, newValue.toString());
|
set tagSortFactor(ChipSortFactor newValue) => _set(tagSortFactorKey, newValue.toString());
|
||||||
|
@ -555,6 +563,10 @@ class Settings extends ChangeNotifier {
|
||||||
|
|
||||||
set countrySortReverse(bool newValue) => _set(countrySortReverseKey, newValue);
|
set countrySortReverse(bool newValue) => _set(countrySortReverseKey, newValue);
|
||||||
|
|
||||||
|
bool get placeSortReverse => getBool(placeSortReverseKey) ?? false;
|
||||||
|
|
||||||
|
set placeSortReverse(bool newValue) => _set(placeSortReverseKey, newValue);
|
||||||
|
|
||||||
bool get tagSortReverse => getBool(tagSortReverseKey) ?? false;
|
bool get tagSortReverse => getBool(tagSortReverseKey) ?? false;
|
||||||
|
|
||||||
set tagSortReverse(bool newValue) => _set(tagSortReverseKey, newValue);
|
set tagSortReverse(bool newValue) => _set(tagSortReverseKey, newValue);
|
||||||
|
@ -1038,6 +1050,7 @@ class Settings extends ChangeNotifier {
|
||||||
case showThumbnailVideoDurationKey:
|
case showThumbnailVideoDurationKey:
|
||||||
case albumSortReverseKey:
|
case albumSortReverseKey:
|
||||||
case countrySortReverseKey:
|
case countrySortReverseKey:
|
||||||
|
case placeSortReverseKey:
|
||||||
case tagSortReverseKey:
|
case tagSortReverseKey:
|
||||||
case showOverlayOnOpeningKey:
|
case showOverlayOnOpeningKey:
|
||||||
case showOverlayMinimapKey:
|
case showOverlayMinimapKey:
|
||||||
|
@ -1084,6 +1097,7 @@ class Settings extends ChangeNotifier {
|
||||||
case albumGroupFactorKey:
|
case albumGroupFactorKey:
|
||||||
case albumSortFactorKey:
|
case albumSortFactorKey:
|
||||||
case countrySortFactorKey:
|
case countrySortFactorKey:
|
||||||
|
case placeSortFactorKey:
|
||||||
case tagSortFactorKey:
|
case tagSortFactorKey:
|
||||||
case imageBackgroundKey:
|
case imageBackgroundKey:
|
||||||
case videoAutoPlayModeKey:
|
case videoAutoPlayModeKey:
|
||||||
|
|
|
@ -14,7 +14,7 @@ import 'package:aves/model/filters/trash.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/model/source/events.dart';
|
import 'package:aves/model/source/events.dart';
|
||||||
import 'package:aves/model/source/location.dart';
|
import 'package:aves/model/source/location/location.dart';
|
||||||
import 'package:aves/model/source/section_keys.dart';
|
import 'package:aves/model/source/section_keys.dart';
|
||||||
import 'package:aves/model/source/tag.dart';
|
import 'package:aves/model/source/tag.dart';
|
||||||
import 'package:aves/utils/change_notifier.dart';
|
import 'package:aves/utils/change_notifier.dart';
|
||||||
|
|
|
@ -15,7 +15,9 @@ import 'package:aves/model/source/album.dart';
|
||||||
import 'package:aves/model/source/analysis_controller.dart';
|
import 'package:aves/model/source/analysis_controller.dart';
|
||||||
import 'package:aves/model/source/enums/enums.dart';
|
import 'package:aves/model/source/enums/enums.dart';
|
||||||
import 'package:aves/model/source/events.dart';
|
import 'package:aves/model/source/events.dart';
|
||||||
import 'package:aves/model/source/location.dart';
|
import 'package:aves/model/source/location/country.dart';
|
||||||
|
import 'package:aves/model/source/location/location.dart';
|
||||||
|
import 'package:aves/model/source/location/place.dart';
|
||||||
import 'package:aves/model/source/tag.dart';
|
import 'package:aves/model/source/tag.dart';
|
||||||
import 'package:aves/model/source/trash.dart';
|
import 'package:aves/model/source/trash.dart';
|
||||||
import 'package:aves/model/vaults/vaults.dart';
|
import 'package:aves/model/vaults/vaults.dart';
|
||||||
|
@ -54,7 +56,7 @@ mixin SourceBase {
|
||||||
void invalidateEntries();
|
void invalidateEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagMixin, TrashMixin {
|
abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, PlaceMixin, LocationMixin, TagMixin, TrashMixin {
|
||||||
CollectionSource() {
|
CollectionSource() {
|
||||||
settings.updateStream.where((event) => event.key == Settings.localeKey).listen((_) => invalidateAlbumDisplayNames());
|
settings.updateStream.where((event) => event.key == Settings.localeKey).listen((_) => invalidateAlbumDisplayNames());
|
||||||
settings.updateStream.where((event) => event.key == Settings.hiddenFiltersKey).listen((event) {
|
settings.updateStream.where((event) => event.key == Settings.hiddenFiltersKey).listen((event) {
|
||||||
|
@ -136,6 +138,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
|
||||||
invalidateEntries();
|
invalidateEntries();
|
||||||
invalidateAlbumFilterSummary(entries: entries, notify: notify);
|
invalidateAlbumFilterSummary(entries: entries, notify: notify);
|
||||||
invalidateCountryFilterSummary(entries: entries, notify: notify);
|
invalidateCountryFilterSummary(entries: entries, notify: notify);
|
||||||
|
invalidatePlaceFilterSummary(entries: entries, notify: notify);
|
||||||
invalidateTagFilterSummary(entries: entries, notify: notify);
|
invalidateTagFilterSummary(entries: entries, notify: notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,21 +504,42 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
|
||||||
|
|
||||||
int count(CollectionFilter filter) {
|
int count(CollectionFilter filter) {
|
||||||
if (filter is AlbumFilter) return albumEntryCount(filter);
|
if (filter is AlbumFilter) return albumEntryCount(filter);
|
||||||
if (filter is LocationFilter) return countryEntryCount(filter);
|
if (filter is LocationFilter) {
|
||||||
|
switch (filter.level) {
|
||||||
|
case LocationLevel.country:
|
||||||
|
return countryEntryCount(filter);
|
||||||
|
case LocationLevel.place:
|
||||||
|
return placeEntryCount(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (filter is TagFilter) return tagEntryCount(filter);
|
if (filter is TagFilter) return tagEntryCount(filter);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int size(CollectionFilter filter) {
|
int size(CollectionFilter filter) {
|
||||||
if (filter is AlbumFilter) return albumSize(filter);
|
if (filter is AlbumFilter) return albumSize(filter);
|
||||||
if (filter is LocationFilter) return countrySize(filter);
|
if (filter is LocationFilter) {
|
||||||
|
switch (filter.level) {
|
||||||
|
case LocationLevel.country:
|
||||||
|
return countrySize(filter);
|
||||||
|
case LocationLevel.place:
|
||||||
|
return placeSize(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (filter is TagFilter) return tagSize(filter);
|
if (filter is TagFilter) return tagSize(filter);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvesEntry? recentEntry(CollectionFilter filter) {
|
AvesEntry? recentEntry(CollectionFilter filter) {
|
||||||
if (filter is AlbumFilter) return albumRecentEntry(filter);
|
if (filter is AlbumFilter) return albumRecentEntry(filter);
|
||||||
if (filter is LocationFilter) return countryRecentEntry(filter);
|
if (filter is LocationFilter) {
|
||||||
|
switch (filter.level) {
|
||||||
|
case LocationLevel.country:
|
||||||
|
return countryRecentEntry(filter);
|
||||||
|
case LocationLevel.place:
|
||||||
|
return placeRecentEntry(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (filter is TagFilter) return tagRecentEntry(filter);
|
if (filter is TagFilter) return tagRecentEntry(filter);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
66
lib/model/source/location/country.dart
Normal file
66
lib/model/source/location/country.dart
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
import 'package:aves/model/entry.dart';
|
||||||
|
import 'package:aves/model/filters/location.dart';
|
||||||
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
|
import 'package:aves/utils/collection_utils.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
|
mixin CountryMixin on SourceBase {
|
||||||
|
// filter summary
|
||||||
|
|
||||||
|
// by country code
|
||||||
|
final Map<String, int> _filterEntryCountMap = {}, _filterSizeMap = {};
|
||||||
|
final Map<String, AvesEntry?> _filterRecentEntryMap = {};
|
||||||
|
|
||||||
|
void invalidateCountryFilterSummary({
|
||||||
|
Set<AvesEntry>? entries,
|
||||||
|
Set<String>? countryCodes,
|
||||||
|
bool notify = true,
|
||||||
|
}) {
|
||||||
|
if (_filterEntryCountMap.isEmpty && _filterSizeMap.isEmpty && _filterRecentEntryMap.isEmpty) return;
|
||||||
|
|
||||||
|
if (entries == null && countryCodes == null) {
|
||||||
|
_filterEntryCountMap.clear();
|
||||||
|
_filterSizeMap.clear();
|
||||||
|
_filterRecentEntryMap.clear();
|
||||||
|
} else {
|
||||||
|
countryCodes ??= {};
|
||||||
|
if (entries != null) {
|
||||||
|
countryCodes.addAll(entries.where((entry) => entry.hasAddress).map((entry) => entry.addressDetails?.countryCode).whereNotNull());
|
||||||
|
}
|
||||||
|
countryCodes.forEach((countryCode) {
|
||||||
|
_filterEntryCountMap.remove(countryCode);
|
||||||
|
_filterSizeMap.remove(countryCode);
|
||||||
|
_filterRecentEntryMap.remove(countryCode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (notify) {
|
||||||
|
eventBus.fire(CountrySummaryInvalidatedEvent(countryCodes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int countryEntryCount(LocationFilter filter) {
|
||||||
|
final countryCode = filter.countryCode;
|
||||||
|
if (countryCode == null) return 0;
|
||||||
|
return _filterEntryCountMap.putIfAbsent(countryCode, () => visibleEntries.where(filter.test).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int countrySize(LocationFilter filter) {
|
||||||
|
final countryCode = filter.countryCode;
|
||||||
|
if (countryCode == null) return 0;
|
||||||
|
return _filterSizeMap.putIfAbsent(countryCode, () => visibleEntries.where(filter.test).map((v) => v.sizeBytes).sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
AvesEntry? countryRecentEntry(LocationFilter filter) {
|
||||||
|
final countryCode = filter.countryCode;
|
||||||
|
if (countryCode == null) return null;
|
||||||
|
return _filterRecentEntryMap.putIfAbsent(countryCode, () => sortedEntriesByDate.firstWhereOrNull(filter.test));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CountriesChangedEvent {}
|
||||||
|
|
||||||
|
class CountrySummaryInvalidatedEvent {
|
||||||
|
final Set<String>? countryCodes;
|
||||||
|
|
||||||
|
const CountrySummaryInvalidatedEvent(this.countryCodes);
|
||||||
|
}
|
|
@ -6,15 +6,15 @@ import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/metadata/address.dart';
|
import 'package:aves/model/metadata/address.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
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_source.dart';
|
|
||||||
import 'package:aves/model/source/enums/enums.dart';
|
import 'package:aves/model/source/enums/enums.dart';
|
||||||
|
import 'package:aves/model/source/location/country.dart';
|
||||||
|
import 'package:aves/model/source/location/place.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/utils/collection_utils.dart';
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
mixin LocationMixin on SourceBase {
|
mixin LocationMixin on CountryMixin, PlaceMixin {
|
||||||
static const commitCountThreshold = 200;
|
static const commitCountThreshold = 200;
|
||||||
static const _stopCheckCountThreshold = 50;
|
static const _stopCheckCountThreshold = 50;
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ mixin LocationMixin on SourceBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateLocations() {
|
void updateLocations() {
|
||||||
final locations = visibleEntries.where((entry) => entry.hasAddress).map((entry) => entry.addressDetails).whereNotNull().toList();
|
final locations = visibleEntries.map((entry) => entry.addressDetails).whereNotNull().toList();
|
||||||
final updatedPlaces = locations.map((address) => address.place).whereNotNull().where((v) => v.isNotEmpty).toSet().toList()..sort(compareAsciiUpperCase);
|
final updatedPlaces = locations.map((address) => address.place).whereNotNull().where((v) => v.isNotEmpty).toSet().toList()..sort(compareAsciiUpperCase);
|
||||||
if (!listEquals(updatedPlaces, sortedPlaces)) {
|
if (!listEquals(updatedPlaces, sortedPlaces)) {
|
||||||
sortedPlaces = List.unmodifiable(updatedPlaces);
|
sortedPlaces = List.unmodifiable(updatedPlaces);
|
||||||
|
@ -177,67 +177,6 @@ mixin LocationMixin on SourceBase {
|
||||||
eventBus.fire(CountriesChangedEvent());
|
eventBus.fire(CountriesChangedEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter summary
|
|
||||||
|
|
||||||
// by country code
|
|
||||||
final Map<String, int> _filterEntryCountMap = {}, _filterSizeMap = {};
|
|
||||||
final Map<String, AvesEntry?> _filterRecentEntryMap = {};
|
|
||||||
|
|
||||||
void invalidateCountryFilterSummary({
|
|
||||||
Set<AvesEntry>? entries,
|
|
||||||
Set<String>? countryCodes,
|
|
||||||
bool notify = true,
|
|
||||||
}) {
|
|
||||||
if (_filterEntryCountMap.isEmpty && _filterSizeMap.isEmpty && _filterRecentEntryMap.isEmpty) return;
|
|
||||||
|
|
||||||
if (entries == null && countryCodes == null) {
|
|
||||||
_filterEntryCountMap.clear();
|
|
||||||
_filterSizeMap.clear();
|
|
||||||
_filterRecentEntryMap.clear();
|
|
||||||
} else {
|
|
||||||
countryCodes ??= {};
|
|
||||||
if (entries != null) {
|
|
||||||
countryCodes.addAll(entries.where((entry) => entry.hasAddress).map((entry) => entry.addressDetails?.countryCode).whereNotNull());
|
|
||||||
}
|
|
||||||
countryCodes.forEach((countryCode) {
|
|
||||||
_filterEntryCountMap.remove(countryCode);
|
|
||||||
_filterSizeMap.remove(countryCode);
|
|
||||||
_filterRecentEntryMap.remove(countryCode);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (notify) {
|
|
||||||
eventBus.fire(CountrySummaryInvalidatedEvent(countryCodes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int countryEntryCount(LocationFilter filter) {
|
|
||||||
final countryCode = filter.countryCode;
|
|
||||||
if (countryCode == null) return 0;
|
|
||||||
return _filterEntryCountMap.putIfAbsent(countryCode, () => visibleEntries.where(filter.test).length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int countrySize(LocationFilter filter) {
|
|
||||||
final countryCode = filter.countryCode;
|
|
||||||
if (countryCode == null) return 0;
|
|
||||||
return _filterSizeMap.putIfAbsent(countryCode, () => visibleEntries.where(filter.test).map((v) => v.sizeBytes).sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
AvesEntry? countryRecentEntry(LocationFilter filter) {
|
|
||||||
final countryCode = filter.countryCode;
|
|
||||||
if (countryCode == null) return null;
|
|
||||||
return _filterRecentEntryMap.putIfAbsent(countryCode, () => sortedEntriesByDate.firstWhereOrNull(filter.test));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddressMetadataChangedEvent {}
|
class AddressMetadataChangedEvent {}
|
||||||
|
|
||||||
class PlacesChangedEvent {}
|
|
||||||
|
|
||||||
class CountriesChangedEvent {}
|
|
||||||
|
|
||||||
class CountrySummaryInvalidatedEvent {
|
|
||||||
final Set<String>? countryCodes;
|
|
||||||
|
|
||||||
const CountrySummaryInvalidatedEvent(this.countryCodes);
|
|
||||||
}
|
|
60
lib/model/source/location/place.dart
Normal file
60
lib/model/source/location/place.dart
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import 'package:aves/model/entry.dart';
|
||||||
|
import 'package:aves/model/filters/location.dart';
|
||||||
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
|
import 'package:aves/utils/collection_utils.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
|
mixin PlaceMixin on SourceBase {
|
||||||
|
// filter summary
|
||||||
|
|
||||||
|
// by place
|
||||||
|
final Map<String, int> _filterEntryCountMap = {}, _filterSizeMap = {};
|
||||||
|
final Map<String, AvesEntry?> _filterRecentEntryMap = {};
|
||||||
|
|
||||||
|
void invalidatePlaceFilterSummary({
|
||||||
|
Set<AvesEntry>? entries,
|
||||||
|
Set<String>? places,
|
||||||
|
bool notify = true,
|
||||||
|
}) {
|
||||||
|
if (_filterEntryCountMap.isEmpty && _filterSizeMap.isEmpty && _filterRecentEntryMap.isEmpty) return;
|
||||||
|
|
||||||
|
if (entries == null && places == null) {
|
||||||
|
_filterEntryCountMap.clear();
|
||||||
|
_filterSizeMap.clear();
|
||||||
|
_filterRecentEntryMap.clear();
|
||||||
|
} else {
|
||||||
|
places ??= {};
|
||||||
|
if (entries != null) {
|
||||||
|
places.addAll(entries.map((entry) => entry.addressDetails?.place).whereNotNull());
|
||||||
|
}
|
||||||
|
places.forEach((place) {
|
||||||
|
_filterEntryCountMap.remove(place);
|
||||||
|
_filterSizeMap.remove(place);
|
||||||
|
_filterRecentEntryMap.remove(place);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (notify) {
|
||||||
|
eventBus.fire(PlaceSummaryInvalidatedEvent(places));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int placeEntryCount(LocationFilter filter) {
|
||||||
|
return _filterEntryCountMap.putIfAbsent(filter.place, () => visibleEntries.where(filter.test).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int placeSize(LocationFilter filter) {
|
||||||
|
return _filterSizeMap.putIfAbsent(filter.place, () => visibleEntries.where(filter.test).map((v) => v.sizeBytes).sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
AvesEntry? placeRecentEntry(LocationFilter filter) {
|
||||||
|
return _filterRecentEntryMap.putIfAbsent(filter.place, () => sortedEntriesByDate.firstWhereOrNull(filter.test));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlacesChangedEvent {}
|
||||||
|
|
||||||
|
class PlaceSummaryInvalidatedEvent {
|
||||||
|
final Set<String>? places;
|
||||||
|
|
||||||
|
const PlaceSummaryInvalidatedEvent(this.places);
|
||||||
|
}
|
|
@ -36,6 +36,8 @@ class AIcons {
|
||||||
static const IconData language = Icons.translate_outlined;
|
static const IconData language = Icons.translate_outlined;
|
||||||
static const IconData location = Icons.place_outlined;
|
static const IconData location = Icons.place_outlined;
|
||||||
static const IconData locationUnlocated = Icons.location_off_outlined;
|
static const IconData locationUnlocated = Icons.location_off_outlined;
|
||||||
|
static const IconData country = Icons.flag_outlined;
|
||||||
|
static const IconData place = Icons.place_outlined;
|
||||||
static const IconData mainStorage = Icons.smartphone_outlined;
|
static const IconData mainStorage = Icons.smartphone_outlined;
|
||||||
static const IconData mimeType = Icons.code_outlined;
|
static const IconData mimeType = Icons.code_outlined;
|
||||||
static const IconData opacity = Icons.opacity;
|
static const IconData opacity = Icons.opacity;
|
||||||
|
|
|
@ -96,6 +96,7 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
final actions = [
|
final actions = [
|
||||||
if (filter is AlbumFilter) ChipAction.goToAlbumPage,
|
if (filter is AlbumFilter) ChipAction.goToAlbumPage,
|
||||||
if ((filter is LocationFilter && filter.level == LocationLevel.country)) ChipAction.goToCountryPage,
|
if ((filter is LocationFilter && filter.level == LocationLevel.country)) ChipAction.goToCountryPage,
|
||||||
|
if ((filter is LocationFilter && filter.level == LocationLevel.place)) ChipAction.goToPlacePage,
|
||||||
if (filter is TagFilter) ChipAction.goToTagPage,
|
if (filter is TagFilter) ChipAction.goToTagPage,
|
||||||
ChipAction.reverse,
|
ChipAction.reverse,
|
||||||
ChipAction.hide,
|
ChipAction.hide,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/widgets/collection/collection_page.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
|
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:aves/widgets/viewer/info/common.dart';
|
import 'package:aves/widgets/viewer/info/common.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -51,6 +52,7 @@ class DebugSettingsSection extends StatelessWidget {
|
||||||
'tileExtent - Collection': '${settings.getTileExtent(CollectionPage.routeName)}',
|
'tileExtent - Collection': '${settings.getTileExtent(CollectionPage.routeName)}',
|
||||||
'tileExtent - Albums': '${settings.getTileExtent(AlbumListPage.routeName)}',
|
'tileExtent - Albums': '${settings.getTileExtent(AlbumListPage.routeName)}',
|
||||||
'tileExtent - Countries': '${settings.getTileExtent(CountryListPage.routeName)}',
|
'tileExtent - Countries': '${settings.getTileExtent(CountryListPage.routeName)}',
|
||||||
|
'tileExtent - Places': '${settings.getTileExtent(PlaceListPage.routeName)}',
|
||||||
'tileExtent - Tags': '${settings.getTileExtent(TagListPage.routeName)}',
|
'tileExtent - Tags': '${settings.getTileExtent(TagListPage.routeName)}',
|
||||||
'infoMapZoom': '${settings.infoMapZoom}',
|
'infoMapZoom': '${settings.infoMapZoom}',
|
||||||
'collectionSelectionQuickActions': '${settings.collectionSelectionQuickActions}',
|
'collectionSelectionQuickActions': '${settings.collectionSelectionQuickActions}',
|
||||||
|
|
|
@ -11,6 +11,7 @@ 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/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -23,6 +24,7 @@ class ChipActionDelegate with FeedbackMixin, VaultAwareMixin {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ChipAction.goToAlbumPage:
|
case ChipAction.goToAlbumPage:
|
||||||
case ChipAction.goToCountryPage:
|
case ChipAction.goToCountryPage:
|
||||||
|
case ChipAction.goToPlacePage:
|
||||||
case ChipAction.goToTagPage:
|
case ChipAction.goToTagPage:
|
||||||
case ChipAction.reverse:
|
case ChipAction.reverse:
|
||||||
return true;
|
return true;
|
||||||
|
@ -42,6 +44,9 @@ class ChipActionDelegate with FeedbackMixin, VaultAwareMixin {
|
||||||
case ChipAction.goToCountryPage:
|
case ChipAction.goToCountryPage:
|
||||||
_goTo(context, filter, CountryListPage.routeName, (context) => const CountryListPage());
|
_goTo(context, filter, CountryListPage.routeName, (context) => const CountryListPage());
|
||||||
break;
|
break;
|
||||||
|
case ChipAction.goToPlacePage:
|
||||||
|
_goTo(context, filter, PlaceListPage.routeName, (context) => const PlaceListPage());
|
||||||
|
break;
|
||||||
case ChipAction.goToTagPage:
|
case ChipAction.goToTagPage:
|
||||||
_goTo(context, filter, TagListPage.routeName, (context) => const TagListPage());
|
_goTo(context, filter, TagListPage.routeName, (context) => const TagListPage());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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/places_page.dart';
|
||||||
|
|
||||||
|
class PlaceChipSetActionDelegate extends ChipSetActionDelegate<LocationFilter> {
|
||||||
|
final Iterable<FilterGridItem<LocationFilter>> _items;
|
||||||
|
|
||||||
|
PlaceChipSetActionDelegate(Iterable<FilterGridItem<LocationFilter>> items) : _items = items;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<FilterGridItem<LocationFilter>> get allItems => _items;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ChipSortFactor get sortFactor => settings.placeSortFactor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set sortFactor(ChipSortFactor factor) => settings.placeSortFactor = factor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get sortReverse => settings.placeSortReverse;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set sortReverse(bool value) => settings.placeSortReverse = value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
TileLayout get tileLayout => settings.getTileLayout(PlaceListPage.routeName);
|
||||||
|
|
||||||
|
@override
|
||||||
|
set tileLayout(TileLayout tileLayout) => settings.setTileLayout(PlaceListPage.routeName, tileLayout);
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/filters/tag.dart';
|
import 'package:aves/model/filters/tag.dart';
|
||||||
import 'package:aves/model/source/album.dart';
|
import 'package:aves/model/source/album.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/model/source/location.dart';
|
import 'package:aves/model/source/location/country.dart';
|
||||||
import 'package:aves/model/source/tag.dart';
|
import 'package:aves/model/source/tag.dart';
|
||||||
import 'package:aves/model/vaults/vaults.dart';
|
import 'package:aves/model/vaults/vaults.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/model/source/enums/enums.dart';
|
import 'package:aves/model/source/enums/enums.dart';
|
||||||
import 'package:aves/model/source/location.dart';
|
import 'package:aves/model/source/location/country.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';
|
||||||
import 'package:aves/widgets/common/identity/empty.dart';
|
import 'package:aves/widgets/common/identity/empty.dart';
|
||||||
|
@ -43,7 +43,7 @@ class CountryListPage extends StatelessWidget {
|
||||||
filterSections: _groupToSections(gridItems),
|
filterSections: _groupToSections(gridItems),
|
||||||
applyQuery: applyQuery,
|
applyQuery: applyQuery,
|
||||||
emptyBuilder: () => EmptyContent(
|
emptyBuilder: () => EmptyContent(
|
||||||
icon: AIcons.location,
|
icon: AIcons.country,
|
||||||
text: context.l10n.countryEmpty,
|
text: context.l10n.countryEmpty,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
80
lib/widgets/filter_grids/places_page.dart
Normal file
80
lib/widgets/filter_grids/places_page.dart
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
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/place_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 PlaceListPage extends StatelessWidget {
|
||||||
|
static const routeName = '/places';
|
||||||
|
|
||||||
|
const PlaceListPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final source = context.read<CollectionSource>();
|
||||||
|
return Selector<Settings, Tuple3<ChipSortFactor, bool, Set<CollectionFilter>>>(
|
||||||
|
selector: (context, s) => Tuple3(s.placeSortFactor, s.placeSortReverse, 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<PlacesChangedEvent>(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final gridItems = _getGridItems(source);
|
||||||
|
return FilterNavigationPage<LocationFilter, PlaceChipSetActionDelegate>(
|
||||||
|
source: source,
|
||||||
|
title: context.l10n.placePageTitle,
|
||||||
|
sortFactor: settings.placeSortFactor,
|
||||||
|
actionDelegate: PlaceChipSetActionDelegate(gridItems),
|
||||||
|
filterSections: _groupToSections(gridItems),
|
||||||
|
applyQuery: applyQuery,
|
||||||
|
emptyBuilder: () => EmptyContent(
|
||||||
|
icon: AIcons.place,
|
||||||
|
text: context.l10n.placeEmpty,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<FilterGridItem<LocationFilter>> applyQuery(BuildContext context, List<FilterGridItem<LocationFilter>> filters, String query) {
|
||||||
|
return filters.where((item) => item.filter.getLabel(context).toUpperCase().contains(query)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<FilterGridItem<LocationFilter>> _getGridItems(CollectionSource source) {
|
||||||
|
final filters = source.sortedPlaces.map((location) => LocationFilter(LocationLevel.place, location)).toSet();
|
||||||
|
|
||||||
|
return FilterNavigationPage.sort(settings.placeSortFactor, settings.placeSortReverse, source, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Map<ChipSectionKey, List<FilterGridItem<LocationFilter>>> _groupToSections(Iterable<FilterGridItem<LocationFilter>> sortedMapEntries) {
|
||||||
|
final pinned = settings.pinnedFilters.whereType<LocationFilter>();
|
||||||
|
final byPin = groupBy<FilterGridItem<LocationFilter>, 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,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,8 @@ import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/album.dart';
|
import 'package:aves/model/source/album.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/model/source/location.dart';
|
import 'package:aves/model/source/location/country.dart';
|
||||||
|
import 'package:aves/model/source/location/place.dart';
|
||||||
import 'package:aves/model/source/tag.dart';
|
import 'package:aves/model/source/tag.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
|
@ -19,6 +20,7 @@ import 'package:aves/widgets/common/identity/aves_logo.dart';
|
||||||
import 'package:aves/widgets/debug/app_debug_page.dart';
|
import 'package:aves/widgets/debug/app_debug_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:aves/widgets/navigation/drawer/collection_nav_tile.dart';
|
import 'package:aves/widgets/navigation/drawer/collection_nav_tile.dart';
|
||||||
import 'package:aves/widgets/navigation/drawer/page_nav_tile.dart';
|
import 'package:aves/widgets/navigation/drawer/page_nav_tile.dart';
|
||||||
|
@ -242,6 +244,12 @@ class _AppDrawerState extends State<AppDrawer> {
|
||||||
builder: (context, _) => Text('${source.sortedCountries.length}'),
|
builder: (context, _) => Text('${source.sortedCountries.length}'),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case PlaceListPage.routeName:
|
||||||
|
trailing = StreamBuilder(
|
||||||
|
stream: source.eventBus.on<PlacesChangedEvent>(),
|
||||||
|
builder: (context, _) => Text('${source.sortedPlaces.length}'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
case TagListPage.routeName:
|
case TagListPage.routeName:
|
||||||
trailing = StreamBuilder(
|
trailing = StreamBuilder(
|
||||||
stream: source.eventBus.on<TagsChangedEvent>(),
|
stream: source.eventBus.on<TagsChangedEvent>(),
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:aves/widgets/common/search/route.dart';
|
||||||
import 'package:aves/widgets/debug/app_debug_page.dart';
|
import 'package:aves/widgets/debug/app_debug_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:aves/widgets/navigation/drawer/tile.dart';
|
import 'package:aves/widgets/navigation/drawer/tile.dart';
|
||||||
import 'package:aves/widgets/search/search_delegate.dart';
|
import 'package:aves/widgets/search/search_delegate.dart';
|
||||||
|
@ -88,6 +89,8 @@ class PageNavTile extends StatelessWidget {
|
||||||
return (_) => const AlbumListPage();
|
return (_) => const AlbumListPage();
|
||||||
case CountryListPage.routeName:
|
case CountryListPage.routeName:
|
||||||
return (_) => const CountryListPage();
|
return (_) => const CountryListPage();
|
||||||
|
case PlaceListPage.routeName:
|
||||||
|
return (_) => const PlaceListPage();
|
||||||
case TagListPage.routeName:
|
case TagListPage.routeName:
|
||||||
return (_) => const TagListPage();
|
return (_) => const TagListPage();
|
||||||
case SettingsPage.routeName:
|
case SettingsPage.routeName:
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:aves/widgets/common/search/page.dart';
|
||||||
import 'package:aves/widgets/debug/app_debug_page.dart';
|
import 'package:aves/widgets/debug/app_debug_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:aves/widgets/settings/settings_page.dart';
|
import 'package:aves/widgets/settings/settings_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -35,6 +36,8 @@ class NavigationDisplay {
|
||||||
return l10n.drawerAlbumPage;
|
return l10n.drawerAlbumPage;
|
||||||
case CountryListPage.routeName:
|
case CountryListPage.routeName:
|
||||||
return l10n.drawerCountryPage;
|
return l10n.drawerCountryPage;
|
||||||
|
case PlaceListPage.routeName:
|
||||||
|
return l10n.drawerPlacePage;
|
||||||
case TagListPage.routeName:
|
case TagListPage.routeName:
|
||||||
return l10n.drawerTagPage;
|
return l10n.drawerTagPage;
|
||||||
case SettingsPage.routeName:
|
case SettingsPage.routeName:
|
||||||
|
@ -55,7 +58,9 @@ class NavigationDisplay {
|
||||||
case AlbumListPage.routeName:
|
case AlbumListPage.routeName:
|
||||||
return AIcons.album;
|
return AIcons.album;
|
||||||
case CountryListPage.routeName:
|
case CountryListPage.routeName:
|
||||||
return AIcons.location;
|
return AIcons.country;
|
||||||
|
case PlaceListPage.routeName:
|
||||||
|
return AIcons.place;
|
||||||
case TagListPage.routeName:
|
case TagListPage.routeName:
|
||||||
return AIcons.tag;
|
return AIcons.tag;
|
||||||
case SettingsPage.routeName:
|
case SettingsPage.routeName:
|
||||||
|
|
|
@ -15,7 +15,8 @@ import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/album.dart';
|
import 'package:aves/model/source/album.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/model/source/location.dart';
|
import 'package:aves/model/source/location/country.dart';
|
||||||
|
import 'package:aves/model/source/location/place.dart';
|
||||||
import 'package:aves/model/source/tag.dart';
|
import 'package:aves/model/source/tag.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/widgets/collection/collection_page.dart';
|
import 'package:aves/widgets/collection/collection_page.dart';
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/search/page.dart';
|
import 'package:aves/widgets/common/search/page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
import 'package:aves/widgets/filter_grids/countries_page.dart';
|
||||||
|
import 'package:aves/widgets/filter_grids/places_page.dart';
|
||||||
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
import 'package:aves/widgets/filter_grids/tags_page.dart';
|
||||||
import 'package:aves/widgets/navigation/drawer/app_drawer.dart';
|
import 'package:aves/widgets/navigation/drawer/app_drawer.dart';
|
||||||
import 'package:aves/widgets/navigation/drawer/tile.dart';
|
import 'package:aves/widgets/navigation/drawer/tile.dart';
|
||||||
|
@ -40,6 +41,7 @@ class _NavigationDrawerEditorPageState extends State<NavigationDrawerEditorPage>
|
||||||
static const Set<String> _pageOptions = {
|
static const Set<String> _pageOptions = {
|
||||||
AlbumListPage.routeName,
|
AlbumListPage.routeName,
|
||||||
CountryListPage.routeName,
|
CountryListPage.routeName,
|
||||||
|
PlaceListPage.routeName,
|
||||||
TagListPage.routeName,
|
TagListPage.routeName,
|
||||||
SearchPage.routeName,
|
SearchPage.routeName,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"chipActionDelete",
|
"chipActionDelete",
|
||||||
"chipActionGoToAlbumPage",
|
"chipActionGoToAlbumPage",
|
||||||
"chipActionGoToCountryPage",
|
"chipActionGoToCountryPage",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionGoToTagPage",
|
"chipActionGoToTagPage",
|
||||||
"chipActionFilterOut",
|
"chipActionFilterOut",
|
||||||
"chipActionFilterIn",
|
"chipActionFilterIn",
|
||||||
|
@ -334,6 +335,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -369,6 +371,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -591,6 +595,7 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"cs": [
|
"cs": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -609,11 +614,15 @@
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -632,11 +641,29 @@
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"el": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
|
"es": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"eu": [
|
"eu": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -655,12 +682,16 @@
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
"clearTooltip",
|
"clearTooltip",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -858,6 +889,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -892,6 +924,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -1120,8 +1154,16 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"gl": [
|
"gl": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -1344,6 +1386,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -1379,6 +1422,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -1646,6 +1691,7 @@
|
||||||
"chipActionDelete",
|
"chipActionDelete",
|
||||||
"chipActionGoToAlbumPage",
|
"chipActionGoToAlbumPage",
|
||||||
"chipActionGoToCountryPage",
|
"chipActionGoToCountryPage",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionGoToTagPage",
|
"chipActionGoToTagPage",
|
||||||
"chipActionFilterOut",
|
"chipActionFilterOut",
|
||||||
"chipActionFilterIn",
|
"chipActionFilterIn",
|
||||||
|
@ -1966,6 +2012,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -2001,6 +2048,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -2235,7 +2284,15 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"id": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2254,12 +2311,16 @@
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionFilterIn",
|
"chipActionFilterIn",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
|
@ -2288,6 +2349,9 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
|
@ -2298,8 +2362,16 @@
|
||||||
"settingsWidgetDisplayedItem"
|
"settingsWidgetDisplayedItem"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ko": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"lt": [
|
"lt": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2322,6 +2394,9 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
|
@ -2332,6 +2407,7 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"nb": [
|
"nb": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2350,12 +2426,16 @@
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nl": [
|
"nl": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2389,6 +2469,9 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
|
@ -2405,6 +2488,7 @@
|
||||||
"nn": [
|
"nn": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"sourceStateCataloguing",
|
"sourceStateCataloguing",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2504,6 +2588,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -2539,6 +2624,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -2709,8 +2796,16 @@
|
||||||
"wallpaperUseScrollEffect"
|
"wallpaperUseScrollEffect"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"pl": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2730,12 +2825,23 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsVideoGestureVerticalDragBrightnessVolume",
|
"settingsVideoGestureVerticalDragBrightnessVolume",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ro": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2757,6 +2863,9 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsVideoGestureVerticalDragBrightnessVolume",
|
"settingsVideoGestureVerticalDragBrightnessVolume",
|
||||||
|
@ -2768,6 +2877,7 @@
|
||||||
"itemCount",
|
"itemCount",
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"timeSeconds",
|
"timeSeconds",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -2905,6 +3015,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -2940,6 +3051,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -3182,6 +3295,7 @@
|
||||||
"timeDays",
|
"timeDays",
|
||||||
"focalLength",
|
"focalLength",
|
||||||
"applyButtonLabel",
|
"applyButtonLabel",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -3250,6 +3364,7 @@
|
||||||
"drawerCollectionSphericalVideos",
|
"drawerCollectionSphericalVideos",
|
||||||
"drawerAlbumPage",
|
"drawerAlbumPage",
|
||||||
"drawerCountryPage",
|
"drawerCountryPage",
|
||||||
|
"drawerPlacePage",
|
||||||
"drawerTagPage",
|
"drawerTagPage",
|
||||||
"sortByDate",
|
"sortByDate",
|
||||||
"sortByName",
|
"sortByName",
|
||||||
|
@ -3285,6 +3400,8 @@
|
||||||
"newFilterBanner",
|
"newFilterBanner",
|
||||||
"countryPageTitle",
|
"countryPageTitle",
|
||||||
"countryEmpty",
|
"countryEmpty",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"tagPageTitle",
|
"tagPageTitle",
|
||||||
"tagEmpty",
|
"tagEmpty",
|
||||||
"binPageTitle",
|
"binPageTitle",
|
||||||
|
@ -3520,6 +3637,7 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -3538,11 +3656,22 @@
|
||||||
"authenticateToConfigureVault",
|
"authenticateToConfigureVault",
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsDisablingBinWarningDialogMessage"
|
"settingsDisablingBinWarningDialogMessage"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"uk": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty"
|
||||||
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -3564,6 +3693,9 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
|
@ -3575,6 +3707,7 @@
|
||||||
|
|
||||||
"zh_Hant": [
|
"zh_Hant": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"chipActionGoToPlacePage",
|
||||||
"chipActionLock",
|
"chipActionLock",
|
||||||
"chipActionCreateVault",
|
"chipActionCreateVault",
|
||||||
"chipActionConfigureVault",
|
"chipActionConfigureVault",
|
||||||
|
@ -3596,6 +3729,9 @@
|
||||||
"authenticateToUnlockVault",
|
"authenticateToUnlockVault",
|
||||||
"vaultBinUsageDialogMessage",
|
"vaultBinUsageDialogMessage",
|
||||||
"tooManyItemsErrorDialogMessage",
|
"tooManyItemsErrorDialogMessage",
|
||||||
|
"drawerPlacePage",
|
||||||
|
"placePageTitle",
|
||||||
|
"placeEmpty",
|
||||||
"settingsModificationWarningDialogMessage",
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsConfirmationVaultDataLoss",
|
"settingsConfirmationVaultDataLoss",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
|
|
Loading…
Reference in a new issue