export: support view mode
This commit is contained in:
parent
218db5d091
commit
c332e125bb
5 changed files with 66 additions and 26 deletions
|
@ -164,6 +164,8 @@ abstract class CollectionSource with SourceBase, AlbumMixin, LocationMixin, TagM
|
||||||
return _filterEntryCountMap.putIfAbsent(filter, () => _rawEntries.where((entry) => filter.filter(entry)).length);
|
return _filterEntryCountMap.putIfAbsent(filter, () => _rawEntries.where((entry) => filter.filter(entry)).length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get initialized => false;
|
||||||
|
|
||||||
Future<void> init();
|
Future<void> init();
|
||||||
|
|
||||||
Future<void> refresh();
|
Future<void> refresh();
|
||||||
|
|
|
@ -13,6 +13,11 @@ import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
||||||
import 'package:pedantic/pedantic.dart';
|
import 'package:pedantic/pedantic.dart';
|
||||||
|
|
||||||
class MediaStoreSource extends CollectionSource {
|
class MediaStoreSource extends CollectionSource {
|
||||||
|
bool _initialized = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get initialized => _initialized;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
final stopwatch = Stopwatch()..start();
|
final stopwatch = Stopwatch()..start();
|
||||||
|
@ -29,6 +34,7 @@ class MediaStoreSource extends CollectionSource {
|
||||||
settings.catalogTimeZone = currentTimeZone;
|
settings.catalogTimeZone = currentTimeZone;
|
||||||
}
|
}
|
||||||
await loadDates(); // 100ms for 5400 entries
|
await loadDates(); // 100ms for 5400 entries
|
||||||
|
_initialized = true;
|
||||||
debugPrint('$runtimeType init done, elapsed=${stopwatch.elapsed}');
|
debugPrint('$runtimeType init done, elapsed=${stopwatch.elapsed}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,14 @@ import 'package:aves/model/actions/chip_actions.dart';
|
||||||
import 'package:aves/model/actions/move_type.dart';
|
import 'package:aves/model/actions/move_type.dart';
|
||||||
import 'package:aves/model/filters/album.dart';
|
import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.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/enums.dart';
|
import 'package:aves/model/source/enums.dart';
|
||||||
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
import 'package:aves/widgets/collection/empty.dart';
|
import 'package:aves/widgets/collection/empty.dart';
|
||||||
|
import 'package:aves/widgets/common/app_bar_subtitle.dart';
|
||||||
|
import 'package:aves/widgets/common/basic/menu_row.dart';
|
||||||
import 'package:aves/widgets/common/basic/query_bar.dart';
|
import 'package:aves/widgets/common/basic/query_bar.dart';
|
||||||
import 'package:aves/widgets/dialogs/create_album_dialog.dart';
|
import 'package:aves/widgets/dialogs/create_album_dialog.dart';
|
||||||
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
import 'package:aves/widgets/filter_grids/albums_page.dart';
|
||||||
|
@ -13,8 +17,10 @@ import 'package:aves/widgets/filter_grids/common/chip_set_action_delegate.dart';
|
||||||
import 'package:aves/widgets/filter_grids/common/filter_grid_page.dart';
|
import 'package:aves/widgets/filter_grids/common/filter_grid_page.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class AlbumPickPage extends StatefulWidget {
|
class AlbumPickPage extends StatefulWidget {
|
||||||
static const routeName = '/album_pick';
|
static const routeName = '/album_pick';
|
||||||
|
@ -39,15 +45,18 @@ class _AlbumPickPageState extends State<AlbumPickPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Widget appBar = AlbumPickAppBar(
|
Widget appBar = AlbumPickAppBar(
|
||||||
|
source: source,
|
||||||
moveType: widget.moveType,
|
moveType: widget.moveType,
|
||||||
actionDelegate: AlbumChipSetActionDelegate(source: source),
|
actionDelegate: AlbumChipSetActionDelegate(source: source),
|
||||||
queryNotifier: _queryNotifier,
|
queryNotifier: _queryNotifier,
|
||||||
);
|
);
|
||||||
|
|
||||||
return Selector<Settings, ChipSortFactor>(
|
return Selector<Settings, Tuple2<AlbumChipGroupFactor, ChipSortFactor>>(
|
||||||
selector: (context, s) => s.albumSortFactor,
|
selector: (context, s) => Tuple2(s.albumGroupFactor, s.albumSortFactor),
|
||||||
builder: (context, sortFactor, child) {
|
builder: (context, s, child) {
|
||||||
return FilterGridPage<AlbumFilter>(
|
return StreamBuilder(
|
||||||
|
stream: source.eventBus.on<AlbumsChangedEvent>(),
|
||||||
|
builder: (context, snapshot) => FilterGridPage<AlbumFilter>(
|
||||||
source: source,
|
source: source,
|
||||||
appBar: appBar,
|
appBar: appBar,
|
||||||
filterSections: AlbumListPage.getAlbumEntries(source),
|
filterSections: AlbumListPage.getAlbumEntries(source),
|
||||||
|
@ -65,6 +74,7 @@ class _AlbumPickPageState extends State<AlbumPickPage> {
|
||||||
settingsRouteKey: AlbumListPage.routeName,
|
settingsRouteKey: AlbumListPage.routeName,
|
||||||
appBarHeight: AlbumPickAppBar.preferredHeight,
|
appBarHeight: AlbumPickAppBar.preferredHeight,
|
||||||
onTap: (filter) => Navigator.pop<String>(context, (filter as AlbumFilter)?.album),
|
onTap: (filter) => Navigator.pop<String>(context, (filter as AlbumFilter)?.album),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -72,6 +82,7 @@ class _AlbumPickPageState extends State<AlbumPickPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class AlbumPickAppBar extends StatelessWidget {
|
class AlbumPickAppBar extends StatelessWidget {
|
||||||
|
final CollectionSource source;
|
||||||
final MoveType moveType;
|
final MoveType moveType;
|
||||||
final AlbumChipSetActionDelegate actionDelegate;
|
final AlbumChipSetActionDelegate actionDelegate;
|
||||||
final ValueNotifier<String> queryNotifier;
|
final ValueNotifier<String> queryNotifier;
|
||||||
|
@ -79,6 +90,7 @@ class AlbumPickAppBar extends StatelessWidget {
|
||||||
static const preferredHeight = kToolbarHeight + AlbumFilterBar.preferredHeight;
|
static const preferredHeight = kToolbarHeight + AlbumFilterBar.preferredHeight;
|
||||||
|
|
||||||
const AlbumPickAppBar({
|
const AlbumPickAppBar({
|
||||||
|
@required this.source,
|
||||||
@required this.moveType,
|
@required this.moveType,
|
||||||
@required this.actionDelegate,
|
@required this.actionDelegate,
|
||||||
@required this.queryNotifier,
|
@required this.queryNotifier,
|
||||||
|
@ -101,7 +113,10 @@ class AlbumPickAppBar extends StatelessWidget {
|
||||||
|
|
||||||
return SliverAppBar(
|
return SliverAppBar(
|
||||||
leading: BackButton(),
|
leading: BackButton(),
|
||||||
|
title: SourceStateAwareAppBarTitle(
|
||||||
title: Text(title()),
|
title: Text(title()),
|
||||||
|
source: source,
|
||||||
|
),
|
||||||
bottom: AlbumFilterBar(
|
bottom: AlbumFilterBar(
|
||||||
filterNotifier: queryNotifier,
|
filterNotifier: queryNotifier,
|
||||||
),
|
),
|
||||||
|
@ -119,10 +134,23 @@ class AlbumPickAppBar extends StatelessWidget {
|
||||||
},
|
},
|
||||||
tooltip: 'Create album',
|
tooltip: 'Create album',
|
||||||
),
|
),
|
||||||
IconButton(
|
PopupMenuButton<ChipSetAction>(
|
||||||
icon: Icon(AIcons.sort),
|
itemBuilder: (context) {
|
||||||
onPressed: () => actionDelegate.onActionSelected(context, ChipSetAction.sort),
|
return [
|
||||||
tooltip: 'Sort…',
|
PopupMenuItem(
|
||||||
|
value: ChipSetAction.sort,
|
||||||
|
child: MenuRow(text: 'Sort…', icon: AIcons.sort),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
value: ChipSetAction.group,
|
||||||
|
child: MenuRow(text: 'Group…', icon: AIcons.group),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
onSelected: (action) {
|
||||||
|
// wait for the popup menu to hide before proceeding with the action
|
||||||
|
Future.delayed(Durations.popupMenuAnimation * timeDilation, () => actionDelegate.onActionSelected(context, action));
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
floating: true,
|
floating: true,
|
||||||
|
|
|
@ -92,7 +92,7 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate {
|
||||||
builder: (context) => AvesSelectionDialog<AlbumChipGroupFactor>(
|
builder: (context) => AvesSelectionDialog<AlbumChipGroupFactor>(
|
||||||
initialValue: settings.albumGroupFactor,
|
initialValue: settings.albumGroupFactor,
|
||||||
options: {
|
options: {
|
||||||
AlbumChipGroupFactor.importance: 'By importance',
|
AlbumChipGroupFactor.importance: 'By tier',
|
||||||
AlbumChipGroupFactor.volume: 'By storage volume',
|
AlbumChipGroupFactor.volume: 'By storage volume',
|
||||||
AlbumChipGroupFactor.none: 'Do not group',
|
AlbumChipGroupFactor.none: 'Do not group',
|
||||||
},
|
},
|
||||||
|
|
|
@ -153,6 +153,10 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
|
|
||||||
Future<void> _showExportDialog(BuildContext context, AvesEntry entry) async {
|
Future<void> _showExportDialog(BuildContext context, AvesEntry entry) async {
|
||||||
final source = context.read<CollectionSource>();
|
final source = context.read<CollectionSource>();
|
||||||
|
if (!source.initialized) {
|
||||||
|
await source.init();
|
||||||
|
unawaited(source.refresh());
|
||||||
|
}
|
||||||
final destinationAlbum = await Navigator.push(
|
final destinationAlbum = await Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute<String>(
|
MaterialPageRoute<String>(
|
||||||
|
|
Loading…
Reference in a new issue