mirror of
https://github.com/stonega/tsacdop
synced 2025-02-18 04:20:37 +01:00
Change add new episode to playlist icon
Add duration picker initial duration
This commit is contained in:
parent
0040513380
commit
60e066d2a9
@ -6,7 +6,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
classpath 'com.android.tools.build:gradle:3.6.2'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,11 +91,13 @@ class Playlist {
|
|||||||
addToPlayList(EpisodeBrief episodeBrief) async {
|
addToPlayList(EpisodeBrief episodeBrief) async {
|
||||||
_playlist.add(episodeBrief);
|
_playlist.add(episodeBrief);
|
||||||
await savePlaylist();
|
await savePlaylist();
|
||||||
|
dbHelper.removeEpisodeNewMark(episodeBrief.enclosureUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
addToPlayListAt(EpisodeBrief episodeBrief, int index) async {
|
addToPlayListAt(EpisodeBrief episodeBrief, int index) async {
|
||||||
_playlist.insert(index, episodeBrief);
|
_playlist.insert(index, episodeBrief);
|
||||||
await savePlaylist();
|
await savePlaylist();
|
||||||
|
dbHelper.removeEpisodeNewMark(episodeBrief.enclosureUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> delFromPlaylist(EpisodeBrief episodeBrief) async {
|
Future<int> delFromPlaylist(EpisodeBrief episodeBrief) async {
|
||||||
@ -188,10 +190,10 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
|||||||
_setAutoAdd();
|
_setAutoAdd();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getAutoAdd() async {
|
//Future _getAutoAdd() async {
|
||||||
int i = await autoAddStorage.getInt();
|
// int i = await autoAddStorage.getInt();
|
||||||
_autoAdd = i == 0 ? false : true;
|
// _autoAdd = i == 0 ? false : true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
Future _setAutoAdd() async {
|
Future _setAutoAdd() async {
|
||||||
await autoAddStorage.saveInt(_autoAdd ? 1 : 0);
|
await autoAddStorage.saveInt(_autoAdd ? 1 : 0);
|
||||||
@ -255,6 +257,8 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
//await _queue.savePlaylist();
|
//await _queue.savePlaylist();
|
||||||
_startAudioService(startPosition);
|
_startAudioService(startPosition);
|
||||||
|
if (episodeNew.isNew == 1)
|
||||||
|
dbHelper.removeEpisodeNewMark(episodeNew.enclosureUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +575,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||||||
|
|
||||||
bool get hasNext => _queue.length > 0;
|
bool get hasNext => _queue.length > 0;
|
||||||
|
|
||||||
MediaItem get mediaItem => _queue.first;
|
MediaItem get mediaItem => _queue.length > 0 ? _queue.first : null;
|
||||||
|
|
||||||
BasicPlaybackState _stateToBasicState(AudioPlaybackState state) {
|
BasicPlaybackState _stateToBasicState(AudioPlaybackState state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -644,19 +648,21 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||||||
Future<void> onSkipToNext() async {
|
Future<void> onSkipToNext() async {
|
||||||
_skipState = BasicPlaybackState.skippingToNext;
|
_skipState = BasicPlaybackState.skippingToNext;
|
||||||
await _audioPlayer.stop();
|
await _audioPlayer.stop();
|
||||||
_queue.removeAt(0);
|
if (_queue.length > 0) _queue.removeAt(0);
|
||||||
await AudioServiceBackground.setQueue(_queue);
|
await AudioServiceBackground.setQueue(_queue);
|
||||||
// }
|
// }
|
||||||
if (_queue.length == 0 || _stopAtEnd) {
|
if (_queue.length == 0 || _stopAtEnd) {
|
||||||
_skipState = null;
|
_skipState = null;
|
||||||
onStop();
|
onStop();
|
||||||
} else {
|
} else {
|
||||||
AudioServiceBackground.setQueue(_queue);
|
await AudioServiceBackground.setQueue(_queue);
|
||||||
AudioServiceBackground.setMediaItem(mediaItem);
|
await AudioServiceBackground.setMediaItem(mediaItem);
|
||||||
await _audioPlayer.setUrl(mediaItem.id);
|
await _audioPlayer.setUrl(mediaItem.id);
|
||||||
Duration duration = await _audioPlayer.durationFuture ?? Duration.zero;
|
print(mediaItem.title);
|
||||||
AudioServiceBackground.setMediaItem(
|
Duration duration = await _audioPlayer.durationFuture;
|
||||||
mediaItem.copyWith(duration: duration.inMilliseconds));
|
if(duration != null)
|
||||||
|
await AudioServiceBackground.setMediaItem(
|
||||||
|
mediaItem.copyWith(duration: duration.inMilliseconds));
|
||||||
_skipState = null;
|
_skipState = null;
|
||||||
// Resume playback if we were playing
|
// Resume playback if we were playing
|
||||||
// if (_playing) {
|
// if (_playing) {
|
||||||
@ -674,9 +680,10 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||||||
_playing = true;
|
_playing = true;
|
||||||
// await AudioServiceBackground.setQueue(_queue);
|
// await AudioServiceBackground.setQueue(_queue);
|
||||||
await _audioPlayer.setUrl(mediaItem.id);
|
await _audioPlayer.setUrl(mediaItem.id);
|
||||||
Duration duration = await _audioPlayer.durationFuture;
|
var duration = await _audioPlayer.durationFuture;
|
||||||
AudioServiceBackground.setMediaItem(
|
if (duration != null)
|
||||||
mediaItem.copyWith(duration: duration.inMilliseconds));
|
await AudioServiceBackground.setMediaItem(
|
||||||
|
mediaItem.copyWith(duration: duration.inMilliseconds));
|
||||||
}
|
}
|
||||||
// if (mediaItem.extras['skip'] > 0) {
|
// if (mediaItem.extras['skip'] > 0) {
|
||||||
// await _audioPlayer.setClip(
|
// await _audioPlayer.setClip(
|
||||||
@ -684,8 +691,9 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||||||
// print(mediaItem.extras['skip']);
|
// print(mediaItem.extras['skip']);
|
||||||
// print('set clip success');
|
// print('set clip success');
|
||||||
// }
|
// }
|
||||||
_playing = true;
|
else
|
||||||
_audioPlayer.play();
|
_playing = true;
|
||||||
|
await _audioPlayer.play();
|
||||||
if (mediaItem.extras['skip'] > 0) {
|
if (mediaItem.extras['skip'] > 0) {
|
||||||
_audioPlayer.seek(Duration(seconds: mediaItem.extras['skip']));
|
_audioPlayer.seek(Duration(seconds: mediaItem.extras['skip']));
|
||||||
}
|
}
|
||||||
@ -716,7 +724,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||||||
await _audioPlayer.stop();
|
await _audioPlayer.stop();
|
||||||
_setState(state: BasicPlaybackState.stopped);
|
_setState(state: BasicPlaybackState.stopped);
|
||||||
await Future.delayed(Duration(milliseconds: 500));
|
await Future.delayed(Duration(milliseconds: 500));
|
||||||
_completer.complete();
|
_completer?.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -56,6 +56,7 @@ class EpisodeBrief {
|
|||||||
title: title,
|
title: title,
|
||||||
artist: feedTitle,
|
artist: feedTitle,
|
||||||
album: feedTitle,
|
album: feedTitle,
|
||||||
|
// duration: 0,
|
||||||
artUri: 'file://$imagePath',
|
artUri: 'file://$imagePath',
|
||||||
extras: {'skip': skipSeconds});
|
extras: {'skip': skipSeconds});
|
||||||
}
|
}
|
||||||
|
@ -182,12 +182,11 @@ class GroupList extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future updatePodcast(String id) async {
|
Future updatePodcast(String id) async {
|
||||||
List<int> counts = await dbHelper.getPodcastCounts(id);
|
int counts = await dbHelper.getPodcastCounts(id);
|
||||||
_groups.forEach((group) {
|
_groups.forEach((group) {
|
||||||
if (group.podcastList.contains(id)) {
|
if (group.podcastList.contains(id)) {
|
||||||
group.podcasts.firstWhere((podcast) => podcast.id == id)
|
group.podcasts.firstWhere((podcast) => podcast.id == id)
|
||||||
..upateCount = counts[0]
|
..episodeCount = counts;
|
||||||
..episodeCount = counts[1];
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,7 @@ class SubscribeWorker extends ChangeNotifier {
|
|||||||
SubscribeItem _currentSubscribeItem = SubscribeItem('', '');
|
SubscribeItem _currentSubscribeItem = SubscribeItem('', '');
|
||||||
bool _created = false;
|
bool _created = false;
|
||||||
|
|
||||||
setSubscribeItem(SubscribeItem item) async{
|
setSubscribeItem(SubscribeItem item) async {
|
||||||
_subscribeItem = item;
|
_subscribeItem = item;
|
||||||
await _start();
|
await _start();
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ Future<void> subIsolateEntryPoint(SendPort sendPort) async {
|
|||||||
|
|
||||||
sendPort.send([item.title, item.url, 3, uuid]);
|
sendPort.send([item.title, item.url, 3, uuid]);
|
||||||
|
|
||||||
await Future.delayed(Duration(seconds: 5));
|
await Future.delayed(Duration(seconds: 2));
|
||||||
|
|
||||||
sendPort.send([item.title, item.url, 4]);
|
sendPort.send([item.title, item.url, 4]);
|
||||||
items.removeWhere((element) => element.url == item.url);
|
items.removeWhere((element) => element.url == item.url);
|
||||||
@ -165,7 +165,7 @@ Future<void> subIsolateEntryPoint(SendPort sendPort) async {
|
|||||||
sendPort.send("done");
|
sendPort.send("done");
|
||||||
} else {
|
} else {
|
||||||
sendPort.send([item.title, item.url, 5]);
|
sendPort.send([item.title, item.url, 5]);
|
||||||
await Future.delayed(Duration(seconds: 5));
|
await Future.delayed(Duration(seconds: 2));
|
||||||
sendPort.send([item.title, item.url, 4]);
|
sendPort.send([item.title, item.url, 4]);
|
||||||
items.removeWhere((element) => element.url == item.url);
|
items.removeWhere((element) => element.url == item.url);
|
||||||
if (items.length > 0) {
|
if (items.length > 0) {
|
||||||
@ -175,7 +175,7 @@ Future<void> subIsolateEntryPoint(SendPort sendPort) async {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendPort.send([item.title, item.url, 6]);
|
sendPort.send([item.title, item.url, 6]);
|
||||||
await Future.delayed(Duration(seconds: 5));
|
await Future.delayed(Duration(seconds: 2));
|
||||||
sendPort.send([item.title, item.url, 4]);
|
sendPort.send([item.title, item.url, 4]);
|
||||||
items.removeWhere((element) => element.url == item.url);
|
items.removeWhere((element) => element.url == item.url);
|
||||||
if (items.length > 0) {
|
if (items.length > 0) {
|
||||||
|
@ -72,14 +72,14 @@ class AboutApp extends StatelessWidget {
|
|||||||
image: AssetImage('assets/logo.png'),
|
image: AssetImage('assets/logo.png'),
|
||||||
height: 80,
|
height: 80,
|
||||||
),
|
),
|
||||||
Text('Version: 0.1.9'),
|
Text('Version: 0.2.0'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 50),
|
padding: EdgeInsets.symmetric(horizontal: 50),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Tsacdop is a podcast player developed in flutter, a simply beautiful and friendly app.',
|
'Tsacdop is a podcast player developed in flutter, a clean, simply beautiful and friendly app.',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -34,7 +34,7 @@ class Import extends StatelessWidget {
|
|||||||
SubscribeItem item = subscribeWorker.currentSubscribeItem;
|
SubscribeItem item = subscribeWorker.currentSubscribeItem;
|
||||||
switch (item.subscribeState) {
|
switch (item.subscribeState) {
|
||||||
case SubscribeState.start:
|
case SubscribeState.start:
|
||||||
return importColumn("Subscribe: ${item.title}", context);
|
return importColumn("Subscribe ${item.title}", context);
|
||||||
case SubscribeState.subscribe:
|
case SubscribeState.subscribe:
|
||||||
groupList.subscribeNewPodcast(item.id);
|
groupList.subscribeNewPodcast(item.id);
|
||||||
return importColumn("Fetch data ${item.title}", context);
|
return importColumn("Fetch data ${item.title}", context);
|
||||||
|
@ -507,33 +507,42 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Selector<AudioPlayerNotifier,
|
child: Selector<AudioPlayerNotifier,
|
||||||
Tuple2<BasicPlaybackState, double>>(
|
Tuple3<BasicPlaybackState, double, String>>(
|
||||||
selector: (_, audio) => Tuple2(
|
selector: (_, audio) => Tuple3(
|
||||||
audio.audioState,
|
audio.audioState,
|
||||||
(audio.backgroundAudioDuration -
|
(audio.backgroundAudioDuration -
|
||||||
audio.backgroundAudioPosition) /
|
audio.backgroundAudioPosition) /
|
||||||
1000),
|
1000,
|
||||||
|
audio.remoteErrorMessage),
|
||||||
builder: (_, data, __) {
|
builder: (_, data, __) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: data.item1 == BasicPlaybackState.buffering ||
|
child: data.item3 != null
|
||||||
data.item1 == BasicPlaybackState.connecting
|
? Text(data.item3,
|
||||||
? Text(
|
style: const TextStyle(
|
||||||
'Buffring...',
|
color: const Color(0xFFFF0000)))
|
||||||
style: TextStyle(
|
: data.item1 == BasicPlaybackState.buffering ||
|
||||||
color: Theme.of(context).accentColor),
|
data.item1 ==
|
||||||
)
|
BasicPlaybackState.connecting ||
|
||||||
: Row(
|
data.item1 ==
|
||||||
children: <Widget>[
|
BasicPlaybackState.skippingToNext ||
|
||||||
Text(
|
data.item1 == BasicPlaybackState.stopped
|
||||||
_stringForSeconds(data.item2) ?? '',
|
? Text(
|
||||||
|
'Buffring...',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).accentColor),
|
||||||
|
)
|
||||||
|
: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
_stringForSeconds(data.item2) ?? '',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
' Left',
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Text(
|
|
||||||
' Left',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -1278,7 +1287,10 @@ class _ControlPanelState extends State<ControlPanel>
|
|||||||
BasicPlaybackState
|
BasicPlaybackState
|
||||||
.connecting ||
|
.connecting ||
|
||||||
data.audioState ==
|
data.audioState ==
|
||||||
BasicPlaybackState.none
|
BasicPlaybackState.none ||
|
||||||
|
data.audioState ==
|
||||||
|
BasicPlaybackState
|
||||||
|
.skippingToNext
|
||||||
? 'Buffring...'
|
? 'Buffring...'
|
||||||
: '',
|
: '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -29,10 +29,9 @@ class ScrollPodcasts extends StatefulWidget {
|
|||||||
class _ScrollPodcastsState extends State<ScrollPodcasts> {
|
class _ScrollPodcastsState extends State<ScrollPodcasts> {
|
||||||
int _groupIndex;
|
int _groupIndex;
|
||||||
|
|
||||||
Future<int> getPodcastCounts(String id) async {
|
Future<int> getPodcastUpdateCounts(String id) async {
|
||||||
var dbHelper = DBHelper();
|
var dbHelper = DBHelper();
|
||||||
List<int> list = await dbHelper.getPodcastCounts(id);
|
return await dbHelper.getPodcastUpdateCounts(id);
|
||||||
return list.first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -268,7 +267,7 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
|
|||||||
"${podcastLocal.imagePath}")),
|
"${podcastLocal.imagePath}")),
|
||||||
),
|
),
|
||||||
FutureBuilder<int>(
|
FutureBuilder<int>(
|
||||||
future: getPodcastCounts(
|
future: getPodcastUpdateCounts(
|
||||||
podcastLocal.id),
|
podcastLocal.id),
|
||||||
initialData: 0,
|
initialData: 0,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
@ -11,16 +11,16 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
|||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
|
||||||
import 'package:tsacdop/class/audiostate.dart';
|
import '../class/audiostate.dart';
|
||||||
import 'package:tsacdop/class/episodebrief.dart';
|
import '../class/episodebrief.dart';
|
||||||
import 'package:tsacdop/local_storage/sqflite_localpodcast.dart';
|
import '../local_storage/sqflite_localpodcast.dart';
|
||||||
import 'package:tsacdop/util/episodegrid.dart';
|
import '../util/episodegrid.dart';
|
||||||
import 'package:tsacdop/util/mypopupmenu.dart';
|
import '../util/mypopupmenu.dart';
|
||||||
import 'package:tsacdop/util/context_extension.dart';
|
import '../util/context_extension.dart';
|
||||||
import 'package:tsacdop/util/custompaint.dart';
|
import '../util/custompaint.dart';
|
||||||
|
|
||||||
import 'package:tsacdop/home/appbar/importompl.dart';
|
import '../home/appbar/importompl.dart';
|
||||||
import 'package:tsacdop/home/audioplayer.dart';
|
import '../home/audioplayer.dart';
|
||||||
import 'home_groups.dart';
|
import 'home_groups.dart';
|
||||||
import 'download_list.dart';
|
import 'download_list.dart';
|
||||||
|
|
||||||
@ -466,14 +466,24 @@ class _RecentUpdateState extends State<_RecentUpdate>
|
|||||||
future: _getUpdateCounts(_group),
|
future: _getUpdateCounts(_group),
|
||||||
initialData: 0,
|
initialData: 0,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return snapshot.data > 0
|
return snapshot.data != 0
|
||||||
? Material(
|
? Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip:
|
tooltip:
|
||||||
'Add new episodes to playlist',
|
'Add new episodes to playlist',
|
||||||
icon: Icon(
|
icon:
|
||||||
LineIcons.tasks_solid),
|
// Icon(Icons.playlist_add),
|
||||||
|
SizedBox(
|
||||||
|
height: 16,
|
||||||
|
width: 21,
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: AddToPlaylistPainter(
|
||||||
|
context
|
||||||
|
.textTheme
|
||||||
|
.bodyText1
|
||||||
|
.color,
|
||||||
|
Colors.red))),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await audio
|
await audio
|
||||||
.addNewEpisode(_group);
|
.addNewEpisode(_group);
|
||||||
@ -488,7 +498,23 @@ class _RecentUpdateState extends State<_RecentUpdate>
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
: Center();
|
: IconButton(
|
||||||
|
tooltip:
|
||||||
|
'Add new episodes to playlist',
|
||||||
|
icon:
|
||||||
|
// Icon(Icons.playlist_add),
|
||||||
|
SizedBox(
|
||||||
|
height: 16,
|
||||||
|
width: 21,
|
||||||
|
child: CustomPaint(
|
||||||
|
painter:
|
||||||
|
AddToPlaylistPainter(
|
||||||
|
context.textTheme
|
||||||
|
.bodyText1.color,
|
||||||
|
context.textTheme
|
||||||
|
.bodyText1.color,
|
||||||
|
))),
|
||||||
|
onPressed: () {});
|
||||||
}),
|
}),
|
||||||
Material(
|
Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
|
@ -102,12 +102,20 @@ class DBHelper {
|
|||||||
return podcastLocal;
|
return podcastLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<int>> getPodcastCounts(String id) async {
|
Future<int> getPodcastCounts(String id) async {
|
||||||
var dbClient = await database;
|
var dbClient = await database;
|
||||||
List<Map> list = await dbClient.rawQuery(
|
List<Map> list = await dbClient.rawQuery(
|
||||||
'SELECT update_count, episode_count FROM PodcastLocal WHERE id = ?',
|
'SELECT episode_count FROM PodcastLocal WHERE id = ?',
|
||||||
[id]);
|
[id]);
|
||||||
return [list.first['update_count'], list.first['episode_count']];
|
return list.first['episode_count'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getPodcastUpdateCounts(String id) async {
|
||||||
|
var dbClient = await database;
|
||||||
|
List<Map> list = await dbClient.rawQuery(
|
||||||
|
'SELECt count(*) as count FROM Episodes WHERE feed_id = ? AND is_new = 1',
|
||||||
|
[id]);
|
||||||
|
return list.first['count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getSkipSeconds(String id) async {
|
Future<int> getSkipSeconds(String id) async {
|
||||||
@ -518,7 +526,7 @@ class DBHelper {
|
|||||||
return 0;
|
return 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +585,6 @@ class DBHelper {
|
|||||||
return episodes;
|
return episodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<List<EpisodeBrief>> getNewEpisodes(String id) async {
|
Future<List<EpisodeBrief>> getNewEpisodes(String id) async {
|
||||||
var dbClient = await database;
|
var dbClient = await database;
|
||||||
List<EpisodeBrief> episodes = [];
|
List<EpisodeBrief> episodes = [];
|
||||||
@ -820,6 +827,12 @@ class DBHelper {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int> removeEpisodeNewMark(String url) async {
|
||||||
|
var dbClient = await database;
|
||||||
|
return await dbClient.rawUpdate(
|
||||||
|
"UPDATE Episodes SET is_new = 0 WHERE enclosure_url = ?", [url]);
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<EpisodeBrief>> getLikedRssItem(int i, int sortBy) async {
|
Future<List<EpisodeBrief>> getLikedRssItem(int i, int sortBy) async {
|
||||||
var dbClient = await database;
|
var dbClient = await database;
|
||||||
List<EpisodeBrief> episodes = List();
|
List<EpisodeBrief> episodes = List();
|
||||||
|
@ -38,22 +38,21 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
|||||||
List<PodcastHost> hosts;
|
List<PodcastHost> hosts;
|
||||||
Future _updateRssItem(PodcastLocal podcastLocal) async {
|
Future _updateRssItem(PodcastLocal podcastLocal) async {
|
||||||
var dbHelper = DBHelper();
|
var dbHelper = DBHelper();
|
||||||
try {
|
|
||||||
final result = await dbHelper.updatePodcastRss(podcastLocal);
|
final result = await dbHelper.updatePodcastRss(podcastLocal);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
msg: 'No Update',
|
msg: 'No Update',
|
||||||
gravity: ToastGravity.TOP,
|
gravity: ToastGravity.TOP,
|
||||||
);
|
);
|
||||||
} else {
|
} else if (result > 0) {
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
msg: 'Updated $result Episodes',
|
msg: 'Updated $result Episodes',
|
||||||
gravity: ToastGravity.TOP,
|
gravity: ToastGravity.TOP,
|
||||||
);
|
);
|
||||||
Provider.of<GroupList>(context, listen: false)
|
Provider.of<GroupList>(context, listen: false)
|
||||||
.updatePodcast(podcastLocal.id);
|
.updatePodcast(podcastLocal.id);
|
||||||
}
|
} else {
|
||||||
} catch (e) {
|
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
msg: 'Update failed, network error',
|
msg: 'Update failed, network error',
|
||||||
gravity: ToastGravity.TOP,
|
gravity: ToastGravity.TOP,
|
||||||
@ -217,7 +216,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
|||||||
color: Theme.of(context).accentColor,
|
color: Theme.of(context).accentColor,
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await _updateRssItem(widget.podcastLocal);
|
await _updateRssItem(widget.podcastLocal);
|
||||||
// audio.addNewEpisode(widget.podcastLocal.id);
|
// audio.addNewEpisode(widget.podcastLocal.id);
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -81,10 +81,12 @@ class _PodcastCardState extends State<PodcastCard>
|
|||||||
Animation _animation;
|
Animation _animation;
|
||||||
double _value;
|
double _value;
|
||||||
int _seconds;
|
int _seconds;
|
||||||
|
int _skipSeconds;
|
||||||
|
|
||||||
Future<int> getSkipSecond(String id) async {
|
Future<int> getSkipSecond(String id) async {
|
||||||
var dbHelper = DBHelper();
|
var dbHelper = DBHelper();
|
||||||
int seconds = await dbHelper.getSkipSeconds(id);
|
int seconds = await dbHelper.getSkipSeconds(id);
|
||||||
|
_skipSeconds = seconds;
|
||||||
return seconds;
|
return seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,12 +375,15 @@ class _PodcastCardState extends State<PodcastCard>
|
|||||||
left: 20,
|
left: 20,
|
||||||
right: 100,
|
right: 100,
|
||||||
bottom: 20),
|
bottom: 20),
|
||||||
title: Text('Skip seconds at the beginning'),
|
title:
|
||||||
|
Text('Skip seconds at the beginning'),
|
||||||
content: DurationPicker(
|
content: DurationPicker(
|
||||||
duration: Duration.zero,
|
duration: Duration(
|
||||||
|
seconds: _skipSeconds ?? 0),
|
||||||
onChange: (value) =>
|
onChange: (value) =>
|
||||||
_seconds = value.inSeconds,
|
_seconds = value.inSeconds,
|
||||||
),
|
),
|
||||||
|
|
||||||
// content: Text('test'),
|
// content: Text('test'),
|
||||||
actionsPadding: EdgeInsets.all(10),
|
actionsPadding: EdgeInsets.all(10),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
@ -402,7 +407,8 @@ class _PodcastCardState extends State<PodcastCard>
|
|||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'CONFIRM',
|
'CONFIRM',
|
||||||
style: TextStyle(color: context.accentColor),
|
style: TextStyle(
|
||||||
|
color: context.accentColor),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -154,6 +154,52 @@ class ListenedAllPainter extends CustomPainter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Add new episode to palylist
|
||||||
|
class AddToPlaylistPainter extends CustomPainter {
|
||||||
|
Color _color;
|
||||||
|
Color _textColor;
|
||||||
|
AddToPlaylistPainter(this._color, this._textColor);
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
Paint _paint = Paint()
|
||||||
|
..color = _color
|
||||||
|
..strokeWidth = 1
|
||||||
|
..strokeCap = StrokeCap.round
|
||||||
|
..style = PaintingStyle.stroke;
|
||||||
|
Path _path = Path();
|
||||||
|
_path.moveTo(0, 0);
|
||||||
|
_path.lineTo(size.width * 4 / 7, 0);
|
||||||
|
_path.moveTo(0, size.height / 3);
|
||||||
|
_path.lineTo(size.width * 4 / 7, size.height / 3);
|
||||||
|
_path.moveTo(0, size.height * 2 / 3);
|
||||||
|
_path.lineTo(size.width * 3 / 7, size.height * 2 / 3);
|
||||||
|
//_path.moveTo(size.width * 3 / 7, size.height * 2 / 3);
|
||||||
|
//_path.lineTo(size.width, size.height * 2 / 3);
|
||||||
|
//_path.moveTo(size.width * 5 / 7, size.height / 3);
|
||||||
|
//_path.lineTo(size.width * 5 / 7, size.height);
|
||||||
|
// _path.moveTo(size.width*5/7, size.height/4);
|
||||||
|
// _path.lineTo(size.width*11/14, 0);
|
||||||
|
// _path.lineTo(size.width*13/14, size.height/4);
|
||||||
|
// _path.lineTo(size.width, 0);
|
||||||
|
var textPainter = TextPainter(
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
text: TextSpan(
|
||||||
|
text: 'N',
|
||||||
|
style: TextStyle(
|
||||||
|
fontStyle: FontStyle.italic, color: _textColor, fontSize: 10),
|
||||||
|
))
|
||||||
|
..layout();
|
||||||
|
textPainter.paint(canvas, Offset(size.width * 4 / 7, size.height / 3));
|
||||||
|
canvas.drawPath(_path, _paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(CustomPainter oldDelegate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Wave play indicator
|
//Wave play indicator
|
||||||
class WavePainter extends CustomPainter {
|
class WavePainter extends CustomPainter {
|
||||||
double _fraction;
|
double _fraction;
|
||||||
|
10
pubspec.yaml
10
pubspec.yaml
@ -33,7 +33,7 @@ dev_dependencies:
|
|||||||
path_provider: ^1.6.5
|
path_provider: ^1.6.5
|
||||||
color_thief_flutter: ^1.0.2
|
color_thief_flutter: ^1.0.2
|
||||||
provider: ^4.0.5
|
provider: ^4.0.5
|
||||||
google_fonts: ^0.5.0+1
|
google_fonts: ^1.0.0
|
||||||
dio: ^3.0.9
|
dio: ^3.0.9
|
||||||
file_picker: ^1.6.3+1
|
file_picker: ^1.6.3+1
|
||||||
xml: ^3.5.0
|
xml: ^3.5.0
|
||||||
@ -44,14 +44,14 @@ dev_dependencies:
|
|||||||
intl: ^0.16.1
|
intl: ^0.16.1
|
||||||
url_launcher: ^5.4.2
|
url_launcher: ^5.4.2
|
||||||
image: ^2.1.12
|
image: ^2.1.12
|
||||||
shared_preferences: ^0.5.6+1
|
shared_preferences: ^0.5.7
|
||||||
uuid: ^2.0.4
|
uuid: ^2.0.4
|
||||||
tuple: ^1.0.3
|
tuple: ^1.0.3
|
||||||
cached_network_image: ^2.1.0+1
|
cached_network_image: ^2.1.0+1
|
||||||
workmanager: ^0.2.2
|
workmanager: ^0.2.2
|
||||||
flutter_colorpicker: ^0.3.2
|
flutter_colorpicker: ^0.3.4
|
||||||
app_settings: ^3.0.1
|
app_settings: ^3.0.1
|
||||||
fl_chart: ^0.9.0
|
fl_chart: ^0.9.3
|
||||||
audio_service: ^0.7.2
|
audio_service: ^0.7.2
|
||||||
just_audio:
|
just_audio:
|
||||||
git:
|
git:
|
||||||
@ -63,7 +63,7 @@ dev_dependencies:
|
|||||||
flutter_linkify: ^3.1.0
|
flutter_linkify: ^3.1.0
|
||||||
extended_nested_scroll_view: ^0.4.0
|
extended_nested_scroll_view: ^0.4.0
|
||||||
connectivity: ^0.4.8+2
|
connectivity: ^0.4.8+2
|
||||||
flare_flutter: ^2.0.1
|
flare_flutter: ^2.0.3
|
||||||
rxdart: ^0.24.0
|
rxdart: ^0.24.0
|
||||||
flutter_isolate: ^1.0.0+11
|
flutter_isolate: ^1.0.0+11
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user