refactored drawer
This commit is contained in:
parent
80644f036b
commit
ad397f0afc
7 changed files with 343 additions and 331 deletions
|
@ -1,8 +1,8 @@
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/widgets/album/thumbnail_collection.dart';
|
import 'package:aves/widgets/album/thumbnail_collection.dart';
|
||||||
import 'package:aves/widgets/app_drawer.dart';
|
|
||||||
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
||||||
import 'package:aves/widgets/common/double_back_pop.dart';
|
import 'package:aves/widgets/common/double_back_pop.dart';
|
||||||
|
import 'package:aves/widgets/drawer/app_drawer.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
|
@ -1,328 +0,0 @@
|
||||||
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/mime.dart';
|
|
||||||
import 'package:aves/model/mime_types.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/flutter_utils.dart';
|
|
||||||
import 'package:aves/widgets/about/about_page.dart';
|
|
||||||
import 'package:aves/widgets/album/collection_page.dart';
|
|
||||||
import 'package:aves/widgets/common/aves_logo.dart';
|
|
||||||
import 'package:aves/widgets/common/icons.dart';
|
|
||||||
import 'package:aves/widgets/debug_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/tags_page.dart';
|
|
||||||
import 'package:aves/widgets/settings/settings_page.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class AppDrawer extends StatefulWidget {
|
|
||||||
final CollectionSource source;
|
|
||||||
|
|
||||||
const AppDrawer({@required this.source});
|
|
||||||
|
|
||||||
@override
|
|
||||||
_AppDrawerState createState() => _AppDrawerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AppDrawerState extends State<AppDrawer> {
|
|
||||||
CollectionSource get source => widget.source;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final header = Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: Divider.createBorderSide(context),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.all(16),
|
|
||||||
color: Theme.of(context).accentColor,
|
|
||||||
child: SafeArea(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Align(
|
|
||||||
alignment: AlignmentDirectional.centerStart,
|
|
||||||
child: Wrap(
|
|
||||||
spacing: 16,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
|
||||||
children: [
|
|
||||||
AvesLogo(size: 64),
|
|
||||||
Text(
|
|
||||||
'Aves',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 44,
|
|
||||||
fontFamily: 'Concourse Caps',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final allCollectionEntry = _FilteredCollectionNavTile(
|
|
||||||
source: source,
|
|
||||||
leading: Icon(AIcons.allCollection),
|
|
||||||
title: 'All collection',
|
|
||||||
filter: null,
|
|
||||||
);
|
|
||||||
final videoEntry = _FilteredCollectionNavTile(
|
|
||||||
source: source,
|
|
||||||
leading: Icon(AIcons.video),
|
|
||||||
title: 'Videos',
|
|
||||||
filter: MimeFilter(MimeTypes.anyVideo),
|
|
||||||
);
|
|
||||||
final favouriteEntry = _FilteredCollectionNavTile(
|
|
||||||
source: source,
|
|
||||||
leading: Icon(AIcons.favourite),
|
|
||||||
title: 'Favourites',
|
|
||||||
filter: FavouriteFilter(),
|
|
||||||
);
|
|
||||||
final settingsEntry = SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
leading: Icon(AIcons.settings),
|
|
||||||
title: Text('Preferences'),
|
|
||||||
onTap: () => _goTo(SettingsPage.routeName, (_) => SettingsPage()),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final aboutEntry = SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
leading: Icon(AIcons.info),
|
|
||||||
title: Text('About'),
|
|
||||||
onTap: () => _goTo(AboutPage.routeName, (_) => AboutPage()),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final drawerItems = <Widget>[
|
|
||||||
header,
|
|
||||||
allCollectionEntry,
|
|
||||||
videoEntry,
|
|
||||||
favouriteEntry,
|
|
||||||
_buildSpecialAlbumSection(),
|
|
||||||
Divider(),
|
|
||||||
_buildAlbumListEntry(),
|
|
||||||
_buildCountryListEntry(),
|
|
||||||
_buildTagListEntry(),
|
|
||||||
Divider(),
|
|
||||||
settingsEntry,
|
|
||||||
aboutEntry,
|
|
||||||
if (kDebugMode) ...[
|
|
||||||
Divider(),
|
|
||||||
SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
leading: Icon(AIcons.debug),
|
|
||||||
title: Text('Debug'),
|
|
||||||
onTap: () => _goTo(DebugPage.routeName, (_) => DebugPage(source: source)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
return Drawer(
|
|
||||||
child: Selector<MediaQueryData, double>(
|
|
||||||
selector: (c, mq) => mq.viewInsets.bottom,
|
|
||||||
builder: (c, mqViewInsetsBottom, child) {
|
|
||||||
return SingleChildScrollView(
|
|
||||||
padding: EdgeInsets.only(bottom: mqViewInsetsBottom),
|
|
||||||
child: Theme(
|
|
||||||
data: Theme.of(context).copyWith(
|
|
||||||
// color used by `ExpansionTile` for leading icon
|
|
||||||
unselectedWidgetColor: Colors.white,
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: drawerItems,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildAlbumEntry(String album, {bool dense = true}) {
|
|
||||||
final uniqueName = source.getUniqueAlbumName(album);
|
|
||||||
return _FilteredCollectionNavTile(
|
|
||||||
source: source,
|
|
||||||
leading: IconUtils.getAlbumIcon(context: context, album: album),
|
|
||||||
title: uniqueName,
|
|
||||||
trailing: androidFileUtils.isOnRemovableStorage(album)
|
|
||||||
? Icon(
|
|
||||||
AIcons.removableStorage,
|
|
||||||
size: 16,
|
|
||||||
color: Colors.grey,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
dense: dense,
|
|
||||||
filter: AlbumFilter(album, uniqueName),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildSpecialAlbumSection() {
|
|
||||||
return StreamBuilder(
|
|
||||||
stream: source.eventBus.on<AlbumsChangedEvent>(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
final specialAlbums = source.sortedAlbums.where((album) {
|
|
||||||
final type = androidFileUtils.getAlbumType(album);
|
|
||||||
return [AlbumType.camera, AlbumType.screenshots].contains(type);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (specialAlbums.isEmpty) return SizedBox.shrink();
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
Divider(),
|
|
||||||
...specialAlbums.map((album) => _buildAlbumEntry(album, dense: false)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildAlbumListEntry() {
|
|
||||||
return SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
key: Key('albums-tile'),
|
|
||||||
leading: Icon(AIcons.album),
|
|
||||||
title: Text('Albums'),
|
|
||||||
trailing: StreamBuilder(
|
|
||||||
stream: source.eventBus.on<AlbumsChangedEvent>(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
return Text(
|
|
||||||
'${source.sortedAlbums.length}',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white.withOpacity(.6),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
onTap: () => _goTo(AlbumListPage.routeName, (_) => AlbumListPage(source: source)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCountryListEntry() {
|
|
||||||
return SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
leading: Icon(AIcons.location),
|
|
||||||
title: Text('Countries'),
|
|
||||||
trailing: StreamBuilder(
|
|
||||||
stream: source.eventBus.on<LocationsChangedEvent>(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
return Text(
|
|
||||||
'${source.sortedCountries.length}',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white.withOpacity(.6),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
onTap: () => _goTo(CountryListPage.routeName, (_) => CountryListPage(source: source)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTagListEntry() {
|
|
||||||
return SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
leading: Icon(AIcons.tag),
|
|
||||||
title: Text('Tags'),
|
|
||||||
trailing: StreamBuilder(
|
|
||||||
stream: source.eventBus.on<TagsChangedEvent>(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
return Text(
|
|
||||||
'${source.sortedTags.length}',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white.withOpacity(.6),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
onTap: () => _goTo(TagListPage.routeName, (_) => TagListPage(source: source)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _goTo(String routeName, WidgetBuilder builder) {
|
|
||||||
Navigator.pop(context);
|
|
||||||
if (routeName != context.currentRouteName) {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
settings: RouteSettings(name: routeName),
|
|
||||||
builder: builder,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _FilteredCollectionNavTile extends StatelessWidget {
|
|
||||||
final CollectionSource source;
|
|
||||||
final Widget leading;
|
|
||||||
final String title;
|
|
||||||
final Widget trailing;
|
|
||||||
final bool dense;
|
|
||||||
final CollectionFilter filter;
|
|
||||||
|
|
||||||
const _FilteredCollectionNavTile({
|
|
||||||
@required this.source,
|
|
||||||
@required this.leading,
|
|
||||||
@required this.title,
|
|
||||||
this.trailing,
|
|
||||||
bool dense,
|
|
||||||
@required this.filter,
|
|
||||||
}) : dense = dense ?? false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
child: ListTile(
|
|
||||||
leading: leading,
|
|
||||||
title: Text(title),
|
|
||||||
trailing: trailing,
|
|
||||||
dense: dense,
|
|
||||||
onTap: () => _goToCollection(context),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _goToCollection(BuildContext context) {
|
|
||||||
Navigator.pushAndRemoveUntil(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
settings: RouteSettings(name: CollectionPage.routeName),
|
|
||||||
builder: (context) => CollectionPage(CollectionLens(
|
|
||||||
source: source,
|
|
||||||
filters: [filter],
|
|
||||||
groupFactor: settings.collectionGroupFactor,
|
|
||||||
sortFactor: settings.collectionSortFactor,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
(route) => false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
228
lib/widgets/drawer/app_drawer.dart
Normal file
228
lib/widgets/drawer/app_drawer.dart
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:aves/model/filters/album.dart';
|
||||||
|
import 'package:aves/model/filters/favourite.dart';
|
||||||
|
import 'package:aves/model/filters/mime.dart';
|
||||||
|
import 'package:aves/model/mime_types.dart';
|
||||||
|
import 'package:aves/model/source/album.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/widgets/about/about_page.dart';
|
||||||
|
import 'package:aves/widgets/common/aves_logo.dart';
|
||||||
|
import 'package:aves/widgets/common/icons.dart';
|
||||||
|
import 'package:aves/widgets/debug_page.dart';
|
||||||
|
import 'package:aves/widgets/drawer/collection_tile.dart';
|
||||||
|
import 'package:aves/widgets/drawer/tile.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/tags_page.dart';
|
||||||
|
import 'package:aves/widgets/settings/settings_page.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AppDrawer extends StatefulWidget {
|
||||||
|
final CollectionSource source;
|
||||||
|
|
||||||
|
const AppDrawer({@required this.source});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AppDrawerState createState() => _AppDrawerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppDrawerState extends State<AppDrawer> {
|
||||||
|
CollectionSource get source => widget.source;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final header = Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: Divider.createBorderSide(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
color: Theme.of(context).accentColor,
|
||||||
|
child: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Align(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 16,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
AvesLogo(size: 64),
|
||||||
|
Text(
|
||||||
|
'Aves',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 44,
|
||||||
|
fontFamily: 'Concourse Caps',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final drawerItems = <Widget>[
|
||||||
|
header,
|
||||||
|
allCollectionTile,
|
||||||
|
videoTile,
|
||||||
|
favouriteTile,
|
||||||
|
_buildSpecialAlbumSection(),
|
||||||
|
Divider(),
|
||||||
|
albumListTile,
|
||||||
|
countryListTile,
|
||||||
|
tagListTile,
|
||||||
|
Divider(),
|
||||||
|
settingsTile,
|
||||||
|
aboutTile,
|
||||||
|
if (kDebugMode) ...[
|
||||||
|
Divider(),
|
||||||
|
debugTile,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return Drawer(
|
||||||
|
child: Selector<MediaQueryData, double>(
|
||||||
|
selector: (c, mq) => mq.viewInsets.bottom,
|
||||||
|
builder: (c, mqViewInsetsBottom, child) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
padding: EdgeInsets.only(bottom: mqViewInsetsBottom),
|
||||||
|
child: Theme(
|
||||||
|
data: Theme.of(context).copyWith(
|
||||||
|
// color used by `ExpansionTile` for leading icon
|
||||||
|
unselectedWidgetColor: Colors.white,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: drawerItems,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildAlbumTile(String album) {
|
||||||
|
final uniqueName = source.getUniqueAlbumName(album);
|
||||||
|
return CollectionNavTile(
|
||||||
|
source: source,
|
||||||
|
leading: IconUtils.getAlbumIcon(context: context, album: album),
|
||||||
|
title: uniqueName,
|
||||||
|
trailing: androidFileUtils.isOnRemovableStorage(album)
|
||||||
|
? Icon(
|
||||||
|
AIcons.removableStorage,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.grey,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
filter: AlbumFilter(album, uniqueName),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSpecialAlbumSection() {
|
||||||
|
return StreamBuilder(
|
||||||
|
stream: source.eventBus.on<AlbumsChangedEvent>(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final specialAlbums = source.sortedAlbums.where((album) {
|
||||||
|
final type = androidFileUtils.getAlbumType(album);
|
||||||
|
return [AlbumType.camera, AlbumType.screenshots].contains(type);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (specialAlbums.isEmpty) return SizedBox.shrink();
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Divider(),
|
||||||
|
...specialAlbums.map(_buildAlbumTile),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// tiles
|
||||||
|
|
||||||
|
Widget get allCollectionTile => CollectionNavTile(
|
||||||
|
source: source,
|
||||||
|
leading: Icon(AIcons.allCollection),
|
||||||
|
title: 'All collection',
|
||||||
|
filter: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get videoTile => CollectionNavTile(
|
||||||
|
source: source,
|
||||||
|
leading: Icon(AIcons.video),
|
||||||
|
title: 'Videos',
|
||||||
|
filter: MimeFilter(MimeTypes.anyVideo),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get favouriteTile => CollectionNavTile(
|
||||||
|
source: source,
|
||||||
|
leading: Icon(AIcons.favourite),
|
||||||
|
title: 'Favourites',
|
||||||
|
filter: FavouriteFilter(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get albumListTile => NavTile(
|
||||||
|
icon: AIcons.album,
|
||||||
|
title: 'Albums',
|
||||||
|
trailing: StreamBuilder(
|
||||||
|
stream: source.eventBus.on<AlbumsChangedEvent>(),
|
||||||
|
builder: (context, _) => Text('${source.sortedAlbums.length}'),
|
||||||
|
),
|
||||||
|
routeName: AlbumListPage.routeName,
|
||||||
|
pageBuilder: (_) => AlbumListPage(source: source),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get countryListTile => NavTile(
|
||||||
|
icon: AIcons.location,
|
||||||
|
title: 'Countries',
|
||||||
|
trailing: StreamBuilder(
|
||||||
|
stream: source.eventBus.on<LocationsChangedEvent>(),
|
||||||
|
builder: (context, _) => Text('${source.sortedCountries.length}'),
|
||||||
|
),
|
||||||
|
routeName: CountryListPage.routeName,
|
||||||
|
pageBuilder: (_) => CountryListPage(source: source),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get tagListTile => NavTile(
|
||||||
|
icon: AIcons.tag,
|
||||||
|
title: 'Tags',
|
||||||
|
trailing: StreamBuilder(
|
||||||
|
stream: source.eventBus.on<TagsChangedEvent>(),
|
||||||
|
builder: (context, _) => Text('${source.sortedTags.length}'),
|
||||||
|
),
|
||||||
|
routeName: TagListPage.routeName,
|
||||||
|
pageBuilder: (_) => TagListPage(source: source),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get settingsTile => NavTile(
|
||||||
|
icon: AIcons.settings,
|
||||||
|
title: 'Preferences',
|
||||||
|
routeName: SettingsPage.routeName,
|
||||||
|
pageBuilder: (_) => SettingsPage(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get aboutTile => NavTile(
|
||||||
|
icon: AIcons.info,
|
||||||
|
title: 'About',
|
||||||
|
routeName: AboutPage.routeName,
|
||||||
|
pageBuilder: (_) => AboutPage(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget get debugTile => NavTile(
|
||||||
|
icon: AIcons.debug,
|
||||||
|
title: 'Debug',
|
||||||
|
routeName: DebugPage.routeName,
|
||||||
|
pageBuilder: (_) => DebugPage(source: source),
|
||||||
|
);
|
||||||
|
}
|
56
lib/widgets/drawer/collection_tile.dart
Normal file
56
lib/widgets/drawer/collection_tile.dart
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
import 'package:aves/model/settings.dart';
|
||||||
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
|
import 'package:aves/widgets/album/collection_page.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CollectionNavTile extends StatelessWidget {
|
||||||
|
final CollectionSource source;
|
||||||
|
final Widget leading;
|
||||||
|
final String title;
|
||||||
|
final Widget trailing;
|
||||||
|
final bool dense;
|
||||||
|
final CollectionFilter filter;
|
||||||
|
|
||||||
|
const CollectionNavTile({
|
||||||
|
@required this.source,
|
||||||
|
@required this.leading,
|
||||||
|
@required this.title,
|
||||||
|
this.trailing,
|
||||||
|
bool dense,
|
||||||
|
@required this.filter,
|
||||||
|
}) : dense = dense ?? false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SafeArea(
|
||||||
|
top: false,
|
||||||
|
bottom: false,
|
||||||
|
child: ListTile(
|
||||||
|
leading: leading,
|
||||||
|
title: Text(title),
|
||||||
|
trailing: trailing,
|
||||||
|
dense: dense,
|
||||||
|
onTap: () => _goToCollection(context),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _goToCollection(BuildContext context) {
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
settings: RouteSettings(name: CollectionPage.routeName),
|
||||||
|
builder: (context) => CollectionPage(CollectionLens(
|
||||||
|
source: source,
|
||||||
|
filters: [filter],
|
||||||
|
groupFactor: settings.collectionGroupFactor,
|
||||||
|
sortFactor: settings.collectionSortFactor,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
(route) => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
56
lib/widgets/drawer/tile.dart
Normal file
56
lib/widgets/drawer/tile.dart
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:aves/utils/flutter_utils.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class NavTile extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final String title;
|
||||||
|
final Widget trailing;
|
||||||
|
final String routeName;
|
||||||
|
final WidgetBuilder pageBuilder;
|
||||||
|
|
||||||
|
const NavTile({
|
||||||
|
@required this.icon,
|
||||||
|
@required this.title,
|
||||||
|
this.trailing,
|
||||||
|
@required this.routeName,
|
||||||
|
@required this.pageBuilder,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SafeArea(
|
||||||
|
top: false,
|
||||||
|
bottom: false,
|
||||||
|
child: ListTile(
|
||||||
|
key: Key('$title-tile'),
|
||||||
|
leading: Icon(icon),
|
||||||
|
title: Text(title),
|
||||||
|
trailing: trailing != null
|
||||||
|
? Builder(
|
||||||
|
builder: (context) => DefaultTextStyle.merge(
|
||||||
|
style: TextStyle(
|
||||||
|
color: IconTheme.of(context).color.withOpacity(.6),
|
||||||
|
),
|
||||||
|
child: trailing,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
if (routeName != context.currentRouteName) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
settings: RouteSettings(name: routeName),
|
||||||
|
builder: pageBuilder,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selected: context.currentRouteName == routeName,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,10 @@ 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/utils/durations.dart';
|
import 'package:aves/utils/durations.dart';
|
||||||
import 'package:aves/widgets/album/collection_page.dart';
|
import 'package:aves/widgets/album/collection_page.dart';
|
||||||
import 'package:aves/widgets/app_drawer.dart';
|
|
||||||
import 'package:aves/widgets/common/app_bar_subtitle.dart';
|
import 'package:aves/widgets/common/app_bar_subtitle.dart';
|
||||||
import 'package:aves/widgets/common/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/aves_filter_chip.dart';
|
||||||
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/data_providers/media_query_data_provider.dart';
|
||||||
|
import 'package:aves/widgets/drawer/app_drawer.dart';
|
||||||
import 'package:aves/widgets/filter_grids/decorated_filter_chip.dart';
|
import 'package:aves/widgets/filter_grids/decorated_filter_chip.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
import 'package:flutter_staggered_animations/flutter_staggered_animations.dart';
|
||||||
|
|
|
@ -91,7 +91,7 @@ void selectFirstAlbum() {
|
||||||
await driver.tap(find.byValueKey('appbar-leading-button'));
|
await driver.tap(find.byValueKey('appbar-leading-button'));
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
|
|
||||||
await driver.tap(find.byValueKey('albums-tile'));
|
await driver.tap(find.byValueKey('Albums-tile'));
|
||||||
await driver.waitUntilNoTransientCallbacks();
|
await driver.waitUntilNoTransientCallbacks();
|
||||||
|
|
||||||
await driver.tap(find.descendant(
|
await driver.tap(find.descendant(
|
||||||
|
|
Loading…
Reference in a new issue