From 6bc416b6b669ef002e91a9c094ed85783413edd8 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 17 Aug 2020 09:45:22 +0900 Subject: [PATCH] settings: added option to show album list on launch --- lib/model/settings.dart | 40 +++++++++--- lib/widgets/app_drawer.dart | 103 +++--------------------------- lib/widgets/filter_grid_page.dart | 82 +++++++++++++++++++++++- lib/widgets/home_page.dart | 17 +++-- lib/widgets/settings_page.dart | 52 +++++++++++++-- 5 files changed, 177 insertions(+), 117 deletions(-) diff --git a/lib/model/settings.dart b/lib/model/settings.dart index 801340b09..f634b4279 100644 --- a/lib/model/settings.dart +++ b/lib/model/settings.dart @@ -16,13 +16,14 @@ class Settings { Settings._private(); // preferences + static const catalogTimeZoneKey = 'catalog_time_zone'; static const collectionGroupFactorKey = 'collection_group_factor'; static const collectionSortFactorKey = 'collection_sort_factor'; static const collectionTileExtentKey = 'collection_tile_extent'; + static const hasAcceptedTermsKey = 'has_accepted_terms'; static const infoMapStyleKey = 'info_map_style'; static const infoMapZoomKey = 'info_map_zoom'; - static const catalogTimeZoneKey = 'catalog_time_zone'; - static const hasAcceptedTermsKey = 'has_accepted_terms'; + static const launchPageKey = 'launch_page'; Future init() async { _prefs = await SharedPreferences.getInstance(); @@ -52,14 +53,6 @@ class Settings { } } - EntryMapStyle get infoMapStyle => getEnumOrDefault(infoMapStyleKey, EntryMapStyle.stamenWatercolor, EntryMapStyle.values); - - set infoMapStyle(EntryMapStyle newValue) => setAndNotify(infoMapStyleKey, newValue.toString()); - - double get infoMapZoom => _prefs.getDouble(infoMapZoomKey) ?? 12; - - set infoMapZoom(double newValue) => setAndNotify(infoMapZoomKey, newValue); - String get catalogTimeZone => _prefs.getString(catalogTimeZoneKey) ?? ''; set catalogTimeZone(String newValue) => setAndNotify(catalogTimeZoneKey, newValue); @@ -76,10 +69,22 @@ class Settings { set collectionTileExtent(double newValue) => setAndNotify(collectionTileExtentKey, newValue); + EntryMapStyle get infoMapStyle => getEnumOrDefault(infoMapStyleKey, EntryMapStyle.stamenWatercolor, EntryMapStyle.values); + + set infoMapStyle(EntryMapStyle newValue) => setAndNotify(infoMapStyleKey, newValue.toString()); + + double get infoMapZoom => _prefs.getDouble(infoMapZoomKey) ?? 12; + + set infoMapZoom(double newValue) => setAndNotify(infoMapZoomKey, newValue); + bool get hasAcceptedTerms => getBoolOrDefault(hasAcceptedTermsKey, false); set hasAcceptedTerms(bool newValue) => setAndNotify(hasAcceptedTermsKey, newValue); + LaunchPage get launchPage => getEnumOrDefault(launchPageKey, LaunchPage.collection, LaunchPage.values); + + set launchPage(LaunchPage newValue) => setAndNotify(launchPageKey, newValue.toString()); + // convenience methods // ignore: avoid_positional_boolean_parameters @@ -124,3 +129,18 @@ class Settings { } } } + +enum LaunchPage { collection, albums } + +extension ExtraLaunchPage on LaunchPage { + String get name { + switch (this) { + case LaunchPage.collection: + return 'All Media'; + case LaunchPage.albums: + return 'Albums'; + default: + return toString(); + } + } +} diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index c0ee4e7f3..29bde3213 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -3,9 +3,7 @@ import 'dart:ui'; import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/favourite.dart'; import 'package:aves/model/filters/filters.dart'; -import 'package:aves/model/filters/location.dart'; import 'package:aves/model/filters/mime.dart'; -import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/mime_types.dart'; import 'package:aves/model/settings.dart'; import 'package:aves/model/source/album.dart'; @@ -16,7 +14,6 @@ import 'package:aves/model/source/tag.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/widgets/about/about_page.dart'; import 'package:aves/widgets/album/collection_page.dart'; -import 'package:aves/widgets/album/empty.dart'; import 'package:aves/widgets/common/aves_logo.dart'; import 'package:aves/widgets/common/icons.dart'; import 'package:aves/widgets/debug_page.dart'; @@ -100,7 +97,7 @@ class _AppDrawerState extends State { child: ListTile( leading: Icon(AIcons.settings), title: Text('Preferences'), - onTap: () => _goToSettings(context), + onTap: () => _goTo((_) => SettingsPage()), ), ); final aboutEntry = SafeArea( @@ -109,7 +106,7 @@ class _AppDrawerState extends State { child: ListTile( leading: Icon(AIcons.info), title: Text('About'), - onTap: () => _goToAbout(context), + onTap: () => _goTo((_) => AboutPage()), ), ); @@ -134,7 +131,7 @@ class _AppDrawerState extends State { child: ListTile( leading: Icon(AIcons.debug), title: Text('Debug'), - onTap: () => _goToDebug(context), + onTap: () => _goTo((_) => DebugPage(source: source)), ), ), ], @@ -215,7 +212,7 @@ class _AppDrawerState extends State { ), ); }), - onTap: () => _goToAlbums(context), + onTap: () => _goTo((_) => AlbumListPage(source: source)), ), ); } @@ -237,7 +234,7 @@ class _AppDrawerState extends State { ), ); }), - onTap: () => _goToCountries(context), + onTap: () => _goTo((_) => CountryListPage(source: source)), ), ); } @@ -259,98 +256,14 @@ class _AppDrawerState extends State { ), ); }), - onTap: () => _goToTags(context), + onTap: () => _goTo((_) => TagListPage(source: source)), ), ); } - void _goToAlbums(BuildContext context) { + void _goTo(WidgetBuilder builder) { Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FilterNavigationPage( - source: source, - title: 'Albums', - filterEntries: source.getAlbumEntries(), - filterBuilder: (s) => AlbumFilter(s, source.getUniqueAlbumName(s)), - emptyBuilder: () => EmptyContent( - icon: AIcons.album, - text: 'No albums', - ), - ), - ), - ); - } - - void _goToCountries(BuildContext context) { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FilterNavigationPage( - source: source, - title: 'Countries', - filterEntries: source.getCountryEntries(), - filterBuilder: (s) => LocationFilter(LocationLevel.country, s), - emptyBuilder: () => EmptyContent( - icon: AIcons.location, - text: 'No countries', - ), - ), - ), - ); - } - - void _goToTags(BuildContext context) { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FilterNavigationPage( - source: source, - title: 'Tags', - filterEntries: source.getTagEntries(), - filterBuilder: (s) => TagFilter(s), - emptyBuilder: () => EmptyContent( - icon: AIcons.tag, - text: 'No tags', - ), - ), - ), - ); - } - - void _goToSettings(BuildContext context) { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SettingsPage(), - ), - ); - } - - void _goToAbout(BuildContext context) { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AboutPage(), - ), - ); - } - - void _goToDebug(BuildContext context) { - Navigator.pop(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => DebugPage( - source: source, - ), - ), - ); + Navigator.push(context, MaterialPageRoute(builder: builder)); } } diff --git a/lib/widgets/filter_grid_page.dart b/lib/widgets/filter_grid_page.dart index 437f1e9c1..2862d2043 100644 --- a/lib/widgets/filter_grid_page.dart +++ b/lib/widgets/filter_grid_page.dart @@ -2,13 +2,19 @@ import 'dart:ui'; import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/filters.dart'; +import 'package:aves/model/filters/location.dart'; +import 'package:aves/model/filters/tag.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/model/settings.dart'; +import 'package:aves/model/source/album.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; +import 'package:aves/model/source/location.dart'; +import 'package:aves/model/source/tag.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/durations.dart'; import 'package:aves/widgets/album/collection_page.dart'; +import 'package:aves/widgets/album/empty.dart'; import 'package:aves/widgets/album/thumbnail/raster.dart'; import 'package:aves/widgets/album/thumbnail/vector.dart'; import 'package:aves/widgets/app_drawer.dart'; @@ -20,6 +26,75 @@ import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; import 'package:provider/provider.dart'; +class AlbumListPage extends StatelessWidget { + final CollectionSource source; + + const AlbumListPage({@required this.source}); + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) => FilterNavigationPage( + source: source, + title: 'Albums', + filterEntries: source.getAlbumEntries(), + filterBuilder: (s) => AlbumFilter(s, source.getUniqueAlbumName(s)), + emptyBuilder: () => EmptyContent( + icon: AIcons.album, + text: 'No albums', + ), + ), + ); + } +} + +class CountryListPage extends StatelessWidget { + final CollectionSource source; + + const CountryListPage({@required this.source}); + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) => FilterNavigationPage( + source: source, + title: 'Countries', + filterEntries: source.getCountryEntries(), + filterBuilder: (s) => LocationFilter(LocationLevel.country, s), + emptyBuilder: () => EmptyContent( + icon: AIcons.location, + text: 'No countries', + ), + ), + ); + } +} + +class TagListPage extends StatelessWidget { + final CollectionSource source; + + const TagListPage({@required this.source}); + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: source.eventBus.on(), + builder: (context, snapshot) => FilterNavigationPage( + source: source, + title: 'Tags', + filterEntries: source.getTagEntries(), + filterBuilder: (s) => TagFilter(s), + emptyBuilder: () => EmptyContent( + icon: AIcons.tag, + text: 'No tags', + ), + ), + ); + } +} + class FilterNavigationPage extends StatelessWidget { final CollectionSource source; final String title; @@ -48,7 +123,12 @@ class FilterNavigationPage extends StatelessWidget { ), filterEntries: filterEntries, filterBuilder: filterBuilder, - emptyBuilder: emptyBuilder, + emptyBuilder: () => ValueListenableBuilder( + valueListenable: source.stateNotifier, + builder: (context, sourceState, child) { + return sourceState != SourceState.loading && emptyBuilder != null ? emptyBuilder() : SizedBox.shrink(); + }, + ), onPressed: (filter) => Navigator.pushAndRemoveUntil( context, MaterialPageRoute( diff --git a/lib/widgets/home_page.dart b/lib/widgets/home_page.dart index 6365e0c1e..b211ddec5 100644 --- a/lib/widgets/home_page.dart +++ b/lib/widgets/home_page.dart @@ -8,6 +8,7 @@ import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/widgets/album/collection_page.dart'; import 'package:aves/widgets/common/data_providers/media_store_collection_provider.dart'; import 'package:aves/widgets/common/icons.dart'; +import 'package:aves/widgets/filter_grid_page.dart'; import 'package:aves/widgets/fullscreen/fullscreen_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -101,11 +102,17 @@ class _HomePageState extends State { return SingleFullscreenPage(entry: _viewerEntry); } if (_mediaStore != null) { - return CollectionPage(CollectionLens( - source: _mediaStore, - groupFactor: settings.collectionGroupFactor, - sortFactor: settings.collectionSortFactor, - )); + switch(settings.launchPage) { + case LaunchPage.albums: + return AlbumListPage(source: _mediaStore); + break; + case LaunchPage.collection: + return CollectionPage(CollectionLens( + source: _mediaStore, + groupFactor: settings.collectionGroupFactor, + sortFactor: settings.collectionSortFactor, + )); + } } return SizedBox.shrink(); }); diff --git a/lib/widgets/settings_page.dart b/lib/widgets/settings_page.dart index f12b8cd1f..8a0b2af4f 100644 --- a/lib/widgets/settings_page.dart +++ b/lib/widgets/settings_page.dart @@ -1,4 +1,5 @@ import 'package:aves/model/settings.dart'; +import 'package:aves/utils/constants.dart'; import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart'; import 'package:aves/widgets/fullscreen/info/location_section.dart'; import 'package:flutter/material.dart'; @@ -17,7 +18,17 @@ class SettingsPage extends StatelessWidget { child: ListView( padding: EdgeInsets.all(16), children: [ - Text('Maps'), + Text('General', style: Constants.titleTextStyle), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text('Launch Page:'), + SizedBox(width: 8), + Flexible(child: LaunchPageSelector()), + ], + ), + SizedBox(height: 16), + Text('Maps', style: Constants.titleTextStyle), Row( mainAxisSize: MainAxisSize.min, children: [ @@ -45,10 +56,10 @@ class _InfoMapStyleSelectorState extends State { Widget build(BuildContext context) { return DropdownButton( items: EntryMapStyle.values - .map((style) => DropdownMenuItem( - value: style, + .map((selected) => DropdownMenuItem( + value: selected, child: Text( - style.name, + selected.name, softWrap: false, overflow: TextOverflow.fade, maxLines: 1, @@ -56,8 +67,37 @@ class _InfoMapStyleSelectorState extends State { )) .toList(), value: settings.infoMapStyle, - onChanged: (style) { - settings.infoMapStyle = style; + onChanged: (selected) { + settings.infoMapStyle = selected; + setState(() {}); + }, + ); + } +} + +class LaunchPageSelector extends StatefulWidget { + @override + _LaunchPageSelectorState createState() => _LaunchPageSelectorState(); +} + +class _LaunchPageSelectorState extends State { + @override + Widget build(BuildContext context) { + return DropdownButton( + items: LaunchPage.values + .map((selected) => DropdownMenuItem( + value: selected, + child: Text( + selected.name, + softWrap: false, + overflow: TextOverflow.fade, + maxLines: 1, + ), + )) + .toList(), + value: settings.launchPage, + onChanged: (selected) { + settings.launchPage = selected; setState(() {}); }, );