collection/albums/countries/tags: selection map/stats
This commit is contained in:
parent
f8337f6e3d
commit
be8f2754db
12 changed files with 241 additions and 145 deletions
|
@ -2,6 +2,8 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Map & Stats from selection
|
||||
|
||||
## [v1.4.8] - 2021-08-08
|
||||
### Added
|
||||
|
|
|
@ -321,6 +321,12 @@
|
|||
"@menuActionSort": {},
|
||||
"menuActionGroup": "Group",
|
||||
"@menuActionGroup": {},
|
||||
"menuActionSelect": "Select",
|
||||
"@menuActionSelect": {},
|
||||
"menuActionSelectAll": "Select all",
|
||||
"@menuActionSelectAll": {},
|
||||
"menuActionSelectNone": "Select none",
|
||||
"@menuActionSelectNone": {},
|
||||
"menuActionMap": "Map",
|
||||
"@menuActionMap": {},
|
||||
"menuActionStats": "Stats",
|
||||
|
@ -376,12 +382,6 @@
|
|||
|
||||
"collectionActionAddShortcut": "Add shortcut",
|
||||
"@collectionActionAddShortcut": {},
|
||||
"collectionActionSelect": "Select",
|
||||
"@collectionActionSelect": {},
|
||||
"collectionActionSelectAll": "Select all",
|
||||
"@collectionActionSelectAll": {},
|
||||
"collectionActionSelectNone": "Select none",
|
||||
"@collectionActionSelectNone": {},
|
||||
"collectionActionCopy": "Copy to album",
|
||||
"@collectionActionCopy": {},
|
||||
"collectionActionMove": "Move to album",
|
||||
|
|
|
@ -147,6 +147,9 @@
|
|||
|
||||
"menuActionSort": "정렬",
|
||||
"menuActionGroup": "묶음",
|
||||
"menuActionSelect": "선택",
|
||||
"menuActionSelectAll": "모두 선택",
|
||||
"menuActionSelectNone": "모두 해제",
|
||||
"menuActionMap": "지도",
|
||||
"menuActionStats": "통계",
|
||||
|
||||
|
@ -174,9 +177,6 @@
|
|||
"collectionSelectionPageTitle": "{count, plural, =0{항목 선택} other{{count}개}}",
|
||||
|
||||
"collectionActionAddShortcut": "홈 화면에 추가",
|
||||
"collectionActionSelect": "선택",
|
||||
"collectionActionSelectAll": "모두 선택",
|
||||
"collectionActionSelectNone": "모두 해제",
|
||||
"collectionActionCopy": "앨범으로 복사",
|
||||
"collectionActionMove": "앨범으로 이동",
|
||||
"collectionActionRefreshMetadata": "새로 분석",
|
||||
|
|
|
@ -6,18 +6,19 @@ enum ChipSetAction {
|
|||
// general
|
||||
sort,
|
||||
group,
|
||||
map,
|
||||
select,
|
||||
selectAll,
|
||||
selectNone,
|
||||
stats,
|
||||
createAlbum,
|
||||
// single/multiple filters
|
||||
// all or filter selection
|
||||
map,
|
||||
stats,
|
||||
// single/multiple filter selection
|
||||
delete,
|
||||
hide,
|
||||
pin,
|
||||
unpin,
|
||||
// single filter
|
||||
// single filter selection
|
||||
rename,
|
||||
setCover,
|
||||
}
|
||||
|
@ -31,11 +32,11 @@ extension ExtraChipSetAction on ChipSetAction {
|
|||
case ChipSetAction.group:
|
||||
return context.l10n.menuActionGroup;
|
||||
case ChipSetAction.select:
|
||||
return context.l10n.collectionActionSelect;
|
||||
return context.l10n.menuActionSelect;
|
||||
case ChipSetAction.selectAll:
|
||||
return context.l10n.collectionActionSelectAll;
|
||||
return context.l10n.menuActionSelectAll;
|
||||
case ChipSetAction.selectNone:
|
||||
return context.l10n.collectionActionSelectNone;
|
||||
return context.l10n.menuActionSelectNone;
|
||||
case ChipSetAction.map:
|
||||
return context.l10n.menuActionMap;
|
||||
case ChipSetAction.stats:
|
||||
|
@ -69,8 +70,9 @@ extension ExtraChipSetAction on ChipSetAction {
|
|||
case ChipSetAction.select:
|
||||
return AIcons.select;
|
||||
case ChipSetAction.selectAll:
|
||||
return AIcons.selected;
|
||||
case ChipSetAction.selectNone:
|
||||
return null;
|
||||
return AIcons.unselected;
|
||||
case ChipSetAction.map:
|
||||
return AIcons.map;
|
||||
case ChipSetAction.stats:
|
||||
|
|
|
@ -1,14 +1,85 @@
|
|||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
enum CollectionAction {
|
||||
addShortcut,
|
||||
// general
|
||||
sort,
|
||||
group,
|
||||
select,
|
||||
selectAll,
|
||||
selectNone,
|
||||
// all
|
||||
addShortcut,
|
||||
// all or entry selection
|
||||
map,
|
||||
stats,
|
||||
// apply to entry set
|
||||
// entry selection
|
||||
copy,
|
||||
move,
|
||||
refreshMetadata,
|
||||
}
|
||||
|
||||
extension ExtraCollectionAction on CollectionAction {
|
||||
String getText(BuildContext context) {
|
||||
switch (this) {
|
||||
// general
|
||||
case CollectionAction.sort:
|
||||
return context.l10n.menuActionSort;
|
||||
case CollectionAction.group:
|
||||
return context.l10n.menuActionGroup;
|
||||
case CollectionAction.select:
|
||||
return context.l10n.menuActionSelect;
|
||||
case CollectionAction.selectAll:
|
||||
return context.l10n.menuActionSelectAll;
|
||||
case CollectionAction.selectNone:
|
||||
return context.l10n.menuActionSelectNone;
|
||||
// all
|
||||
case CollectionAction.addShortcut:
|
||||
return context.l10n.collectionActionAddShortcut;
|
||||
// all or entry selection
|
||||
case CollectionAction.map:
|
||||
return context.l10n.menuActionMap;
|
||||
case CollectionAction.stats:
|
||||
return context.l10n.menuActionStats;
|
||||
// entry selection
|
||||
case CollectionAction.copy:
|
||||
return context.l10n.collectionActionCopy;
|
||||
case CollectionAction.move:
|
||||
return context.l10n.collectionActionMove;
|
||||
case CollectionAction.refreshMetadata:
|
||||
return context.l10n.collectionActionRefreshMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
IconData? getIcon() {
|
||||
switch (this) {
|
||||
// general
|
||||
case CollectionAction.sort:
|
||||
return AIcons.sort;
|
||||
case CollectionAction.group:
|
||||
return AIcons.group;
|
||||
case CollectionAction.select:
|
||||
return AIcons.select;
|
||||
case CollectionAction.selectAll:
|
||||
return AIcons.selected;
|
||||
case CollectionAction.selectNone:
|
||||
return AIcons.unselected;
|
||||
// all
|
||||
case CollectionAction.addShortcut:
|
||||
return AIcons.addShortcut;
|
||||
// all or entry selection
|
||||
case CollectionAction.map:
|
||||
return AIcons.map;
|
||||
case CollectionAction.stats:
|
||||
return AIcons.stats;
|
||||
// entry selection
|
||||
case CollectionAction.copy:
|
||||
return AIcons.copy;
|
||||
case CollectionAction.move:
|
||||
return AIcons.move;
|
||||
case CollectionAction.refreshMetadata:
|
||||
return AIcons.refresh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ class AIcons {
|
|||
static const IconData captureFrame = Icons.screenshot_outlined;
|
||||
static const IconData clear = Icons.clear_outlined;
|
||||
static const IconData clipboard = Icons.content_copy_outlined;
|
||||
static const IconData copy = Icons.file_copy_outlined;
|
||||
static const IconData createAlbum = Icons.add_circle_outline;
|
||||
static const IconData debug = Icons.whatshot_outlined;
|
||||
static const IconData delete = Icons.delete_outlined;
|
||||
|
@ -51,6 +52,7 @@ class AIcons {
|
|||
static const IconData info = Icons.info_outlined;
|
||||
static const IconData layers = Icons.layers_outlined;
|
||||
static const IconData map = Icons.map_outlined;
|
||||
static const IconData move = MdiIcons.fileMoveOutline;
|
||||
static const IconData newTier = Icons.fiber_new_outlined;
|
||||
static const IconData openOutside = Icons.open_in_new_outlined;
|
||||
static const IconData pin = Icons.push_pin_outlined;
|
||||
|
@ -58,6 +60,7 @@ class AIcons {
|
|||
static const IconData play = Icons.play_arrow;
|
||||
static const IconData pause = Icons.pause;
|
||||
static const IconData print = Icons.print_outlined;
|
||||
static const IconData refresh = Icons.refresh_outlined;
|
||||
static const IconData rename = Icons.title_outlined;
|
||||
static const IconData rotateLeft = Icons.rotate_left_outlined;
|
||||
static const IconData rotateRight = Icons.rotate_right_outlined;
|
||||
|
|
|
@ -12,7 +12,6 @@ import 'package:aves/model/source/collection_source.dart';
|
|||
import 'package:aves/model/source/enums.dart';
|
||||
import 'package:aves/services/app_shortcut_service.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/utils/pedantic.dart';
|
||||
import 'package:aves/widgets/collection/entry_set_action_delegate.dart';
|
||||
import 'package:aves/widgets/collection/filter_bar.dart';
|
||||
|
@ -22,10 +21,8 @@ import 'package:aves/widgets/common/basic/menu_row.dart';
|
|||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/dialogs/add_shortcut_dialog.dart';
|
||||
import 'package:aves/widgets/dialogs/aves_selection_dialog.dart';
|
||||
import 'package:aves/widgets/map/map_page.dart';
|
||||
import 'package:aves/widgets/search/search_button.dart';
|
||||
import 'package:aves/widgets/search/search_delegate.dart';
|
||||
import 'package:aves/widgets/stats/stats_page.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
@ -192,70 +189,55 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
return PopupMenuButton<CollectionAction>(
|
||||
key: const Key('appbar-menu-button'),
|
||||
itemBuilder: (context) {
|
||||
final groupable = collection.sortFactor == EntrySortFactor.date;
|
||||
final selection = context.read<Selection<AvesEntry>>();
|
||||
final isNotEmpty = !collection.isEmpty;
|
||||
final hasSelection = selection.selection.isNotEmpty;
|
||||
final isSelecting = selection.isSelecting;
|
||||
final selectedItems = selection.selection;
|
||||
final hasSelection = selectedItems.isNotEmpty;
|
||||
final hasItems = !collection.isEmpty;
|
||||
final otherViewEnabled = (!isSelecting && hasItems) || (isSelecting && hasSelection);
|
||||
|
||||
return [
|
||||
PopupMenuItem(
|
||||
_toMenuItem(
|
||||
CollectionAction.sort,
|
||||
key: const Key('menu-sort'),
|
||||
value: CollectionAction.sort,
|
||||
child: MenuRow(text: context.l10n.menuActionSort, icon: AIcons.sort),
|
||||
),
|
||||
if (collection.sortFactor == EntrySortFactor.date)
|
||||
PopupMenuItem(
|
||||
if (groupable)
|
||||
_toMenuItem(
|
||||
CollectionAction.group,
|
||||
key: const Key('menu-group'),
|
||||
value: CollectionAction.group,
|
||||
child: MenuRow(text: context.l10n.menuActionGroup, icon: AIcons.group),
|
||||
),
|
||||
if (!selection.isSelecting && appMode == AppMode.main) ...[
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.select,
|
||||
enabled: isNotEmpty,
|
||||
child: MenuRow(text: context.l10n.collectionActionSelect, icon: AIcons.select),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.map,
|
||||
enabled: isNotEmpty,
|
||||
child: MenuRow(text: context.l10n.menuActionMap, icon: AIcons.map),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.stats,
|
||||
enabled: isNotEmpty,
|
||||
child: MenuRow(text: context.l10n.menuActionStats, icon: AIcons.stats),
|
||||
),
|
||||
if (canAddShortcuts)
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.addShortcut,
|
||||
child: MenuRow(text: context.l10n.collectionActionAddShortcut, icon: AIcons.addShortcut),
|
||||
if (appMode == AppMode.main) ...[
|
||||
if (!isSelecting)
|
||||
_toMenuItem(
|
||||
CollectionAction.select,
|
||||
enabled: hasItems,
|
||||
),
|
||||
const PopupMenuDivider(),
|
||||
if (isSelecting)
|
||||
...[
|
||||
CollectionAction.copy,
|
||||
CollectionAction.move,
|
||||
CollectionAction.refreshMetadata,
|
||||
].map((v) => _toMenuItem(v, enabled: hasSelection)),
|
||||
...[
|
||||
CollectionAction.map,
|
||||
CollectionAction.stats,
|
||||
].map((v) => _toMenuItem(v, enabled: otherViewEnabled)),
|
||||
if (!isSelecting && canAddShortcuts) ...[
|
||||
const PopupMenuDivider(),
|
||||
_toMenuItem(CollectionAction.addShortcut),
|
||||
],
|
||||
if (selection.isSelecting) ...[
|
||||
],
|
||||
if (isSelecting) ...[
|
||||
const PopupMenuDivider(),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.copy,
|
||||
enabled: hasSelection,
|
||||
child: MenuRow(text: context.l10n.collectionActionCopy),
|
||||
_toMenuItem(
|
||||
CollectionAction.selectAll,
|
||||
enabled: selectedItems.length < collection.entryCount,
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.move,
|
||||
_toMenuItem(
|
||||
CollectionAction.selectNone,
|
||||
enabled: hasSelection,
|
||||
child: MenuRow(text: context.l10n.collectionActionMove),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.refreshMetadata,
|
||||
enabled: hasSelection,
|
||||
child: MenuRow(text: context.l10n.collectionActionRefreshMetadata),
|
||||
),
|
||||
const PopupMenuDivider(),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.selectAll,
|
||||
enabled: selection.selection.length < collection.entryCount,
|
||||
child: MenuRow(text: context.l10n.collectionActionSelectAll),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: CollectionAction.selectNone,
|
||||
enabled: hasSelection,
|
||||
child: MenuRow(text: context.l10n.collectionActionSelectNone),
|
||||
),
|
||||
]
|
||||
];
|
||||
|
@ -270,6 +252,18 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
];
|
||||
}
|
||||
|
||||
PopupMenuItem<CollectionAction> _toMenuItem(CollectionAction action, {Key? key, bool enabled = true}) {
|
||||
return PopupMenuItem(
|
||||
key: key,
|
||||
value: action,
|
||||
enabled: enabled,
|
||||
child: MenuRow(
|
||||
text: action.getText(context),
|
||||
icon: action.getIcon(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onActivityChange() {
|
||||
if (context.read<Selection<AvesEntry>>().isSelecting) {
|
||||
_browseToSelectAnimation.forward();
|
||||
|
@ -287,6 +281,8 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
case CollectionAction.copy:
|
||||
case CollectionAction.move:
|
||||
case CollectionAction.refreshMetadata:
|
||||
case CollectionAction.map:
|
||||
case CollectionAction.stats:
|
||||
_actionDelegate.onCollectionActionSelected(context, action);
|
||||
break;
|
||||
case CollectionAction.select:
|
||||
|
@ -298,12 +294,6 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
case CollectionAction.selectNone:
|
||||
context.read<Selection<AvesEntry>>().clearSelection();
|
||||
break;
|
||||
case CollectionAction.map:
|
||||
_goToMap();
|
||||
break;
|
||||
case CollectionAction.stats:
|
||||
_goToStats();
|
||||
break;
|
||||
case CollectionAction.addShortcut:
|
||||
unawaited(_showShortcutDialog(context));
|
||||
break;
|
||||
|
@ -385,30 +375,4 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _goToMap() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: MapPage.routeName),
|
||||
builder: (context) => MapPage(
|
||||
source: source,
|
||||
parentCollection: collection,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _goToStats() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: StatsPage.routeName),
|
||||
builder: (context) => StatsPage(
|
||||
source: source,
|
||||
parentCollection: collection,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import 'package:aves/widgets/common/action_mixins/size_aware.dart';
|
|||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/dialogs/aves_dialog.dart';
|
||||
import 'package:aves/widgets/filter_grids/album_pick.dart';
|
||||
import 'package:aves/widgets/map/map_page.dart';
|
||||
import 'package:aves/widgets/stats/stats_page.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
@ -52,6 +54,12 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
|||
case CollectionAction.refreshMetadata:
|
||||
_refreshMetadata(context);
|
||||
break;
|
||||
case CollectionAction.map:
|
||||
_goToMap(context);
|
||||
break;
|
||||
case CollectionAction.stats:
|
||||
_goToStats(context);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -242,4 +250,37 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _goToMap(BuildContext context) {
|
||||
final selection = context.read<Selection<AvesEntry>>();
|
||||
final entries = selection.isSelecting ? _getExpandedSelectedItems(selection) : context.read<CollectionLens>().sortedEntries;
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: MapPage.routeName),
|
||||
builder: (context) => MapPage(
|
||||
entries: entries.where((entry) => entry.hasGps).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _goToStats(BuildContext context) {
|
||||
final selection = context.read<Selection<AvesEntry>>();
|
||||
final collection = context.read<CollectionLens>();
|
||||
final entries = selection.isSelecting ? _getExpandedSelectedItems(selection) : collection.sortedEntries.toSet();
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: StatsPage.routeName),
|
||||
builder: (context) => StatsPage(
|
||||
entries: entries,
|
||||
source: collection.source,
|
||||
parentCollection: collection,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,10 +76,10 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
|||
_showSortDialog(context);
|
||||
break;
|
||||
case ChipSetAction.map:
|
||||
_goToMap(context);
|
||||
_goToMap(context, filters);
|
||||
break;
|
||||
case ChipSetAction.stats:
|
||||
_goToStats(context);
|
||||
_goToStats(context, filters);
|
||||
break;
|
||||
case ChipSetAction.select:
|
||||
context.read<Selection<FilterGridItem<T>>>().select();
|
||||
|
@ -129,28 +129,33 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
|||
}
|
||||
}
|
||||
|
||||
void _goToMap(BuildContext context) {
|
||||
void _goToMap(BuildContext context, Set<T> filters) {
|
||||
final source = context.read<CollectionSource>();
|
||||
final entries = filters.isEmpty ? source.visibleEntries : source.visibleEntries.where((entry) => filters.any((f) => f.test(entry)));
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: MapPage.routeName),
|
||||
builder: (context) => MapPage(
|
||||
source: source,
|
||||
entries: entries.where((entry) => entry.hasGps).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _goToStats(BuildContext context) {
|
||||
void _goToStats(BuildContext context, Set<T> filters) {
|
||||
final source = context.read<CollectionSource>();
|
||||
final entries = filters.isEmpty ? source.visibleEntries : source.visibleEntries.where((entry) => filters.any((f) => f.test(entry)));
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
settings: const RouteSettings(name: StatsPage.routeName),
|
||||
builder: (context) => StatsPage(
|
||||
builder: (context) {
|
||||
return StatsPage(
|
||||
entries: entries.toSet(),
|
||||
source: source,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -174,19 +174,44 @@ class _FilterGridAppBarState<T extends CollectionFilter> extends State<FilterGri
|
|||
PopupMenuButton<ChipSetAction>(
|
||||
key: const Key('appbar-menu-button'),
|
||||
itemBuilder: (context) {
|
||||
final selectedItems = selection.selection;
|
||||
final hasSelection = selectedItems.isNotEmpty;
|
||||
final hasItems = !widget.isEmpty;
|
||||
final otherViewEnabled = (!isSelecting && hasItems) || (isSelecting && hasSelection);
|
||||
|
||||
final menuItems = <PopupMenuEntry<ChipSetAction>>[
|
||||
toMenuItem(ChipSetAction.sort),
|
||||
if (widget.groupable) toMenuItem(ChipSetAction.group),
|
||||
if (appMode == AppMode.main && !isSelecting)
|
||||
toMenuItem(
|
||||
ChipSetAction.select,
|
||||
enabled: hasItems,
|
||||
),
|
||||
];
|
||||
|
||||
if (isSelecting) {
|
||||
final selectedItems = selection.selection;
|
||||
|
||||
if (selectionRowActions.isNotEmpty) {
|
||||
if (appMode == AppMode.main) {
|
||||
menuItems.add(const PopupMenuDivider());
|
||||
if (isSelecting) {
|
||||
menuItems.addAll(selectionRowActions.map(toMenuItem));
|
||||
}
|
||||
|
||||
menuItems.addAll([
|
||||
toMenuItem(
|
||||
ChipSetAction.map,
|
||||
enabled: otherViewEnabled,
|
||||
),
|
||||
toMenuItem(
|
||||
ChipSetAction.stats,
|
||||
enabled: otherViewEnabled,
|
||||
),
|
||||
]);
|
||||
if (!isSelecting) {
|
||||
menuItems.addAll([
|
||||
const PopupMenuDivider(),
|
||||
toMenuItem(ChipSetAction.createAlbum),
|
||||
]);
|
||||
}
|
||||
}
|
||||
if (isSelecting) {
|
||||
menuItems.addAll([
|
||||
const PopupMenuDivider(),
|
||||
toMenuItem(
|
||||
|
@ -195,19 +220,9 @@ class _FilterGridAppBarState<T extends CollectionFilter> extends State<FilterGri
|
|||
),
|
||||
toMenuItem(
|
||||
ChipSetAction.selectNone,
|
||||
enabled: selectedItems.isNotEmpty,
|
||||
enabled: hasSelection,
|
||||
),
|
||||
]);
|
||||
} else if (appMode == AppMode.main) {
|
||||
menuItems.addAll([
|
||||
toMenuItem(
|
||||
ChipSetAction.select,
|
||||
enabled: !widget.isEmpty,
|
||||
),
|
||||
toMenuItem(ChipSetAction.map),
|
||||
toMenuItem(ChipSetAction.stats),
|
||||
toMenuItem(ChipSetAction.createAlbum),
|
||||
]);
|
||||
}
|
||||
|
||||
return menuItems;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import 'package:aves/model/entry.dart';
|
||||
import 'package:aves/model/settings/map_style.dart';
|
||||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/model/source/collection_lens.dart';
|
||||
import 'package:aves/model/source/collection_source.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/map/geo_map.dart';
|
||||
|
@ -14,17 +12,12 @@ import 'package:flutter/scheduler.dart';
|
|||
class MapPage extends StatefulWidget {
|
||||
static const routeName = '/collection/map';
|
||||
|
||||
final CollectionSource source;
|
||||
final CollectionLens? parentCollection;
|
||||
late final List<AvesEntry> entries;
|
||||
final List<AvesEntry> entries;
|
||||
|
||||
MapPage({
|
||||
const MapPage({
|
||||
Key? key,
|
||||
required this.source,
|
||||
this.parentCollection,
|
||||
}) : super(key: key) {
|
||||
entries = (parentCollection?.sortedEntries.expand((entry) => entry.burstEntries ?? {entry}).toSet() ?? source.visibleEntries).where((entry) => entry.hasGps).toList();
|
||||
}
|
||||
required this.entries,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MapPageState createState() => _MapPageState();
|
||||
|
|
|
@ -28,17 +28,17 @@ class StatsPage extends StatelessWidget {
|
|||
|
||||
final CollectionSource source;
|
||||
final CollectionLens? parentCollection;
|
||||
late final Set<AvesEntry> entries;
|
||||
final Set<AvesEntry> entries;
|
||||
final Map<String, int> entryCountPerCountry = {}, entryCountPerPlace = {}, entryCountPerTag = {};
|
||||
|
||||
static const mimeDonutMinWidth = 124.0;
|
||||
|
||||
StatsPage({
|
||||
Key? key,
|
||||
required this.entries,
|
||||
required this.source,
|
||||
this.parentCollection,
|
||||
}) : super(key: key) {
|
||||
entries = parentCollection?.sortedEntries.expand((entry) => entry.burstEntries ?? {entry}).toSet() ?? source.visibleEntries;
|
||||
entries.forEach((entry) {
|
||||
if (entry.hasAddress) {
|
||||
final address = entry.addressDetails!;
|
||||
|
|
Loading…
Reference in a new issue