Open playlist page default.
This commit is contained in:
parent
747aa47772
commit
4fe335ff69
|
@ -60,6 +60,8 @@ const String downloadPositionKey = 'downloadPositionKey';
|
||||||
const String deleteAfterPlayedKey = 'removeAfterPlayedKey';
|
const String deleteAfterPlayedKey = 'removeAfterPlayedKey';
|
||||||
const String playlistsAllKey = 'playlistsAllKey';
|
const String playlistsAllKey = 'playlistsAllKey';
|
||||||
const String playerStateKey = 'playerStateKey';
|
const String playerStateKey = 'playerStateKey';
|
||||||
|
const String openPlaylistDefaultKey = 'openPlaylistDefaultKey';
|
||||||
|
const String openAllPodcastDefaultKey = 'openAllPodcastDefaultKey';
|
||||||
|
|
||||||
class KeyValueStorage {
|
class KeyValueStorage {
|
||||||
final String key;
|
final String key;
|
||||||
|
|
|
@ -5,6 +5,8 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tsacdop/playlists/playlist_home.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
import 'generated/l10n.dart';
|
import 'generated/l10n.dart';
|
||||||
import 'home/home.dart';
|
import 'home/home.dart';
|
||||||
|
@ -52,15 +54,17 @@ Future main() async {
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<SettingState>(
|
return Selector<SettingState, Tuple3<ThemeMode, ThemeData, ThemeData>>(
|
||||||
builder: (_, setting, child) {
|
selector: (_, setting) =>
|
||||||
|
Tuple3(setting.theme, setting.lightTheme, setting.darkTheme),
|
||||||
|
builder: (_, data, child) {
|
||||||
return FeatureDiscovery(
|
return FeatureDiscovery(
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
themeMode: setting.theme,
|
themeMode: data.item1,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'Tsacdop',
|
title: 'Tsacdop',
|
||||||
theme: setting.lightTheme,
|
theme: data.item2,
|
||||||
darkTheme: setting.darkTheme,
|
darkTheme: data.item3,
|
||||||
localizationsDelegates: [
|
localizationsDelegates: [
|
||||||
S.delegate,
|
S.delegate,
|
||||||
GlobalMaterialLocalizations.delegate,
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
@ -68,11 +72,15 @@ class MyApp extends StatelessWidget {
|
||||||
GlobalCupertinoLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
],
|
],
|
||||||
supportedLocales: S.delegate.supportedLocales,
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
home: setting.showIntro ? SlideIntro(goto: Goto.home) : child,
|
home: context.read<SettingState>().showIntro
|
||||||
|
? SlideIntro(goto: Goto.home)
|
||||||
|
: context.read<SettingState>().openPlaylistDefault
|
||||||
|
? PlaylistHome()
|
||||||
|
: Home(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: FeatureDiscovery(child: Home()),
|
//child: FeatureDiscovery(child: Home()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,13 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:line_icons/line_icons.dart';
|
import 'package:line_icons/line_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tsacdop/util/pageroute.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
import '../home/home.dart';
|
||||||
import '../local_storage/sqflite_localpodcast.dart';
|
import '../local_storage/sqflite_localpodcast.dart';
|
||||||
import '../state/audio_state.dart';
|
import '../state/audio_state.dart';
|
||||||
|
import '../state/setting_state.dart';
|
||||||
import '../type/episodebrief.dart';
|
import '../type/episodebrief.dart';
|
||||||
import '../type/play_histroy.dart';
|
import '../type/play_histroy.dart';
|
||||||
import '../type/playlist.dart';
|
import '../type/playlist.dart';
|
||||||
|
@ -30,7 +33,9 @@ class _PlaylistHomeState extends State<PlaylistHome> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
Future.microtask(() => context.read<AudioPlayerNotifier>().initPlaylist());
|
||||||
super.initState();
|
super.initState();
|
||||||
|
//context.read<AudioPlayerNotifier>().initPlaylist();
|
||||||
_selected = 'PlayNext';
|
_selected = 'PlayNext';
|
||||||
_body = _Queue();
|
_body = _Queue();
|
||||||
}
|
}
|
||||||
|
@ -64,184 +69,195 @@ class _PlaylistHomeState extends State<PlaylistHome> {
|
||||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||||
),
|
),
|
||||||
child: Scaffold(
|
child: WillPopScope(
|
||||||
appBar: AppBar(
|
onWillPop: () {
|
||||||
leading: CustomBackButton(),
|
if (context.read<SettingState>().openPlaylistDefault) {
|
||||||
centerTitle: true,
|
Navigator.push(context, SlideRightRoute(page: Home()));
|
||||||
title: Selector<AudioPlayerNotifier, EpisodeBrief>(
|
return Future.value(false);
|
||||||
selector: (_, audio) => audio.episode,
|
} else {
|
||||||
builder: (_, data, __) {
|
return Future.value(true);
|
||||||
return Text(data?.title ?? '', maxLines: 1);
|
}
|
||||||
},
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: CustomBackButton(),
|
||||||
|
centerTitle: true,
|
||||||
|
title: Selector<AudioPlayerNotifier, EpisodeBrief>(
|
||||||
|
selector: (_, audio) => audio.episode,
|
||||||
|
builder: (_, data, __) {
|
||||||
|
return Text(data?.title ?? '', maxLines: 1);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
backgroundColor: context.scaffoldBackgroundColor,
|
||||||
),
|
),
|
||||||
backgroundColor: context.scaffoldBackgroundColor,
|
body: Column(
|
||||||
),
|
children: [
|
||||||
body: Column(
|
SizedBox(
|
||||||
children: [
|
height: 100,
|
||||||
SizedBox(
|
child: Selector<AudioPlayerNotifier,
|
||||||
height: 100,
|
Tuple4<Playlist, bool, bool, EpisodeBrief>>(
|
||||||
child: Selector<AudioPlayerNotifier,
|
selector: (_, audio) => Tuple4(audio.playlist,
|
||||||
Tuple4<Playlist, bool, bool, EpisodeBrief>>(
|
audio.playerRunning, audio.playing, audio.episode),
|
||||||
selector: (_, audio) => Tuple4(audio.playlist,
|
builder: (_, data, __) {
|
||||||
audio.playerRunning, audio.playing, audio.episode),
|
final running = data.item2;
|
||||||
builder: (_, data, __) {
|
final playing = data.item3;
|
||||||
final running = data.item2;
|
final audio = context.read<AudioPlayerNotifier>();
|
||||||
final playing = data.item3;
|
return Row(
|
||||||
final audio = context.read<AudioPlayerNotifier>();
|
children: [
|
||||||
return Row(
|
Expanded(
|
||||||
children: [
|
child: Column(
|
||||||
Expanded(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: Column(
|
children: [
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
Row(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Row(
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
IconButton(
|
||||||
children: [
|
icon: Icon(Icons.fast_rewind),
|
||||||
IconButton(
|
onPressed: () {
|
||||||
icon: Icon(Icons.fast_rewind),
|
if (running) {
|
||||||
onPressed: () {
|
audio.rewind();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
SizedBox(width: 30),
|
||||||
|
IconButton(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Icon(
|
||||||
|
playing
|
||||||
|
? LineIcons.pause_solid
|
||||||
|
: LineIcons.play_solid,
|
||||||
|
size: 40),
|
||||||
|
onPressed: () {
|
||||||
|
if (running) {
|
||||||
|
playing
|
||||||
|
? audio.pauseAduio()
|
||||||
|
: audio.resumeAudio();
|
||||||
|
} else {
|
||||||
|
context
|
||||||
|
.read<AudioPlayerNotifier>()
|
||||||
|
.playFromLastPosition();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
SizedBox(width: 30),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.fast_forward),
|
||||||
|
onPressed: () {
|
||||||
|
if (running) {
|
||||||
|
audio.fastForward();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (data.item2)
|
||||||
|
Selector<AudioPlayerNotifier,
|
||||||
|
Tuple3<bool, double, String>>(
|
||||||
|
selector: (_, audio) => Tuple3(
|
||||||
|
audio.buffering,
|
||||||
|
(audio.backgroundAudioDuration -
|
||||||
|
audio.backgroundAudioPosition) /
|
||||||
|
1000,
|
||||||
|
audio.remoteErrorMessage),
|
||||||
|
builder: (_, data, __) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10),
|
||||||
|
child: data.item3 != null
|
||||||
|
? Text(data.item3,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Color(0xFFFF0000)))
|
||||||
|
: data.item1
|
||||||
|
? Text(
|
||||||
|
s.buffering,
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
context.accentColor),
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
s.timeLeft((data.item2)
|
||||||
|
.toInt()
|
||||||
|
.toTime ??
|
||||||
|
''),
|
||||||
|
maxLines: 2,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
data.item4 != null
|
||||||
|
? ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
if (running) {
|
if (running) {
|
||||||
audio.rewind();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
SizedBox(width: 30),
|
|
||||||
IconButton(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
icon: Icon(
|
|
||||||
playing
|
|
||||||
? LineIcons.pause_solid
|
|
||||||
: LineIcons.play_solid,
|
|
||||||
size: 40),
|
|
||||||
onPressed: () {
|
|
||||||
if (running) {
|
|
||||||
playing
|
|
||||||
? audio.pauseAduio()
|
|
||||||
: audio.resumeAudio();
|
|
||||||
} else {
|
|
||||||
context
|
context
|
||||||
.read<AudioPlayerNotifier>()
|
.read<AudioPlayerNotifier>()
|
||||||
.playFromLastPosition();
|
.playNext();
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
SizedBox(width: 30),
|
child: SizedBox(
|
||||||
IconButton(
|
width: 80,
|
||||||
icon: Icon(Icons.fast_forward),
|
height: 80,
|
||||||
onPressed: () {
|
child: Image(
|
||||||
if (running) {
|
image: data.item4.avatarImage)),
|
||||||
audio.fastForward();
|
),
|
||||||
}
|
)
|
||||||
})
|
: Container(
|
||||||
],
|
decoration: BoxDecoration(
|
||||||
),
|
color: context.accentColor.withAlpha(70),
|
||||||
if (data.item2)
|
borderRadius: BorderRadius.circular(10)),
|
||||||
Selector<AudioPlayerNotifier,
|
width: 80,
|
||||||
Tuple3<bool, double, String>>(
|
height: 80),
|
||||||
selector: (_, audio) => Tuple3(
|
SizedBox(
|
||||||
audio.buffering,
|
width: 20,
|
||||||
(audio.backgroundAudioDuration -
|
),
|
||||||
audio.backgroundAudioPosition) /
|
],
|
||||||
1000,
|
);
|
||||||
audio.remoteErrorMessage),
|
},
|
||||||
builder: (_, data, __) {
|
),
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 10),
|
|
||||||
child: data.item3 != null
|
|
||||||
? Text(data.item3,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: Color(0xFFFF0000)))
|
|
||||||
: data.item1
|
|
||||||
? Text(
|
|
||||||
s.buffering,
|
|
||||||
style: TextStyle(
|
|
||||||
color: context.accentColor),
|
|
||||||
)
|
|
||||||
: Text(
|
|
||||||
s.timeLeft((data.item2)
|
|
||||||
.toInt()
|
|
||||||
.toTime ??
|
|
||||||
''),
|
|
||||||
maxLines: 2,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
data.item4 != null
|
|
||||||
? ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
if (running) {
|
|
||||||
context
|
|
||||||
.read<AudioPlayerNotifier>()
|
|
||||||
.playNext();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: SizedBox(
|
|
||||||
width: 80,
|
|
||||||
height: 80,
|
|
||||||
child:
|
|
||||||
Image(image: data.item4.avatarImage)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: context.accentColor.withAlpha(70),
|
|
||||||
borderRadius: BorderRadius.circular(10)),
|
|
||||||
width: 80,
|
|
||||||
height: 80),
|
|
||||||
SizedBox(
|
|
||||||
width: 20,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
SizedBox(
|
height: 50,
|
||||||
height: 50,
|
child: Row(
|
||||||
child: Row(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
||||||
children: [
|
_tabWidget(
|
||||||
_tabWidget(
|
icon: Icon(Icons.queue_music_rounded),
|
||||||
icon: Icon(Icons.queue_music_rounded),
|
label: s.playNext,
|
||||||
label: s.playNext,
|
color: Colors.blue,
|
||||||
color: Colors.blue,
|
isSelected: _selected == 'PlayNext',
|
||||||
isSelected: _selected == 'PlayNext',
|
onTap: () => setState(() {
|
||||||
onTap: () => setState(() {
|
_body = _Queue();
|
||||||
_body = _Queue();
|
_selected = 'PlayNext';
|
||||||
_selected = 'PlayNext';
|
})),
|
||||||
})),
|
_tabWidget(
|
||||||
_tabWidget(
|
icon: Icon(Icons.history),
|
||||||
icon: Icon(Icons.history),
|
label: s.settingsHistory,
|
||||||
label: s.settingsHistory,
|
color: Colors.green,
|
||||||
color: Colors.green,
|
isSelected: _selected == 'History',
|
||||||
isSelected: _selected == 'History',
|
onTap: () => setState(() {
|
||||||
onTap: () => setState(() {
|
_body = _History();
|
||||||
_body = _History();
|
_selected = 'History';
|
||||||
_selected = 'History';
|
})),
|
||||||
})),
|
_tabWidget(
|
||||||
_tabWidget(
|
icon: Icon(Icons.playlist_play),
|
||||||
icon: Icon(Icons.playlist_play),
|
label: s.playlists,
|
||||||
label: s.playlists,
|
color: Colors.purple,
|
||||||
color: Colors.purple,
|
isSelected: _selected == 'Playlists',
|
||||||
isSelected: _selected == 'Playlists',
|
onTap: () => setState(() {
|
||||||
onTap: () => setState(() {
|
_body = _Playlists();
|
||||||
_body = _Playlists();
|
_selected = 'Playlists';
|
||||||
_selected = 'Playlists';
|
})),
|
||||||
})),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
Divider(height: 1),
|
||||||
Divider(height: 1),
|
Expanded(
|
||||||
Expanded(
|
child: AnimatedSwitcher(
|
||||||
child: AnimatedSwitcher(
|
duration: Duration(milliseconds: 300), child: _body))
|
||||||
duration: Duration(milliseconds: 300), child: _body))
|
],
|
||||||
],
|
)),
|
||||||
)),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,61 +276,67 @@ class __QueueState extends State<_Queue> {
|
||||||
selector: (_, audio) =>
|
selector: (_, audio) =>
|
||||||
Tuple3(audio.playlist, audio.playerRunning, audio.episode),
|
Tuple3(audio.playlist, audio.playerRunning, audio.episode),
|
||||||
builder: (_, data, __) {
|
builder: (_, data, __) {
|
||||||
var episodes = data.item1.episodes.toSet().toList();
|
var episodes = data.item1?.episodes?.toSet()?.toList();
|
||||||
var queue = data.item1;
|
var queue = data.item1;
|
||||||
var running = data.item2;
|
var running = data.item2;
|
||||||
return queue.name == 'Queue'
|
return queue == null
|
||||||
? ReorderableListView(
|
? Center()
|
||||||
onReorder: (oldIndex, newIndex) {
|
: queue?.name == 'Queue'
|
||||||
context
|
? ReorderableListView(
|
||||||
.read<AudioPlayerNotifier>()
|
onReorder: (oldIndex, newIndex) {
|
||||||
.reorderPlaylist(oldIndex, newIndex);
|
context
|
||||||
setState(() {});
|
.read<AudioPlayerNotifier>()
|
||||||
},
|
.reorderPlaylist(oldIndex, newIndex);
|
||||||
scrollDirection: Axis.vertical,
|
setState(() {});
|
||||||
children: data.item2
|
|
||||||
? episodes.map<Widget>((episode) {
|
|
||||||
if (episode.enclosureUrl !=
|
|
||||||
episodes.first.enclosureUrl) {
|
|
||||||
return DismissibleContainer(
|
|
||||||
episode: episode,
|
|
||||||
onRemove: (value) => setState(() {}),
|
|
||||||
key: ValueKey(episode.enclosureUrl),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return EpisodeCard(episode,
|
|
||||||
key: ValueKey('playing'),
|
|
||||||
isPlaying: true,
|
|
||||||
canReorder: true,
|
|
||||||
tileColor: context.primaryColorDark);
|
|
||||||
}
|
|
||||||
}).toList()
|
|
||||||
: episodes
|
|
||||||
.map<Widget>((episode) => DismissibleContainer(
|
|
||||||
episode: episode,
|
|
||||||
onRemove: (value) => setState(() {}),
|
|
||||||
key: ValueKey(episode.enclosureUrl),
|
|
||||||
))
|
|
||||||
.toList())
|
|
||||||
: ListView.builder(
|
|
||||||
itemCount: queue.episodeList.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final episode = queue.episodes[index];
|
|
||||||
final isPlaying =
|
|
||||||
data.item3 != null && data.item3 == episode;
|
|
||||||
return EpisodeCard(
|
|
||||||
episode,
|
|
||||||
isPlaying: isPlaying && running,
|
|
||||||
tileColor: isPlaying ? context.primaryColorDark : null,
|
|
||||||
onTap: () async {
|
|
||||||
if (!isPlaying) {
|
|
||||||
await context
|
|
||||||
.read<AudioPlayerNotifier>()
|
|
||||||
.loadEpisodeFromPlaylist(episode);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
scrollDirection: Axis.vertical,
|
||||||
});
|
children: data.item2
|
||||||
|
? episodes.map<Widget>((episode) {
|
||||||
|
if (episode.enclosureUrl !=
|
||||||
|
episodes.first.enclosureUrl) {
|
||||||
|
return DismissibleContainer(
|
||||||
|
episode: episode,
|
||||||
|
onRemove: (value) => setState(() {}),
|
||||||
|
key: ValueKey(episode.enclosureUrl),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return EpisodeCard(episode,
|
||||||
|
key: ValueKey('playing'),
|
||||||
|
isPlaying: true,
|
||||||
|
canReorder: true,
|
||||||
|
tileColor: context.primaryColorDark);
|
||||||
|
}
|
||||||
|
}).toList()
|
||||||
|
: episodes
|
||||||
|
.map<Widget>((episode) => DismissibleContainer(
|
||||||
|
episode: episode,
|
||||||
|
onRemove: (value) => setState(() {}),
|
||||||
|
key: ValueKey(episode.enclosureUrl),
|
||||||
|
))
|
||||||
|
.toList())
|
||||||
|
: ListView.builder(
|
||||||
|
itemCount: queue?.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final episode =
|
||||||
|
queue != null ? queue.episodes[index] : null;
|
||||||
|
final isPlaying =
|
||||||
|
data.item3 != null && data.item3 == episode;
|
||||||
|
return episode == null
|
||||||
|
? Center()
|
||||||
|
: EpisodeCard(
|
||||||
|
episode,
|
||||||
|
isPlaying: isPlaying && running,
|
||||||
|
tileColor:
|
||||||
|
isPlaying ? context.primaryColorDark : null,
|
||||||
|
onTap: () async {
|
||||||
|
if (!isPlaying) {
|
||||||
|
await context
|
||||||
|
.read<AudioPlayerNotifier>()
|
||||||
|
.loadEpisodeFromPlaylist(episode);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tsacdop/state/setting_state.dart';
|
||||||
|
|
||||||
import '../local_storage/key_value_storage.dart';
|
import '../local_storage/key_value_storage.dart';
|
||||||
import '../service/search_api.dart';
|
import '../service/search_api.dart';
|
||||||
|
@ -310,9 +311,61 @@ class _LayoutSettingState extends State<LayoutSetting> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Divider(height: 1),
|
Divider(height: 1),
|
||||||
Padding(
|
SizedBox(height: 20),
|
||||||
padding: EdgeInsets.all(10.0),
|
Container(
|
||||||
|
height: 30.0,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 70),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text('Default page',
|
||||||
|
style: context.textTheme.bodyText1
|
||||||
|
.copyWith(color: context.accentColor)),
|
||||||
),
|
),
|
||||||
|
Selector<SettingState, bool>(
|
||||||
|
selector: (_, setting) => setting.openPlaylistDefault,
|
||||||
|
builder: (_, data, __) {
|
||||||
|
return ListTile(
|
||||||
|
contentPadding: EdgeInsets.fromLTRB(70, 10, 10, 10),
|
||||||
|
onTap: () => context
|
||||||
|
.read<SettingState>()
|
||||||
|
.openPlaylistDefault = !data,
|
||||||
|
title: Text('Open playlist page by default'),
|
||||||
|
subtitle: Text(
|
||||||
|
'Open playlist page instead of homepage by default'),
|
||||||
|
trailing: Transform.scale(
|
||||||
|
scale: 0.9,
|
||||||
|
child: Switch(
|
||||||
|
value: data,
|
||||||
|
onChanged: (boo) => context
|
||||||
|
.read<SettingState>()
|
||||||
|
.openPlaylistDefault = boo),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Selector<SettingState, bool>(
|
||||||
|
selector: (_, setting) => setting.openAllPodcastDefalt,
|
||||||
|
builder: (_, data, __) {
|
||||||
|
return ListTile(
|
||||||
|
contentPadding: EdgeInsets.fromLTRB(70, 10, 10, 10),
|
||||||
|
onTap: () => context
|
||||||
|
.read<SettingState>()
|
||||||
|
.openAllPodcastDefault = !data,
|
||||||
|
title: Text('Open all podcasts page by default'),
|
||||||
|
subtitle: Text(
|
||||||
|
'Open all podcasts page instead of group page by default'),
|
||||||
|
trailing: Transform.scale(
|
||||||
|
scale: 0.9,
|
||||||
|
child: Switch(
|
||||||
|
value: data,
|
||||||
|
onChanged: (boo) => context
|
||||||
|
.read<SettingState>()
|
||||||
|
.openAllPodcastDefault = boo),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Divider(height: 1),
|
||||||
|
SizedBox(height: 20),
|
||||||
Container(
|
Container(
|
||||||
height: 30.0,
|
height: 30.0,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 70),
|
padding: EdgeInsets.symmetric(horizontal: 70),
|
||||||
|
|
|
@ -84,7 +84,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
EpisodeBrief _episode;
|
EpisodeBrief _episode;
|
||||||
|
|
||||||
/// Playlists include queue and playlists created by user.
|
/// Playlists include queue and playlists created by user.
|
||||||
List<Playlist> _playlists;
|
List<Playlist> _playlists = [];
|
||||||
|
|
||||||
/// Playing playlist.
|
/// Playing playlist.
|
||||||
Playlist _playlist;
|
Playlist _playlist;
|
||||||
|
@ -261,53 +261,55 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initPlaylist() async {
|
Future<void> initPlaylist() async {
|
||||||
var playlistEntities = await _playlistsStorgae.getPlaylists();
|
if (_playlists.isEmpty) {
|
||||||
_playlists = [
|
var playlistEntities = await _playlistsStorgae.getPlaylists();
|
||||||
for (var entity in playlistEntities) Playlist.fromEntity(entity)
|
_playlists = [
|
||||||
];
|
for (var entity in playlistEntities) Playlist.fromEntity(entity)
|
||||||
await _playlists.first.getPlaylist();
|
];
|
||||||
await _getAutoPlay();
|
await _playlists.first.getPlaylist();
|
||||||
|
await _getAutoPlay();
|
||||||
|
|
||||||
var state = await _playerStateStorage.getPlayerState();
|
var state = await _playerStateStorage.getPlayerState();
|
||||||
var idList = [for (var p in _playlists) p.id];
|
var idList = [for (var p in _playlists) p.id];
|
||||||
if (idList.contains(state[1])) {
|
if (idList.contains(state[1])) {
|
||||||
_playlist = _playlists.firstWhere(
|
_playlist = _playlists.firstWhere(
|
||||||
(p) => p.id == state[0],
|
(p) => p.id == state[0],
|
||||||
);
|
);
|
||||||
await _playlist.getPlaylist();
|
await _playlist.getPlaylist();
|
||||||
if (state[1] != '') {
|
if (state[1] != '') {
|
||||||
var episode = await _dbHelper.getRssItemWithUrl(state[1]);
|
var episode = await _dbHelper.getRssItemWithUrl(state[1]);
|
||||||
if ((!_playlist.isQueue && _playlist.contains(episode)) ||
|
if ((!_playlist.isQueue && _playlist.contains(episode)) ||
|
||||||
(_playlist.isQueue &&
|
(_playlist.isQueue &&
|
||||||
_queue.isNotEmpty &&
|
_queue.isNotEmpty &&
|
||||||
_queue.episodes.first == episode)) {
|
_queue.episodes.first == episode)) {
|
||||||
_episode = episode;
|
_episode = episode;
|
||||||
_lastPosition = int.parse(state[2] ?? '0');
|
_lastPosition = int.parse(state[2] ?? '0');
|
||||||
|
} else {
|
||||||
|
_episode = _playlist.isNotEmpty ? _playlist.episodes.first : null;
|
||||||
|
_lastPosition = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_episode = _playlist.isNotEmpty ? _playlist.episodes.first : null;
|
_episode = _playlist.isNotEmpty ? _playlist.episodes.first : null;
|
||||||
_lastPosition = 0;
|
_lastPosition = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_episode = _playlist.isNotEmpty ? _playlist.episodes.first : null;
|
_playlist = _playlists.first;
|
||||||
|
_episode = _playlist.isNotEmpty ? _playlist.episodes?.first : null;
|
||||||
_lastPosition = 0;
|
_lastPosition = 0;
|
||||||
}
|
}
|
||||||
} else {
|
notifyListeners();
|
||||||
_playlist = _playlists.first;
|
|
||||||
_episode = _playlist.isNotEmpty ? _playlist.episodes?.first : null;
|
|
||||||
_lastPosition = 0;
|
|
||||||
}
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
/// Save plays history if app is closed accidentally.
|
/// Save plays history if app is closed accidentally.
|
||||||
/// if (_lastPostion > 0 && _queue.episodes.isNotEmpty) {
|
/// if (_lastPostion > 0 && _queue.episodes.isNotEmpty) {
|
||||||
/// final episode = _queue.episodes.first;
|
/// final episode = _queue.episodes.first;
|
||||||
/// final duration = episode.duration * 1000;
|
/// final duration = episode.duration * 1000;
|
||||||
/// final seekValue = duration != 0 ? _lastPostion / duration : 1.0;
|
/// final seekValue = duration != 0 ? _lastPostion / duration : 1.0;
|
||||||
/// final history = PlayHistory(
|
/// final history = PlayHistory(
|
||||||
/// episode.title, episode.enclosureUrl, _lastPostion ~/ 1000, seekValue);
|
/// episode.title, episode.enclosureUrl, _lastPostion ~/ 1000, seekValue);
|
||||||
/// await _dbHelper.saveHistory(history);
|
/// await _dbHelper.saveHistory(history);
|
||||||
/// }
|
/// }
|
||||||
await KeyValueStorage(lastWorkKey).saveInt(0);
|
await KeyValueStorage(lastWorkKey).saveInt(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> playFromLastPosition() async {
|
Future<void> playFromLastPosition() async {
|
||||||
|
|
|
@ -74,37 +74,40 @@ final showNotesFontStyles = <TextStyle>[
|
||||||
];
|
];
|
||||||
|
|
||||||
class SettingState extends ChangeNotifier {
|
class SettingState extends ChangeNotifier {
|
||||||
var themeStorage = KeyValueStorage(themesKey);
|
final _themeStorage = KeyValueStorage(themesKey);
|
||||||
var accentStorage = KeyValueStorage(accentsKey);
|
final _accentStorage = KeyValueStorage(accentsKey);
|
||||||
var autoupdateStorage = KeyValueStorage(autoUpdateKey);
|
final _autoupdateStorage = KeyValueStorage(autoUpdateKey);
|
||||||
var intervalStorage = KeyValueStorage(updateIntervalKey);
|
final _intervalStorage = KeyValueStorage(updateIntervalKey);
|
||||||
var downloadUsingDataStorage = KeyValueStorage(downloadUsingDataKey);
|
final _downloadUsingDataStorage = KeyValueStorage(downloadUsingDataKey);
|
||||||
var introStorage = KeyValueStorage(introKey);
|
final _introStorage = KeyValueStorage(introKey);
|
||||||
var realDarkStorage = KeyValueStorage(realDarkKey);
|
final _realDarkStorage = KeyValueStorage(realDarkKey);
|
||||||
var autoPlayStorage = KeyValueStorage(autoPlayKey);
|
final _autoPlayStorage = KeyValueStorage(autoPlayKey);
|
||||||
var defaultSleepTimerStorage = KeyValueStorage(defaultSleepTimerKey);
|
final _defaultSleepTimerStorage = KeyValueStorage(defaultSleepTimerKey);
|
||||||
var autoSleepTimerStorage = KeyValueStorage(autoSleepTimerKey);
|
final _autoSleepTimerStorage = KeyValueStorage(autoSleepTimerKey);
|
||||||
var autoSleepTimerModeStorage = KeyValueStorage(autoSleepTimerModeKey);
|
final _autoSleepTimerModeStorage = KeyValueStorage(autoSleepTimerModeKey);
|
||||||
var autoSleepTimerStartStorage = KeyValueStorage(autoSleepTimerStartKey);
|
final _autoSleepTimerStartStorage = KeyValueStorage(autoSleepTimerStartKey);
|
||||||
var autoSleepTimerEndStorage = KeyValueStorage(autoSleepTimerEndKey);
|
final _autoSleepTimerEndStorage = KeyValueStorage(autoSleepTimerEndKey);
|
||||||
var tapToOpenPopupMenuStorage = KeyValueStorage(tapToOpenPopupMenuKey);
|
final _cacheStorage = KeyValueStorage(cacheMaxKey);
|
||||||
var cacheStorage = KeyValueStorage(cacheMaxKey);
|
final _podcastLayoutStorage = KeyValueStorage(podcastLayoutKey);
|
||||||
var podcastLayoutStorage = KeyValueStorage(podcastLayoutKey);
|
final _favLayoutStorage = KeyValueStorage(favLayoutKey);
|
||||||
var favLayoutStorage = KeyValueStorage(favLayoutKey);
|
final _downloadLayoutStorage = KeyValueStorage(downloadLayoutKey);
|
||||||
var downloadLayoutStorage = KeyValueStorage(downloadLayoutKey);
|
final _recentLayoutStorage = KeyValueStorage(recentLayoutKey);
|
||||||
var recentLayoutStorage = KeyValueStorage(recentLayoutKey);
|
final _autoDeleteStorage = KeyValueStorage(autoDeleteKey);
|
||||||
var autoDeleteStorage = KeyValueStorage(autoDeleteKey);
|
final _autoDownloadStorage = KeyValueStorage(autoDownloadNetworkKey);
|
||||||
var autoDownloadStorage = KeyValueStorage(autoDownloadNetworkKey);
|
final _fastForwardSecondsStorage = KeyValueStorage(fastForwardSecondsKey);
|
||||||
var fastForwardSecondsStorage = KeyValueStorage(fastForwardSecondsKey);
|
final _rewindSecondsStorage = KeyValueStorage(rewindSecondsKey);
|
||||||
var rewindSecondsStorage = KeyValueStorage(rewindSecondsKey);
|
final _localeStorage = KeyValueStorage(localeKey);
|
||||||
var localeStorage = KeyValueStorage(localeKey);
|
final _showNotesFontStorage = KeyValueStorage(showNotesFontKey);
|
||||||
var showNotesFontStorage = KeyValueStorage(showNotesFontKey);
|
final _openPlaylistDefaultStorage = KeyValueStorage(openPlaylistDefaultKey);
|
||||||
|
final _openAllPodcastDefaultStorage =
|
||||||
|
KeyValueStorage(openAllPodcastDefaultKey);
|
||||||
|
|
||||||
Future initData() async {
|
Future initData() async {
|
||||||
await _getTheme();
|
await _getTheme();
|
||||||
await _getAccentSetColor();
|
await _getAccentSetColor();
|
||||||
await _getShowIntro();
|
await _getShowIntro();
|
||||||
await _getRealDark();
|
await _getRealDark();
|
||||||
|
await _getOpenPlaylistDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -116,6 +119,7 @@ class SettingState extends ChangeNotifier {
|
||||||
_getSleepTimerData();
|
_getSleepTimerData();
|
||||||
_getPlayerSeconds();
|
_getPlayerSeconds();
|
||||||
_getShowNotesFonts();
|
_getShowNotesFonts();
|
||||||
|
_getOpenAllPodcastDefault();
|
||||||
_getUpdateInterval().then((value) async {
|
_getUpdateInterval().then((value) async {
|
||||||
if (_initUpdateTag == 0) {
|
if (_initUpdateTag == 0) {
|
||||||
setWorkManager(24);
|
setWorkManager(24);
|
||||||
|
@ -247,6 +251,24 @@ class SettingState extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Open playlist page default
|
||||||
|
bool _openPlaylistDefault;
|
||||||
|
bool get openPlaylistDefault => _openPlaylistDefault;
|
||||||
|
set openPlaylistDefault(bool boo) {
|
||||||
|
_openPlaylistDefault = boo;
|
||||||
|
_setOpenPlaylistDefault();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open all podcasts page default
|
||||||
|
bool _openAllPodcastDefault;
|
||||||
|
bool get openAllPodcastDefalt => _openAllPodcastDefault;
|
||||||
|
set openAllPodcastDefault(boo) {
|
||||||
|
_openAllPodcastDefault = boo;
|
||||||
|
_setOpenAllPodcastDefault();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
int _defaultSleepTimer;
|
int _defaultSleepTimer;
|
||||||
int get defaultSleepTimer => _defaultSleepTimer;
|
int get defaultSleepTimer => _defaultSleepTimer;
|
||||||
set setDefaultSleepTimer(int i) {
|
set setDefaultSleepTimer(int i) {
|
||||||
|
@ -322,12 +344,12 @@ class SettingState extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getTheme() async {
|
Future _getTheme() async {
|
||||||
var mode = await themeStorage.getInt();
|
var mode = await _themeStorage.getInt();
|
||||||
_theme = ThemeMode.values[mode];
|
_theme = ThemeMode.values[mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getAccentSetColor() async {
|
Future _getAccentSetColor() async {
|
||||||
var colorString = await accentStorage.getString();
|
var colorString = await _accentStorage.getString();
|
||||||
if (colorString.isNotEmpty) {
|
if (colorString.isNotEmpty) {
|
||||||
var color = int.parse('FF${colorString.toUpperCase()}', radix: 16);
|
var color = int.parse('FF${colorString.toUpperCase()}', radix: 16);
|
||||||
_accentSetColor = Color(color).withOpacity(1.0);
|
_accentSetColor = Color(color).withOpacity(1.0);
|
||||||
|
@ -339,53 +361,63 @@ class SettingState extends ChangeNotifier {
|
||||||
|
|
||||||
Future _getAutoUpdate() async {
|
Future _getAutoUpdate() async {
|
||||||
_autoUpdate =
|
_autoUpdate =
|
||||||
await autoupdateStorage.getBool(defaultValue: true, reverse: true);
|
await _autoupdateStorage.getBool(defaultValue: true, reverse: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getUpdateInterval() async {
|
Future _getUpdateInterval() async {
|
||||||
_initUpdateTag = await intervalStorage.getInt();
|
_initUpdateTag = await _intervalStorage.getInt();
|
||||||
_updateInterval = _initUpdateTag;
|
_updateInterval = _initUpdateTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getDownloadUsingData() async {
|
Future _getDownloadUsingData() async {
|
||||||
_downloadUsingData = await downloadUsingDataStorage.getBool(
|
_downloadUsingData = await _downloadUsingDataStorage.getBool(
|
||||||
defaultValue: true, reverse: true);
|
defaultValue: true, reverse: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _saveDownloadUsingData() async {
|
Future _saveDownloadUsingData() async {
|
||||||
await downloadUsingDataStorage.saveBool(_downloadUsingData, reverse: true);
|
await _downloadUsingDataStorage.saveBool(_downloadUsingData, reverse: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getShowIntro() async {
|
Future _getShowIntro() async {
|
||||||
_initialShowIntor = await introStorage.getInt();
|
_initialShowIntor = await _introStorage.getInt();
|
||||||
_showIntro = _initialShowIntor == 0;
|
_showIntro = _initialShowIntor == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getRealDark() async {
|
Future _getRealDark() async {
|
||||||
_realDark = await realDarkStorage.getBool(defaultValue: false);
|
_realDark = await _realDarkStorage.getBool(defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _getOpenPlaylistDefault() async {
|
||||||
|
_openPlaylistDefault =
|
||||||
|
await _openPlaylistDefaultStorage.getBool(defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _getOpenAllPodcastDefault() async {
|
||||||
|
_openAllPodcastDefault =
|
||||||
|
await _openAllPodcastDefaultStorage.getBool(defaultValue: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getSleepTimerData() async {
|
Future _getSleepTimerData() async {
|
||||||
_defaultSleepTimer =
|
_defaultSleepTimer =
|
||||||
await defaultSleepTimerStorage.getInt(defaultValue: 30);
|
await _defaultSleepTimerStorage.getInt(defaultValue: 30);
|
||||||
_autoSleepTimer = await autoSleepTimerStorage.getBool(defaultValue: false);
|
_autoSleepTimer = await _autoSleepTimerStorage.getBool(defaultValue: false);
|
||||||
_autoSleepTimerStart =
|
_autoSleepTimerStart =
|
||||||
await autoSleepTimerStartStorage.getInt(defaultValue: 1380);
|
await _autoSleepTimerStartStorage.getInt(defaultValue: 1380);
|
||||||
_autoSleepTimerEnd =
|
_autoSleepTimerEnd =
|
||||||
await autoSleepTimerEndStorage.getInt(defaultValue: 360);
|
await _autoSleepTimerEndStorage.getInt(defaultValue: 360);
|
||||||
_autoPlay =
|
_autoPlay =
|
||||||
await autoPlayStorage.getBool(defaultValue: true, reverse: true);
|
await _autoPlayStorage.getBool(defaultValue: true, reverse: true);
|
||||||
_autoSleepTimerMode = await autoSleepTimerModeStorage.getInt();
|
_autoSleepTimerMode = await _autoSleepTimerModeStorage.getInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getPlayerSeconds() async {
|
Future _getPlayerSeconds() async {
|
||||||
_rewindSeconds = await rewindSecondsStorage.getInt(defaultValue: 10);
|
_rewindSeconds = await _rewindSecondsStorage.getInt(defaultValue: 10);
|
||||||
_fastForwardSeconds =
|
_fastForwardSeconds =
|
||||||
await fastForwardSecondsStorage.getInt(defaultValue: 30);
|
await _fastForwardSecondsStorage.getInt(defaultValue: 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getLocale() async {
|
Future _getLocale() async {
|
||||||
var localeString = await localeStorage.getStringList();
|
var localeString = await _localeStorage.getStringList();
|
||||||
if (localeString.isEmpty) {
|
if (localeString.isEmpty) {
|
||||||
await findSystemLocale();
|
await findSystemLocale();
|
||||||
var systemLanCode;
|
var systemLanCode;
|
||||||
|
@ -405,111 +437,119 @@ class SettingState extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _getShowNotesFonts() async {
|
Future<void> _getShowNotesFonts() async {
|
||||||
_showNotesFontIndex = await showNotesFontStorage.getInt(defaultValue: 1);
|
_showNotesFontIndex = await _showNotesFontStorage.getInt(defaultValue: 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAccentSetColor() async {
|
Future<void> _saveAccentSetColor() async {
|
||||||
await accentStorage
|
await _accentStorage
|
||||||
.saveString(_accentSetColor.toString().substring(10, 16));
|
.saveString(_accentSetColor.toString().substring(10, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _setRealDark() async {
|
Future<void> _setRealDark() async {
|
||||||
await realDarkStorage.saveBool(_realDark);
|
await _realDarkStorage.saveBool(_realDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _setOpenPlaylistDefault() async {
|
||||||
|
await _openPlaylistDefaultStorage.saveBool(_openPlaylistDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _setOpenAllPodcastDefault() async {
|
||||||
|
await _openAllPodcastDefaultStorage.saveBool(_openAllPodcastDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveShowIntro(int i) async {
|
Future<void> saveShowIntro(int i) async {
|
||||||
await introStorage.saveInt(i);
|
await _introStorage.saveInt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveUpdateInterval() async {
|
Future<void> _saveUpdateInterval() async {
|
||||||
await intervalStorage.saveInt(_updateInterval);
|
await _intervalStorage.saveInt(_updateInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveTheme() async {
|
Future<void> _saveTheme() async {
|
||||||
await themeStorage.saveInt(_theme.index);
|
await _themeStorage.saveInt(_theme.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAutoUpdate() async {
|
Future<void> _saveAutoUpdate() async {
|
||||||
await autoupdateStorage.saveBool(_autoUpdate, reverse: true);
|
await _autoupdateStorage.saveBool(_autoUpdate, reverse: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAutoPlay() async {
|
Future<void> _saveAutoPlay() async {
|
||||||
await autoPlayStorage.saveBool(_autoPlay, reverse: true);
|
await _autoPlayStorage.saveBool(_autoPlay, reverse: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _setDefaultSleepTimer() async {
|
Future<void> _setDefaultSleepTimer() async {
|
||||||
await defaultSleepTimerStorage.saveInt(_defaultSleepTimer);
|
await _defaultSleepTimerStorage.saveInt(_defaultSleepTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAutoSleepTimer() async {
|
Future<void> _saveAutoSleepTimer() async {
|
||||||
await autoSleepTimerStorage.saveBool(_autoSleepTimer);
|
await _autoSleepTimerStorage.saveBool(_autoSleepTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAutoSleepTimerMode() async {
|
Future<void> _saveAutoSleepTimerMode() async {
|
||||||
await autoSleepTimerModeStorage.saveInt(_autoSleepTimerMode);
|
await _autoSleepTimerModeStorage.saveInt(_autoSleepTimerMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAutoSleepTimerStart() async {
|
Future<void> _saveAutoSleepTimerStart() async {
|
||||||
await autoSleepTimerStartStorage.saveInt(_autoSleepTimerStart);
|
await _autoSleepTimerStartStorage.saveInt(_autoSleepTimerStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAutoSleepTimerEnd() async {
|
Future<void> _saveAutoSleepTimerEnd() async {
|
||||||
await autoSleepTimerEndStorage.saveInt(_autoSleepTimerEnd);
|
await _autoSleepTimerEndStorage.saveInt(_autoSleepTimerEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveFastForwardSeconds() async {
|
Future<void> _saveFastForwardSeconds() async {
|
||||||
await fastForwardSecondsStorage.saveInt(_fastForwardSeconds);
|
await _fastForwardSecondsStorage.saveInt(_fastForwardSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveRewindSeconds() async {
|
Future<void> _saveRewindSeconds() async {
|
||||||
await rewindSecondsStorage.saveInt(_rewindSeconds);
|
await _rewindSecondsStorage.saveInt(_rewindSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveShowNotesFonts() async {
|
Future<void> _saveShowNotesFonts() async {
|
||||||
await showNotesFontStorage.saveInt(_showNotesFontIndex);
|
await _showNotesFontStorage.saveInt(_showNotesFontIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SettingsBackup> backup() async {
|
Future<SettingsBackup> backup() async {
|
||||||
var theme = await themeStorage.getInt();
|
var theme = await _themeStorage.getInt();
|
||||||
var accentColor = await accentStorage.getString();
|
var accentColor = await _accentStorage.getString();
|
||||||
var realDark = await realDarkStorage.getBool(defaultValue: false);
|
var realDark = await _realDarkStorage.getBool(defaultValue: false);
|
||||||
var autoPlay =
|
var autoPlay =
|
||||||
await autoPlayStorage.getBool(defaultValue: true, reverse: true);
|
await _autoPlayStorage.getBool(defaultValue: true, reverse: true);
|
||||||
var autoUpdate =
|
var autoUpdate =
|
||||||
await autoupdateStorage.getBool(defaultValue: true, reverse: true);
|
await _autoupdateStorage.getBool(defaultValue: true, reverse: true);
|
||||||
var updateInterval = await intervalStorage.getInt();
|
var updateInterval = await _intervalStorage.getInt();
|
||||||
var downloadUsingData = await downloadUsingDataStorage.getBool(
|
var downloadUsingData = await _downloadUsingDataStorage.getBool(
|
||||||
defaultValue: true, reverse: true);
|
defaultValue: true, reverse: true);
|
||||||
var cacheMax = await cacheStorage.getInt(defaultValue: 500 * 1024 * 1024);
|
var cacheMax = await _cacheStorage.getInt(defaultValue: 500 * 1024 * 1024);
|
||||||
var podcastLayout = await podcastLayoutStorage.getInt();
|
var podcastLayout = await _podcastLayoutStorage.getInt();
|
||||||
var recentLayout = await recentLayoutStorage.getInt();
|
var recentLayout = await _recentLayoutStorage.getInt();
|
||||||
var favLayout = await favLayoutStorage.getInt();
|
var favLayout = await _favLayoutStorage.getInt();
|
||||||
var downloadLayout = await downloadLayoutStorage.getInt();
|
var downloadLayout = await _downloadLayoutStorage.getInt();
|
||||||
var autoDownloadNetwork =
|
var autoDownloadNetwork =
|
||||||
await autoDownloadStorage.getBool(defaultValue: false);
|
await _autoDownloadStorage.getBool(defaultValue: false);
|
||||||
var episodePopupMenu = await KeyValueStorage(episodePopupMenuKey).getMenu();
|
var episodePopupMenu = await KeyValueStorage(episodePopupMenuKey).getMenu();
|
||||||
var autoDelete = await autoDeleteStorage.getInt();
|
var autoDelete = await _autoDeleteStorage.getInt();
|
||||||
var autoSleepTimer =
|
var autoSleepTimer =
|
||||||
await autoSleepTimerStorage.getBool(defaultValue: false);
|
await _autoSleepTimerStorage.getBool(defaultValue: false);
|
||||||
var autoSleepTimerStart = await autoSleepTimerStartStorage.getInt();
|
var autoSleepTimerStart = await _autoSleepTimerStartStorage.getInt();
|
||||||
var autoSleepTimerEnd = await autoSleepTimerEndStorage.getInt();
|
var autoSleepTimerEnd = await _autoSleepTimerEndStorage.getInt();
|
||||||
var autoSleepTimerMode = await autoSleepTimerModeStorage.getInt();
|
var autoSleepTimerMode = await _autoSleepTimerModeStorage.getInt();
|
||||||
var defaultSleepTime = await defaultSleepTimerStorage.getInt();
|
var defaultSleepTime = await _defaultSleepTimerStorage.getInt();
|
||||||
var tapToOpenPopupMenu = await KeyValueStorage(tapToOpenPopupMenuKey)
|
var tapToOpenPopupMenu = await KeyValueStorage(tapToOpenPopupMenuKey)
|
||||||
.getBool(defaultValue: false);
|
.getBool(defaultValue: false);
|
||||||
var fastForwardSeconds =
|
var fastForwardSeconds =
|
||||||
await fastForwardSecondsStorage.getInt(defaultValue: 30);
|
await _fastForwardSecondsStorage.getInt(defaultValue: 30);
|
||||||
var rewindSeconds = await rewindSecondsStorage.getInt(defaultValue: 10);
|
var rewindSeconds = await _rewindSecondsStorage.getInt(defaultValue: 10);
|
||||||
var playerHeight =
|
var playerHeight =
|
||||||
await KeyValueStorage(playerHeightKey).getInt(defaultValue: 0);
|
await KeyValueStorage(playerHeightKey).getInt(defaultValue: 0);
|
||||||
var localeList = await localeStorage.getStringList();
|
var localeList = await _localeStorage.getStringList();
|
||||||
var backupLocale =
|
var backupLocale =
|
||||||
localeList.isEmpty ? '' : '${'${localeList.first}-'}${localeList[1]}';
|
localeList.isEmpty ? '' : '${'${localeList.first}-'}${localeList[1]}';
|
||||||
var hideListened =
|
var hideListened =
|
||||||
await KeyValueStorage(hideListenedKey).getBool(defaultValue: false);
|
await KeyValueStorage(hideListenedKey).getBool(defaultValue: false);
|
||||||
var notificationLayout =
|
var notificationLayout =
|
||||||
await KeyValueStorage(notificationLayoutKey).getInt(defaultValue: 0);
|
await KeyValueStorage(notificationLayoutKey).getInt(defaultValue: 0);
|
||||||
var showNotesFont = await showNotesFontStorage.getInt(defaultValue: 1);
|
var showNotesFont = await _showNotesFontStorage.getInt(defaultValue: 1);
|
||||||
var speedList = await KeyValueStorage(speedListKey).getStringList();
|
var speedList = await KeyValueStorage(speedListKey).getStringList();
|
||||||
var hidePodcastDiscovery = await KeyValueStorage(hidePodcastDiscoveryKey)
|
var hidePodcastDiscovery = await KeyValueStorage(hidePodcastDiscoveryKey)
|
||||||
.getBool(defaultValue: false);
|
.getBool(defaultValue: false);
|
||||||
|
@ -555,37 +595,37 @@ class SettingState extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> restore(SettingsBackup backup) async {
|
Future<void> restore(SettingsBackup backup) async {
|
||||||
await themeStorage.saveInt(backup.theme);
|
await _themeStorage.saveInt(backup.theme);
|
||||||
await accentStorage.saveString(backup.accentColor);
|
await _accentStorage.saveString(backup.accentColor);
|
||||||
await realDarkStorage.saveBool(backup.realDark);
|
await _realDarkStorage.saveBool(backup.realDark);
|
||||||
await autoPlayStorage.saveBool(backup.autoPlay, reverse: true);
|
await _autoPlayStorage.saveBool(backup.autoPlay, reverse: true);
|
||||||
await autoupdateStorage.saveBool(backup.autoUpdate, reverse: true);
|
await _autoupdateStorage.saveBool(backup.autoUpdate, reverse: true);
|
||||||
await intervalStorage.saveInt(backup.updateInterval);
|
await _intervalStorage.saveInt(backup.updateInterval);
|
||||||
await downloadUsingDataStorage.saveBool(backup.downloadUsingData,
|
await _downloadUsingDataStorage.saveBool(backup.downloadUsingData,
|
||||||
reverse: true);
|
reverse: true);
|
||||||
await cacheStorage.saveInt(backup.cacheMax);
|
await _cacheStorage.saveInt(backup.cacheMax);
|
||||||
await podcastLayoutStorage.saveInt(backup.podcastLayout);
|
await _podcastLayoutStorage.saveInt(backup.podcastLayout);
|
||||||
await recentLayoutStorage.saveInt(backup.recentLayout);
|
await _recentLayoutStorage.saveInt(backup.recentLayout);
|
||||||
await favLayoutStorage.saveInt(backup.favLayout);
|
await _favLayoutStorage.saveInt(backup.favLayout);
|
||||||
await downloadLayoutStorage.saveInt(backup.downloadLayout);
|
await _downloadLayoutStorage.saveInt(backup.downloadLayout);
|
||||||
await autoDownloadStorage.saveBool(backup.autoDownloadNetwork);
|
await _autoDownloadStorage.saveBool(backup.autoDownloadNetwork);
|
||||||
await KeyValueStorage(episodePopupMenuKey)
|
await KeyValueStorage(episodePopupMenuKey)
|
||||||
.saveStringList(backup.episodePopupMenu);
|
.saveStringList(backup.episodePopupMenu);
|
||||||
await autoDeleteStorage.saveInt(backup.autoDelete);
|
await _autoDeleteStorage.saveInt(backup.autoDelete);
|
||||||
await autoSleepTimerStorage.saveBool(backup.autoSleepTimer);
|
await _autoSleepTimerStorage.saveBool(backup.autoSleepTimer);
|
||||||
await autoSleepTimerStartStorage.saveInt(backup.autoSleepTimerStart);
|
await _autoSleepTimerStartStorage.saveInt(backup.autoSleepTimerStart);
|
||||||
await autoSleepTimerEndStorage.saveInt(backup.autoSleepTimerEnd);
|
await _autoSleepTimerEndStorage.saveInt(backup.autoSleepTimerEnd);
|
||||||
await autoSleepTimerModeStorage.saveInt(backup.autoSleepTimerMode);
|
await _autoSleepTimerModeStorage.saveInt(backup.autoSleepTimerMode);
|
||||||
await defaultSleepTimerStorage.saveInt(backup.defaultSleepTime);
|
await _defaultSleepTimerStorage.saveInt(backup.defaultSleepTime);
|
||||||
await fastForwardSecondsStorage.saveInt(backup.fastForwardSeconds);
|
await _fastForwardSecondsStorage.saveInt(backup.fastForwardSeconds);
|
||||||
await rewindSecondsStorage.saveInt(backup.rewindSeconds);
|
await _rewindSecondsStorage.saveInt(backup.rewindSeconds);
|
||||||
await KeyValueStorage(playerHeightKey).saveInt(backup.playerHeight);
|
await KeyValueStorage(playerHeightKey).saveInt(backup.playerHeight);
|
||||||
await KeyValueStorage(tapToOpenPopupMenuKey)
|
await KeyValueStorage(tapToOpenPopupMenuKey)
|
||||||
.saveBool(backup.tapToOpenPopupMenu);
|
.saveBool(backup.tapToOpenPopupMenu);
|
||||||
await KeyValueStorage(hideListenedKey).saveBool(backup.hideListened);
|
await KeyValueStorage(hideListenedKey).saveBool(backup.hideListened);
|
||||||
await KeyValueStorage(notificationLayoutKey)
|
await KeyValueStorage(notificationLayoutKey)
|
||||||
.saveInt(backup.notificationLayout);
|
.saveInt(backup.notificationLayout);
|
||||||
await showNotesFontStorage.saveInt(backup.showNotesFont);
|
await _showNotesFontStorage.saveInt(backup.showNotesFont);
|
||||||
await KeyValueStorage(speedListKey).saveStringList(backup.speedList);
|
await KeyValueStorage(speedListKey).saveStringList(backup.speedList);
|
||||||
await KeyValueStorage(markListenedAfterSkipKey)
|
await KeyValueStorage(markListenedAfterSkipKey)
|
||||||
.saveBool(backup.markListenedAfterSkip);
|
.saveBool(backup.markListenedAfterSkip);
|
||||||
|
@ -593,7 +633,7 @@ class SettingState extends ChangeNotifier {
|
||||||
.saveBool(backup.deleteAfterPlayed);
|
.saveBool(backup.deleteAfterPlayed);
|
||||||
|
|
||||||
if (backup.locale == '') {
|
if (backup.locale == '') {
|
||||||
await localeStorage.saveStringList([]);
|
await _localeStorage.saveStringList([]);
|
||||||
await S.load(Locale(Intl.systemLocale));
|
await S.load(Locale(Intl.systemLocale));
|
||||||
} else {
|
} else {
|
||||||
var localeList = backup.locale.split('-');
|
var localeList = backup.locale.split('-');
|
||||||
|
@ -603,7 +643,7 @@ class SettingState extends ChangeNotifier {
|
||||||
} else {
|
} else {
|
||||||
backupLocale = Locale(localeList.first, localeList[1]);
|
backupLocale = Locale(localeList.first, localeList[1]);
|
||||||
}
|
}
|
||||||
await localeStorage.saveStringList(
|
await _localeStorage.saveStringList(
|
||||||
[backupLocale.languageCode, backupLocale.countryCode]);
|
[backupLocale.languageCode, backupLocale.countryCode]);
|
||||||
await S.load(backupLocale);
|
await S.load(backupLocale);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||||
|
|
||||||
//Slide Transition
|
//Slide Transition
|
||||||
class SlideLeftRoute extends PageRouteBuilder {
|
class SlideLeftRoute extends PageRouteBuilder {
|
||||||
|
@override
|
||||||
|
Duration get transitionDuration => Duration(milliseconds: 300);
|
||||||
final Widget page;
|
final Widget page;
|
||||||
SlideLeftRoute({this.page})
|
SlideLeftRoute({this.page})
|
||||||
: super(
|
: super(
|
||||||
|
@ -17,23 +19,38 @@ class SlideLeftRoute extends PageRouteBuilder {
|
||||||
secondaryAnimation,
|
secondaryAnimation,
|
||||||
child,
|
child,
|
||||||
) {
|
) {
|
||||||
var begin = Offset(1.0, 0.0);
|
|
||||||
var end = Offset.zero;
|
|
||||||
var curve = Curves.easeOutQuart;
|
|
||||||
var tween =
|
|
||||||
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
|
|
||||||
var tweenSequence = TweenSequence(<TweenSequenceItem<Offset>>[
|
|
||||||
TweenSequenceItem<Offset>(
|
|
||||||
tween: tween,
|
|
||||||
weight: 90.0,
|
|
||||||
),
|
|
||||||
TweenSequenceItem<Offset>(
|
|
||||||
tween: ConstantTween<Offset>(Offset.zero),
|
|
||||||
weight: 10.0,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
return SlideTransition(
|
return SlideTransition(
|
||||||
position: animation.drive(tweenSequence),
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(1, 0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(animation),
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Slide Transition
|
||||||
|
class SlideRightRoute extends PageRouteBuilder {
|
||||||
|
final Widget page;
|
||||||
|
SlideRightRoute({this.page})
|
||||||
|
: super(
|
||||||
|
pageBuilder: (
|
||||||
|
context,
|
||||||
|
animation,
|
||||||
|
secondaryAnimation,
|
||||||
|
) =>
|
||||||
|
page,
|
||||||
|
transitionsBuilder: (
|
||||||
|
context,
|
||||||
|
animation,
|
||||||
|
secondaryAnimation,
|
||||||
|
child,
|
||||||
|
) {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(-1, 0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(animation),
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -200,7 +200,7 @@ class EpisodeCard extends StatelessWidget {
|
||||||
this.isPlaying,
|
this.isPlaying,
|
||||||
this.canReorder = false,
|
this.canReorder = false,
|
||||||
Key key})
|
Key key})
|
||||||
: super(key: key);
|
: assert(episode != null), super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
Loading…
Reference in New Issue