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