Select all.

This commit is contained in:
stonegate 2020-10-11 18:09:36 +08:00
parent b1c778922b
commit b31cc38fad
1 changed files with 184 additions and 137 deletions

View File

@ -84,6 +84,8 @@ class _PodcastDetailState extends State<PodcastDetail> {
///Toggle for multi-select. ///Toggle for multi-select.
bool _multiSelect; bool _multiSelect;
bool _selectAll;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -92,6 +94,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
_controller = ScrollController(); _controller = ScrollController();
_scroll = false; _scroll = false;
_multiSelect = false; _multiSelect = false;
_selectAll = false;
} }
@override @override
@ -146,9 +149,9 @@ class _PodcastDetailState extends State<PodcastDetail> {
{int count, bool reverse, Filter filter, String query}) async { {int count, bool reverse, Filter filter, String query}) async {
var episodes = <EpisodeBrief>[]; var episodes = <EpisodeBrief>[];
_episodeCount = await _dbHelper.getPodcastCounts(podcastLocal.id); _episodeCount = await _dbHelper.getPodcastCounts(podcastLocal.id);
var storage = KeyValueStorage(podcastLayoutKey); final layoutStorage = KeyValueStorage(podcastLayoutKey);
var hideListenedStorage = KeyValueStorage(hideListenedKey); final hideListenedStorage = KeyValueStorage(hideListenedKey);
var index = await storage.getInt(defaultValue: 1); final index = await layoutStorage.getInt(defaultValue: 1);
if (_layout == null) _layout = Layout.values[index]; if (_layout == null) _layout = Layout.values[index];
if (_hideListened == null) { if (_hideListened == null) {
_hideListened = await hideListenedStorage.getBool(defaultValue: false); _hideListened = await hideListenedStorage.getBool(defaultValue: false);
@ -859,6 +862,9 @@ class _PodcastDetailState extends State<PodcastDetail> {
filter: _filter, filter: _filter,
query: _query), query: _query),
builder: (context, snapshot) { builder: (context, snapshot) {
if (_selectAll) {
_selectedEpisodes = snapshot.data;
}
return (snapshot.hasData) return (snapshot.hasData)
? EpisodeGrid( ? EpisodeGrid(
episodes: snapshot.data, episodes: snapshot.data,
@ -874,8 +880,10 @@ class _PodcastDetailState extends State<PodcastDetail> {
multiSelect: _multiSelect, multiSelect: _multiSelect,
selectedList: selectedList:
_selectedEpisodes ?? [], _selectedEpisodes ?? [],
onSelect: (value) => setState(() => onSelect: (value) => setState(() {
_selectedEpisodes = value), _selectAll = false;
_selectedEpisodes = value;
}),
) )
: SliverToBoxAdapter( : SliverToBoxAdapter(
child: Center(), child: Center(),
@ -907,9 +915,19 @@ class _PodcastDetailState extends State<PodcastDetail> {
if (_multiSelect) if (_multiSelect)
MultiSelectMenuBar( MultiSelectMenuBar(
selectedList: _selectedEpisodes, selectedList: _selectedEpisodes,
selectAll: _selectAll,
onSelectAll: (value) {
setState(() {
_selectAll = value;
_selectedEpisodes = [];
});
},
onClose: (value) { onClose: (value) {
setState(() { setState(() {
if (value) _multiSelect = false; if (value) {
_multiSelect = false;
_selectAll = false;
}
}); });
}, },
), ),
@ -936,9 +954,16 @@ class _PodcastDetailState extends State<PodcastDetail> {
} }
class MultiSelectMenuBar extends StatefulWidget { class MultiSelectMenuBar extends StatefulWidget {
MultiSelectMenuBar({this.selectedList, this.onClose, Key key}) MultiSelectMenuBar(
{this.selectedList,
this.selectAll,
this.onSelectAll,
this.onClose,
Key key})
: super(key: key); : super(key: key);
final List<EpisodeBrief> selectedList; final List<EpisodeBrief> selectedList;
final bool selectAll;
final ValueChanged<bool> onSelectAll;
final ValueChanged<bool> onClose; final ValueChanged<bool> onClose;
@override @override
@ -1121,138 +1146,160 @@ class _MultiSelectMenuBarState extends State<MultiSelectMenuBar> {
tween: Tween<double>(begin: 0, end: 1), tween: Tween<double>(begin: 0, end: 1),
duration: Duration(milliseconds: 500), duration: Duration(milliseconds: 500),
builder: (context, value, child) => Container( builder: (context, value, child) => Container(
height: 50.0 * value, height: 80.0 * value,
decoration: BoxDecoration(color: context.primaryColor), decoration: BoxDecoration(color: context.primaryColor),
child: Row( child: SingleChildScrollView(
children: [ child: Column(
_buttonOnMenu( mainAxisSize: MainAxisSize.min,
child: _liked children: [
? Icon(Icons.favorite, color: Colors.red) SizedBox(
: Icon( height: 30,
Icons.favorite_border, child: Align(
color: Colors.grey[700], alignment: Alignment.centerRight,
), child: Padding(
onTap: () async { padding: EdgeInsets.symmetric(horizontal: 20.0),
if (widget.selectedList.isNotEmpty) { child: Text('${widget.selectedList.length} selected',
if (!_liked) { style: context.textTheme.headline6
await _saveLiked(); .copyWith(color: context.accentColor))),
Fluttertoast.showToast(
msg: s.liked,
gravity: ToastGravity.BOTTOM,
);
} else {
await _setUnliked();
Fluttertoast.showToast(
msg: s.unliked,
gravity: ToastGravity.BOTTOM,
);
}
}
// OverlayEntry _overlayEntry;
// _overlayEntry = _createOverlayEntry();
// Overlay.of(context).insert(_overlayEntry);
// await Future.delayed(Duration(seconds: 2));
// _overlayEntry?.remove();
}),
_buttonOnMenu(
child: _downloaded
? Center(
child: SizedBox(
height: 20,
width: 20,
child: CustomPaint(
painter: DownloadPainter(
color: context.accentColor,
fraction: 1,
progressColor: context.accentColor,
progress: 1),
),
),
)
: Center(
child: SizedBox(
height: 20,
width: 20,
child: CustomPaint(
painter: DownloadPainter(
color: Colors.grey[700],
fraction: 0,
progressColor: context.accentColor,
),
),
),
),
onTap: () {
if (widget.selectedList.isNotEmpty) {
if (!_downloaded) _requestDownload();
}
},
),
_buttonOnMenu(
child: _inPlaylist
? Icon(Icons.playlist_add_check, color: context.accentColor)
: Icon(
Icons.playlist_add,
color: Colors.grey[700],
),
onTap: () async {
if (widget.selectedList.isNotEmpty) {
if (!_inPlaylist) {
for (var episode in widget.selectedList) {
audio.addToPlaylist(episode);
Fluttertoast.showToast(
msg: s.toastAddPlaylist,
gravity: ToastGravity.BOTTOM,
);
}
setState(() => _inPlaylist = true);
} else {
for (var episode in widget.selectedList) {
audio.delFromPlaylist(episode);
Fluttertoast.showToast(
msg: s.toastRemovePlaylist,
gravity: ToastGravity.BOTTOM,
);
}
setState(() => _inPlaylist = false);
}
}
}),
_buttonOnMenu(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: CustomPaint(
size: Size(25, 20),
painter: ListenedAllPainter(
_marked ? context.accentColor : Colors.grey[700],
stroke: 2.0),
),
), ),
onTap: () async { ),
if (widget.selectedList.isNotEmpty) { Row(
if (!_marked) { children: [
await _markListened(); _buttonOnMenu(
Fluttertoast.showToast( child: _liked
msg: s.markListened, ? Icon(Icons.favorite, color: Colors.red)
gravity: ToastGravity.BOTTOM, : Icon(
); Icons.favorite_border,
} else { color: Colors.grey[700],
await _markNotListened(); ),
Fluttertoast.showToast( onTap: () async {
msg: s.markNotListened, if (widget.selectedList.isNotEmpty) {
gravity: ToastGravity.BOTTOM, if (!_liked) {
); await _saveLiked();
} Fluttertoast.showToast(
} msg: s.liked,
}), gravity: ToastGravity.BOTTOM,
Spacer(), );
Padding( } else {
padding: EdgeInsets.symmetric(horizontal: 10.0), await _setUnliked();
child: Text('${widget.selectedList.length} selected', Fluttertoast.showToast(
style: context.textTheme.headline6)), msg: s.unliked,
_buttonOnMenu( gravity: ToastGravity.BOTTOM,
child: Icon(Icons.close), onTap: () => widget.onClose(true)) );
], }
}
// OverlayEntry _overlayEntry;
// _overlayEntry = _createOverlayEntry();
// Overlay.of(context).insert(_overlayEntry);
// await Future.delayed(Duration(seconds: 2));
// _overlayEntry?.remove();
}),
_buttonOnMenu(
child: _downloaded
? Center(
child: SizedBox(
height: 20,
width: 20,
child: CustomPaint(
painter: DownloadPainter(
color: context.accentColor,
fraction: 1,
progressColor: context.accentColor,
progress: 1),
),
),
)
: Center(
child: SizedBox(
height: 20,
width: 20,
child: CustomPaint(
painter: DownloadPainter(
color: Colors.grey[700],
fraction: 0,
progressColor: context.accentColor,
),
),
),
),
onTap: () {
if (widget.selectedList.isNotEmpty) {
if (!_downloaded) _requestDownload();
}
},
),
_buttonOnMenu(
child: _inPlaylist
? Icon(Icons.playlist_add_check,
color: context.accentColor)
: Icon(
Icons.playlist_add,
color: Colors.grey[700],
),
onTap: () async {
if (widget.selectedList.isNotEmpty) {
if (!_inPlaylist) {
for (var episode in widget.selectedList) {
audio.addToPlaylist(episode);
Fluttertoast.showToast(
msg: s.toastAddPlaylist,
gravity: ToastGravity.BOTTOM,
);
}
setState(() => _inPlaylist = true);
} else {
for (var episode in widget.selectedList) {
audio.delFromPlaylist(episode);
Fluttertoast.showToast(
msg: s.toastRemovePlaylist,
gravity: ToastGravity.BOTTOM,
);
}
setState(() => _inPlaylist = false);
}
}
}),
_buttonOnMenu(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: CustomPaint(
size: Size(25, 20),
painter: ListenedAllPainter(
_marked ? context.accentColor : Colors.grey[700],
stroke: 2.0),
),
),
onTap: () async {
if (widget.selectedList.isNotEmpty) {
if (!_marked) {
await _markListened();
Fluttertoast.showToast(
msg: s.markListened,
gravity: ToastGravity.BOTTOM,
);
} else {
await _markNotListened();
Fluttertoast.showToast(
msg: s.markNotListened,
gravity: ToastGravity.BOTTOM,
);
}
}
}),
Spacer(),
_buttonOnMenu(
child: Icon(Icons.select_all_rounded,
color: widget.selectAll ? context.accentColor : null),
onTap: () {
widget.onSelectAll(!widget.selectAll);
}),
_buttonOnMenu(
child: Icon(Icons.close),
onTap: () => widget.onClose(true))
],
),
],
),
), ),
), ),
); );