mirror of
https://github.com/stonega/tsacdop
synced 2025-02-17 20:10:37 +01:00
Select before and select after.
This commit is contained in:
parent
7f66ebd7e6
commit
2e0e65f41a
@ -671,40 +671,78 @@ class DBHelper {
|
||||
var list = <Map>[];
|
||||
if (hideListened) {
|
||||
if (count == -1) {
|
||||
switch (filter) {
|
||||
case Filter.all:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
if (reverse) {
|
||||
switch (filter) {
|
||||
case Filter.all:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
LEFT JOIN PlayHistory H ON E.enclosure_url = H.enclosure_url
|
||||
WHERE P.id = ? GROUP BY E.enclosure_url HAVING SUM(H.listen_time) is null
|
||||
OR SUM(H.listen_time) = 0 ORDER BY E.milliseconds ASC""", [id]);
|
||||
break;
|
||||
case Filter.liked:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
break;
|
||||
case Filter.liked:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.liked = 1 ORDER BY E.milliseconds ASC""", [id]);
|
||||
break;
|
||||
case Filter.downloaded:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
break;
|
||||
case Filter.downloaded:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.media_id != E.enclosure_url ORDER BY E.milliseconds ASC""",
|
||||
[id]);
|
||||
break;
|
||||
case Filter.search:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
[id]);
|
||||
break;
|
||||
case Filter.search:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.title LIKE ? ORDER BY E.milliseconds ASC""",
|
||||
[id, '%$query%']);
|
||||
break;
|
||||
default:
|
||||
[id, '%$query%']);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
switch (filter) {
|
||||
case Filter.all:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
LEFT JOIN PlayHistory H ON E.enclosure_url = H.enclosure_url
|
||||
WHERE P.id = ? GROUP BY E.enclosure_url HAVING SUM(H.listen_time) is null
|
||||
OR SUM(H.listen_time) = 0 ORDER BY E.milliseconds DESC""", [id]);
|
||||
break;
|
||||
case Filter.liked:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.liked = 1 ORDER BY E.milliseconds DESC""", [id]);
|
||||
break;
|
||||
case Filter.downloaded:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.media_id != E.enclosure_url ORDER BY E.milliseconds DESC""",
|
||||
[id]);
|
||||
break;
|
||||
case Filter.search:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.title LIKE ? ORDER BY E.milliseconds DESC""",
|
||||
[id, '%$query%']);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
} else if (reverse) {
|
||||
switch (filter) {
|
||||
@ -798,38 +836,74 @@ class DBHelper {
|
||||
}
|
||||
} else {
|
||||
if (count == -1) {
|
||||
switch (filter) {
|
||||
case Filter.all:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
if (reverse) {
|
||||
switch (filter) {
|
||||
case Filter.all:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? ORDER BY E.milliseconds ASC""", [id]);
|
||||
break;
|
||||
case Filter.liked:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
break;
|
||||
case Filter.liked:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.liked = 1 ORDER BY E.milliseconds ASC""", [id]);
|
||||
break;
|
||||
case Filter.downloaded:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
break;
|
||||
case Filter.downloaded:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.media_id != E.enclosure_url ORDER BY E.milliseconds ASC""",
|
||||
[id]);
|
||||
break;
|
||||
case Filter.search:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
[id]);
|
||||
break;
|
||||
case Filter.search:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.title LIKE ? ORDER BY E.milliseconds ASC""",
|
||||
[id, '%$query%']);
|
||||
break;
|
||||
default:
|
||||
[id, '%$query%']);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} else {
|
||||
switch (filter) {
|
||||
case Filter.all:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? ORDER BY E.milliseconds DESC""", [id]);
|
||||
break;
|
||||
case Filter.liked:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.liked = 1 ORDER BY E.milliseconds DESC""", [id]);
|
||||
break;
|
||||
case Filter.downloaded:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.media_id != E.enclosure_url ORDER BY E.milliseconds DESC""",
|
||||
[id]);
|
||||
break;
|
||||
case Filter.search:
|
||||
list = await dbClient.rawQuery(
|
||||
"""SELECT E.title, E.enclosure_url, E.enclosure_length,
|
||||
E.milliseconds, P.imagePath, P.title as feed_title, E.duration, E.explicit,
|
||||
P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
|
||||
WHERE P.id = ? AND E.title LIKE ? ORDER BY E.milliseconds DESC""",
|
||||
[id, '%$query%']);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
} else if (reverse) {
|
||||
switch (filter) {
|
||||
|
@ -86,6 +86,10 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
|
||||
bool _selectAll;
|
||||
|
||||
bool _selectBefore;
|
||||
|
||||
bool _selectAfter;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -95,6 +99,8 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
_scroll = false;
|
||||
_multiSelect = false;
|
||||
_selectAll = false;
|
||||
_selectAfter = false;
|
||||
_selectBefore = false;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -696,6 +702,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_top = -1;
|
||||
_selectedEpisodes = [];
|
||||
_multiSelect = true;
|
||||
});
|
||||
@ -862,32 +869,48 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
filter: _filter,
|
||||
query: _query),
|
||||
builder: (context, snapshot) {
|
||||
if (_selectAll) {
|
||||
_selectedEpisodes = snapshot.data;
|
||||
if (snapshot.hasData) {
|
||||
if (_selectAll) {
|
||||
_selectedEpisodes = snapshot.data;
|
||||
}
|
||||
if (_selectBefore) {
|
||||
final index = snapshot.data
|
||||
.indexOf(_selectedEpisodes.first);
|
||||
if (index != 0) {
|
||||
_selectedEpisodes = snapshot.data
|
||||
.sublist(0, index + 1);
|
||||
}
|
||||
}
|
||||
if (_selectAfter) {
|
||||
final index = snapshot.data
|
||||
.indexOf(_selectedEpisodes.first);
|
||||
_selectedEpisodes =
|
||||
snapshot.data.sublist(index);
|
||||
}
|
||||
return EpisodeGrid(
|
||||
episodes: snapshot.data,
|
||||
showFavorite: true,
|
||||
showNumber: _filter == Filter.all &&
|
||||
!_hideListened
|
||||
? true
|
||||
: false,
|
||||
layout: _layout,
|
||||
reverse: _reverse,
|
||||
episodeCount: _episodeCount,
|
||||
initNum: _scroll ? 0 : 12,
|
||||
multiSelect: _multiSelect,
|
||||
selectedList: _selectedEpisodes ?? [],
|
||||
onSelect: (value) => setState(() {
|
||||
_selectAll = false;
|
||||
_selectBefore = false;
|
||||
_selectAfter = false;
|
||||
_selectedEpisodes = value;
|
||||
}),
|
||||
);
|
||||
}
|
||||
return (snapshot.hasData)
|
||||
? EpisodeGrid(
|
||||
episodes: snapshot.data,
|
||||
showFavorite: true,
|
||||
showNumber: _filter == Filter.all &&
|
||||
!_hideListened
|
||||
? true
|
||||
: false,
|
||||
layout: _layout,
|
||||
reverse: _reverse,
|
||||
episodeCount: _episodeCount,
|
||||
initNum: _scroll ? 0 : 12,
|
||||
multiSelect: _multiSelect,
|
||||
selectedList:
|
||||
_selectedEpisodes ?? [],
|
||||
onSelect: (value) => setState(() {
|
||||
_selectAll = false;
|
||||
_selectedEpisodes = value;
|
||||
}),
|
||||
)
|
||||
: SliverToBoxAdapter(
|
||||
child: Center(),
|
||||
);
|
||||
return SliverToBoxAdapter(
|
||||
child: Center(),
|
||||
);
|
||||
}),
|
||||
SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
@ -919,7 +942,23 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
onSelectAll: (value) {
|
||||
setState(() {
|
||||
_selectAll = value;
|
||||
_selectedEpisodes = [];
|
||||
_selectAfter = false;
|
||||
_selectBefore = false;
|
||||
if (!value) {
|
||||
_selectedEpisodes = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
onSelectAfter: (value) {
|
||||
setState(() {
|
||||
_selectBefore = false;
|
||||
_selectAfter = true;
|
||||
});
|
||||
},
|
||||
onSelectBefore: (value) {
|
||||
setState(() {
|
||||
_selectAfter = false;
|
||||
_selectBefore = true;
|
||||
});
|
||||
},
|
||||
onClose: (value) {
|
||||
@ -927,6 +966,8 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
if (value) {
|
||||
_multiSelect = false;
|
||||
_selectAll = false;
|
||||
_selectAfter = false;
|
||||
_selectBefore = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -959,12 +1000,16 @@ class MultiSelectMenuBar extends StatefulWidget {
|
||||
this.selectAll,
|
||||
this.onSelectAll,
|
||||
this.onClose,
|
||||
this.onSelectAfter,
|
||||
this.onSelectBefore,
|
||||
Key key})
|
||||
: super(key: key);
|
||||
final List<EpisodeBrief> selectedList;
|
||||
final bool selectAll;
|
||||
final ValueChanged<bool> onSelectAll;
|
||||
final ValueChanged<bool> onClose;
|
||||
final ValueChanged<bool> onSelectBefore;
|
||||
final ValueChanged<bool> onSelectAfter;
|
||||
|
||||
@override
|
||||
_MultiSelectMenuBarState createState() => _MultiSelectMenuBarState();
|
||||
@ -1146,22 +1191,84 @@ class _MultiSelectMenuBarState extends State<MultiSelectMenuBar> {
|
||||
tween: Tween<double>(begin: 0, end: 1),
|
||||
duration: Duration(milliseconds: 500),
|
||||
builder: (context, value, child) => Container(
|
||||
height: 80.0 * value,
|
||||
height: 90.0 * value,
|
||||
decoration: BoxDecoration(color: context.primaryColor),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 30,
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Text('${widget.selectedList.length} selected',
|
||||
style: context.textTheme.headline6
|
||||
.copyWith(color: context.accentColor))),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Text('${widget.selectedList.length} selected',
|
||||
style: context.textTheme.headline6
|
||||
.copyWith(color: context.accentColor))),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
if (widget.selectedList.length == 1)
|
||||
SizedBox(
|
||||
height: 25,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(color: context.accentColor),
|
||||
primary: context.textColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(100)))),
|
||||
onPressed: () {
|
||||
widget.onSelectBefore(true);
|
||||
},
|
||||
child: Text('Before')),
|
||||
),
|
||||
),
|
||||
if (widget.selectedList.length == 1)
|
||||
SizedBox(
|
||||
height: 25,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(color: context.accentColor),
|
||||
primary: context.textColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(100)))),
|
||||
onPressed: () {
|
||||
widget.onSelectAfter(true);
|
||||
},
|
||||
child: Text('After')),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 25,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(color: context.accentColor),
|
||||
backgroundColor:
|
||||
widget.selectAll ? context.accentColor : null,
|
||||
primary: widget.selectAll
|
||||
? Colors.white
|
||||
: context.textColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(100)))),
|
||||
onPressed: () {
|
||||
widget.onSelectAll(!widget.selectAll);
|
||||
},
|
||||
child: Text('All')),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
@ -1287,12 +1394,6 @@ class _MultiSelectMenuBarState extends State<MultiSelectMenuBar> {
|
||||
}
|
||||
}),
|
||||
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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user