Create playlists with new options.

This commit is contained in:
Stonegate 2021-01-01 02:08:23 +08:00
parent b25093583a
commit b3e1d4cb42
2 changed files with 80 additions and 95 deletions

View File

@ -1119,6 +1119,45 @@ class DBHelper {
return episodes;
}
Future<List<EpisodeBrief>> getRandomRssItem(int random,
{bool hideListened = false}) async {
var dbClient = await database;
var episodes = <EpisodeBrief>[];
var list = <Map>[];
if (hideListened) {
list = await dbClient.rawQuery(
"""SELECT E.title, E.enclosure_url, E.enclosure_length, E.is_new,
E.milliseconds, P.title as feed_title, E.duration, E.explicit,
P.imagePath, 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
GROUP BY E.enclosure_url HAVING SUM(H.listen_time) is null
OR SUM(H.listen_time) = 0 ORDER BY RANDOM() LIMIT ? """,
[random]);
} else {
list = await dbClient.rawQuery(
"""SELECT E.title, E.enclosure_url, E.enclosure_length, E.is_new,
E.milliseconds, P.title as feed_title, E.duration, E.explicit,
P.imagePath, P.primaryColor FROM Episodes E INNER JOIN PodcastLocal P ON E.feed_id = P.id
ORDER BY RANDOM() LIMIT ? """, [random]);
}
if (list.isNotEmpty) {
for (var i in list) {
episodes.add(EpisodeBrief(
i['title'],
i['enclosure_url'],
i['enclosure_length'],
i['milliseconds'],
i['feed_title'],
i['primaryColor'],
i['duration'],
i['explicit'],
i['imagePath'],
i['is_new']));
}
}
return episodes;
}
Future<List<EpisodeBrief>> getGroupRssItem(int top, List<String> group,
{bool hideListened = false}) async {
var dbClient = await database;
@ -1361,7 +1400,7 @@ class DBHelper {
Future<void> removeGroupNewMark(List<String> group) async {
var dbClient = await database;
if (group.length > 0) {
if (group.isNotEmpty) {
var s = group.map<String>((e) => "'$e'").toList();
await dbClient.transaction((txn) async {
await txn.rawUpdate(

View File

@ -168,7 +168,7 @@ class _PlaylistHomeState extends State<PlaylistHome> {
)
],
)),
data.item3 != null
data.item4 != null
? ClipRRect(
borderRadius: BorderRadius.circular(10),
child: InkWell(
@ -285,9 +285,10 @@ class __QueueState extends State<_Queue> {
key: ValueKey(episode.enclosureUrl),
);
} else {
return Container(
key: ValueKey('sd'),
);
return EpisodeCard(episode,
key: ValueKey('playing'),
isPlaying: true,
tileColor: context.primaryColorDark);
}
}).toList()
: episodes
@ -301,98 +302,19 @@ class __QueueState extends State<_Queue> {
itemCount: queue.episodeList.length,
itemBuilder: (context, index) {
final episode = queue.episodes[index];
final c = episode.backgroudColor(context);
final isPlaying =
data.item3 != null && data.item3 == episode;
return SizedBox(
height: 90.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
child: ListTile(
tileColor:
isPlaying ? context.primaryColorDark : null,
contentPadding: EdgeInsets.symmetric(vertical: 8),
onTap: () async {
if (!isPlaying) {
await context
.read<AudioPlayerNotifier>()
.loadEpisodeFromPlaylist(episode);
}
},
title: Container(
padding: EdgeInsets.fromLTRB(0, 5.0, 20.0, 5.0),
child: Text(
episode.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
leading: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
// Icon(Icons.unfold_more, color: c),
SizedBox(width: 24),
CircleAvatar(
backgroundColor: c.withOpacity(0.5),
backgroundImage: episode.avatarImage),
],
),
subtitle: Container(
padding: EdgeInsets.only(top: 5, bottom: 5),
height: 35,
child: Row(
children: <Widget>[
if (episode.explicit == 1)
Container(
decoration: BoxDecoration(
color: Colors.red[800],
shape: BoxShape.circle),
height: 25.0,
width: 25.0,
margin: EdgeInsets.only(right: 10.0),
alignment: Alignment.center,
child: Text('E',
style: TextStyle(
color: Colors.white))),
if (episode.duration != 0)
episodeTag(
episode.duration == 0
? ''
: s.minsCount(
episode.duration ~/ 60),
Colors.cyan[300]),
if (episode.enclosureLength != null)
episodeTag(
episode.enclosureLength == 0
? ''
: '${(episode.enclosureLength) ~/ 1000000}MB',
Colors.lightBlue[300]),
],
),
),
trailing: isPlaying && running
? Container(
height: 20,
width: 20,
margin:
EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
shape: BoxShape.circle,
),
child: WaveLoader(
color: context.accentColor))
: SizedBox(width: 1),
),
),
Divider(
height: 2,
),
],
),
return EpisodeCard(
episode,
isPlaying: isPlaying && running,
tileColor: isPlaying ? context.primaryColorDark : null,
onTap: () async {
if (!isPlaying) {
await context
.read<AudioPlayerNotifier>()
.loadEpisodeFromPlaylist(episode);
}
},
);
});
});
@ -857,6 +779,7 @@ class _NewPlaylist extends StatefulWidget {
}
class __NewPlaylistState extends State<_NewPlaylist> {
final _dbHelper = DBHelper();
String _playlistName = '';
NewPlaylistOption _option;
int _error;
@ -867,6 +790,14 @@ class __NewPlaylistState extends State<_NewPlaylist> {
_option = NewPlaylistOption.blank;
}
Future<List<EpisodeBrief>> _random() async {
return await _dbHelper.getRandomRssItem(10);
}
Future<List<EpisodeBrief>> _recent() async {
return await _dbHelper.getRecentRssItem(10);
}
Widget _createOption(NewPlaylistOption option) {
return Padding(
padding: const EdgeInsets.all(8.0),
@ -954,7 +885,22 @@ class __NewPlaylistState extends State<_NewPlaylist> {
);
break;
case NewPlaylistOption.latest10:
final recent = await _recent();
playlist = Playlist(
_playlistName,
episodeList: [for(var e in recent) e.enclosureUrl],
);
await playlist.getPlaylist();
break;
case NewPlaylistOption.randon10:
final random = await _random();
playlist = Playlist(
_playlistName,
episodeList: [for(var e in random) e.enclosureUrl],
);
await playlist.getPlaylist();
break;
default:
break;
}
context.read<AudioPlayerNotifier>().addPlaylist(playlist);