Support fast forward / rewind seconds setting.

This commit is contained in:
stonegate 2020-07-25 01:17:47 +08:00
parent 0bff5b8f3b
commit 01d21940d4
21 changed files with 328 additions and 90 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

View File

@ -63,17 +63,19 @@ class MessageLookup extends MessageLookupByLibrary {
static m21(date) => "Removed at ${date}";
static m22(count) => "${Intl.plural(count, zero: 'Just now', one: '${count} second ago', other: '${count} seconds ago')}";
static m22(count) => "${Intl.plural(count, zero: '0 sec', one: '${count} sec', other: '${count} sec')}";
static m23(time) => "Last time ${time}";
static m23(count) => "${Intl.plural(count, zero: 'Just now', one: '${count} second ago', other: '${count} seconds ago')}";
static m24(time) => "${time} Left";
static m24(time) => "Last time ${time}";
static m25(time) => "To ${time}";
static m25(time) => "${time} Left";
static m26(count) => "${Intl.plural(count, zero: 'No update', one: 'Updated ${count} episode', other: 'Updated ${count} episodes')}";
static m26(time) => "To ${time}";
static m27(version) => "Version : ${version}";
static m27(count) => "${Intl.plural(count, zero: 'No update', one: 'Updated ${count} episode', other: 'Updated ${count} episodes')}";
static m28(version) => "Version : ${version}";
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
@ -187,6 +189,7 @@ class MessageLookup extends MessageLookupByLibrary {
"notificationUpdateError" : m18,
"oldestFirst" : MessageLookupByLibrary.simpleMessage("Oldest first"),
"play" : MessageLookupByLibrary.simpleMessage("Play"),
"playback" : MessageLookupByLibrary.simpleMessage("Playback control"),
"playing" : MessageLookupByLibrary.simpleMessage("Playing"),
"plugins" : MessageLookupByLibrary.simpleMessage("Plugins"),
"podcast" : m19,
@ -214,7 +217,8 @@ class MessageLookup extends MessageLookupByLibrary {
"searchEpisode" : MessageLookupByLibrary.simpleMessage("Search episode"),
"searchInvalidRss" : MessageLookupByLibrary.simpleMessage("Invalid RSS link"),
"searchPodcast" : MessageLookupByLibrary.simpleMessage("Search podcast"),
"secondsAgo" : m22,
"secCount" : m22,
"secondsAgo" : m23,
"settingStorage" : MessageLookupByLibrary.simpleMessage("Storage"),
"settings" : MessageLookupByLibrary.simpleMessage("Settings"),
"settingsAccentColor" : MessageLookupByLibrary.simpleMessage("Accent color"),
@ -238,6 +242,8 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsEnableSyncing" : MessageLookupByLibrary.simpleMessage("Enable syncing"),
"settingsEnableSyncingDes" : MessageLookupByLibrary.simpleMessage("Refresh all podcasts in the background to get leatest episodes"),
"settingsExportDes" : MessageLookupByLibrary.simpleMessage("Export and import app settings"),
"settingsFastForwardSec" : MessageLookupByLibrary.simpleMessage("Fast forward seconds"),
"settingsFastForwardSecDes" : MessageLookupByLibrary.simpleMessage("Change the fast forward seconds in player"),
"settingsFeedback" : MessageLookupByLibrary.simpleMessage("Feedback"),
"settingsFeedbackDes" : MessageLookupByLibrary.simpleMessage("Bugs and features request"),
"settingsHistory" : MessageLookupByLibrary.simpleMessage("History"),
@ -263,6 +269,8 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsPrefrence" : MessageLookupByLibrary.simpleMessage("Prefrence"),
"settingsRealDark" : MessageLookupByLibrary.simpleMessage("Real dark"),
"settingsRealDarkDes" : MessageLookupByLibrary.simpleMessage("Turn on if you think the night is not dark enough"),
"settingsRewindSec" : MessageLookupByLibrary.simpleMessage("Rewind seconds"),
"settingsRewindSecDes" : MessageLookupByLibrary.simpleMessage("Change the rewind seconds in player"),
"settingsSTAuto" : MessageLookupByLibrary.simpleMessage("Auto turn on sleep timer"),
"settingsSTAutoDes" : MessageLookupByLibrary.simpleMessage("Auto start sleep timer at scheduled time"),
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Default time"),
@ -283,9 +291,9 @@ class MessageLookup extends MessageLookupByLibrary {
"subscribe" : MessageLookupByLibrary.simpleMessage("Subscribe"),
"subscribeExportDes" : MessageLookupByLibrary.simpleMessage("Export OMPL file of all podcasts"),
"systemDefault" : MessageLookupByLibrary.simpleMessage("System default"),
"timeLastPlayed" : m23,
"timeLeft" : m24,
"to" : m25,
"timeLastPlayed" : m24,
"timeLeft" : m25,
"to" : m26,
"toastAddPlaylist" : MessageLookupByLibrary.simpleMessage("Added to playlist"),
"toastDiscovery" : MessageLookupByLibrary.simpleMessage("Discovery feature reopened, pleast restart the app"),
"toastFileError" : MessageLookupByLibrary.simpleMessage("File error, subscribe failed"),
@ -306,8 +314,8 @@ class MessageLookup extends MessageLookupByLibrary {
"unlike" : MessageLookupByLibrary.simpleMessage("Unlike"),
"unliked" : MessageLookupByLibrary.simpleMessage("Episode removed from favorite"),
"updateDate" : MessageLookupByLibrary.simpleMessage("Update date"),
"updateEpisodesCount" : m26,
"updateEpisodesCount" : m27,
"updateFailed" : MessageLookupByLibrary.simpleMessage("Update failed, network error"),
"version" : m27
"version" : m28
};
}

View File

@ -63,17 +63,19 @@ class MessageLookup extends MessageLookupByLibrary {
static m21(date) => "Supprimé le ${date}";
static m22(count) => "${Intl.plural(count, zero: 'A l\'instant', one: 'Il y a ${count} seconde', other: 'Il y a ${count} secondes')}";
static m22(count) => "${Intl.plural(count, zero: '0 sec', one: '${count} sec', other: '${count} sec')}";
static m23(time) => "Dernière écoute à ${time}";
static m23(count) => "${Intl.plural(count, zero: 'A l\'instant', one: 'Il y a ${count} seconde', other: 'Il y a ${count} secondes')}";
static m24(time) => "${time} Restant";
static m24(time) => "Dernière écoute à ${time}";
static m25(time) => "Jusqu\'à ${time}";
static m25(time) => "${time} Restant";
static m26(count) => "${Intl.plural(count, zero: 'Aucune mise à jour.', one: 'Mise à jour d\'${count} épisode.', other: 'Mise à jour de ${count} épisodes.')}";
static m26(time) => "Jusqu\'à ${time}";
static m27(version) => "Version : ${version}";
static m27(count) => "${Intl.plural(count, zero: 'Aucune mise à jour.', one: 'Mise à jour d\'${count} épisode.', other: 'Mise à jour de ${count} épisodes.')}";
static m28(version) => "Version : ${version}";
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
@ -187,6 +189,7 @@ class MessageLookup extends MessageLookupByLibrary {
"notificationUpdateError" : m18,
"oldestFirst" : MessageLookupByLibrary.simpleMessage("Le plus ancien en premier."),
"play" : MessageLookupByLibrary.simpleMessage("Lecture"),
"playback" : MessageLookupByLibrary.simpleMessage("Playback control"),
"playing" : MessageLookupByLibrary.simpleMessage("En cours"),
"plugins" : MessageLookupByLibrary.simpleMessage("Plugins"),
"podcast" : m19,
@ -214,7 +217,8 @@ class MessageLookup extends MessageLookupByLibrary {
"searchEpisode" : MessageLookupByLibrary.simpleMessage("Search episode"),
"searchInvalidRss" : MessageLookupByLibrary.simpleMessage("Lien RSS invalide"),
"searchPodcast" : MessageLookupByLibrary.simpleMessage("Chercher un podcast"),
"secondsAgo" : m22,
"secCount" : m22,
"secondsAgo" : m23,
"settingStorage" : MessageLookupByLibrary.simpleMessage("Espace de stockage"),
"settings" : MessageLookupByLibrary.simpleMessage("Paramètres"),
"settingsAccentColor" : MessageLookupByLibrary.simpleMessage("Couleur principale"),
@ -238,6 +242,8 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsEnableSyncing" : MessageLookupByLibrary.simpleMessage("Activer la synchronisation"),
"settingsEnableSyncingDes" : MessageLookupByLibrary.simpleMessage("Actualisez tous les podcasts en arrière-plan pour toujours afficher les derniers épisodes"),
"settingsExportDes" : MessageLookupByLibrary.simpleMessage("Exporter et importer les paramètres de l\'application"),
"settingsFastForwardSec" : MessageLookupByLibrary.simpleMessage("Fast forward seconds"),
"settingsFastForwardSecDes" : MessageLookupByLibrary.simpleMessage("Change the fast forward seconds in player"),
"settingsFeedback" : MessageLookupByLibrary.simpleMessage("Feedback"),
"settingsFeedbackDes" : MessageLookupByLibrary.simpleMessage("Report de bugs et demande d\'ajout de fonction"),
"settingsHistory" : MessageLookupByLibrary.simpleMessage("Historique"),
@ -263,6 +269,8 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsPrefrence" : MessageLookupByLibrary.simpleMessage("Préférences"),
"settingsRealDark" : MessageLookupByLibrary.simpleMessage("Noir profond"),
"settingsRealDarkDes" : MessageLookupByLibrary.simpleMessage("Activez pour un mode sombre accentué"),
"settingsRewindSec" : MessageLookupByLibrary.simpleMessage("Rewind seconds"),
"settingsRewindSecDes" : MessageLookupByLibrary.simpleMessage("Change the rewind seconds in player"),
"settingsSTAuto" : MessageLookupByLibrary.simpleMessage("Activation automatique de la minuterie"),
"settingsSTAutoDes" : MessageLookupByLibrary.simpleMessage("Démarrer la minuterie à l\'horaire programmé"),
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Temps par défaut"),
@ -283,9 +291,9 @@ class MessageLookup extends MessageLookupByLibrary {
"subscribe" : MessageLookupByLibrary.simpleMessage("Abonnements"),
"subscribeExportDes" : MessageLookupByLibrary.simpleMessage("Exporter le fichier OPML de tous les podcasts"),
"systemDefault" : MessageLookupByLibrary.simpleMessage("Valeur du système par défaut"),
"timeLastPlayed" : m23,
"timeLeft" : m24,
"to" : m25,
"timeLastPlayed" : m24,
"timeLeft" : m25,
"to" : m26,
"toastAddPlaylist" : MessageLookupByLibrary.simpleMessage("Ajouté à la playlist."),
"toastDiscovery" : MessageLookupByLibrary.simpleMessage("Tutoriel réinitialisé, veuillez redémarrer l\'application."),
"toastFileError" : MessageLookupByLibrary.simpleMessage("Erreur du fichier, échec de l\'abonnement."),
@ -306,8 +314,8 @@ class MessageLookup extends MessageLookupByLibrary {
"unlike" : MessageLookupByLibrary.simpleMessage("Dislike"),
"unliked" : MessageLookupByLibrary.simpleMessage("L\'épisode a été supprimé des favoris."),
"updateDate" : MessageLookupByLibrary.simpleMessage("Date de mise à jour"),
"updateEpisodesCount" : m26,
"updateEpisodesCount" : m27,
"updateFailed" : MessageLookupByLibrary.simpleMessage("Échec de la mise à jour, erreur de réseau"),
"version" : m27
"version" : m28
};
}

View File

@ -63,17 +63,19 @@ class MessageLookup extends MessageLookupByLibrary {
static m21(date) => "${date}移除";
static m22(count) => "${Intl.plural(count, zero: '刚刚', other: '${count}')}";
static m22(count) => "${Intl.plural(count, zero: '0 秒', other: '${count} 秒')}";
static m23(time) => "上次播放${time}";
static m23(count) => "${Intl.plural(count, zero: '刚刚', other: '${count}秒前')}";
static m24(time) => "剩余 ${time}";
static m24(time) => "上次播放${time}";
static m25(time) => "${time}";
static m25(time) => "剩余 ${time}";
static m26(count) => "${Intl.plural(count, zero: '未有更新', other: '更新 ${count} 集节目')}";
static m26(time) => "${time}";
static m27(version) => "版本:${version}";
static m27(count) => "${Intl.plural(count, zero: '未有更新', other: '更新 ${count} 集节目')}";
static m28(version) => "版本:${version}";
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
@ -187,6 +189,7 @@ class MessageLookup extends MessageLookupByLibrary {
"notificationUpdateError" : m18,
"oldestFirst" : MessageLookupByLibrary.simpleMessage("由旧到新"),
"play" : MessageLookupByLibrary.simpleMessage("播放"),
"playback" : MessageLookupByLibrary.simpleMessage("播放控制"),
"playing" : MessageLookupByLibrary.simpleMessage("正在播放"),
"plugins" : MessageLookupByLibrary.simpleMessage("插件"),
"podcast" : m19,
@ -214,7 +217,8 @@ class MessageLookup extends MessageLookupByLibrary {
"searchEpisode" : MessageLookupByLibrary.simpleMessage("搜索节目"),
"searchInvalidRss" : MessageLookupByLibrary.simpleMessage("RSS 链接错误"),
"searchPodcast" : MessageLookupByLibrary.simpleMessage("搜索播客"),
"secondsAgo" : m22,
"secCount" : m22,
"secondsAgo" : m23,
"settingStorage" : MessageLookupByLibrary.simpleMessage("储存空间"),
"settings" : MessageLookupByLibrary.simpleMessage("设置"),
"settingsAccentColor" : MessageLookupByLibrary.simpleMessage("次要颜色"),
@ -238,6 +242,8 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsEnableSyncing" : MessageLookupByLibrary.simpleMessage("开启自动更新"),
"settingsEnableSyncingDes" : MessageLookupByLibrary.simpleMessage("在后台更新所有订阅播客"),
"settingsExportDes" : MessageLookupByLibrary.simpleMessage("导出及恢复所有设置项"),
"settingsFastForwardSec" : MessageLookupByLibrary.simpleMessage("快进时间"),
"settingsFastForwardSecDes" : MessageLookupByLibrary.simpleMessage("修改播放器快进时间"),
"settingsFeedback" : MessageLookupByLibrary.simpleMessage("反馈"),
"settingsFeedbackDes" : MessageLookupByLibrary.simpleMessage("意见与建议"),
"settingsHistory" : MessageLookupByLibrary.simpleMessage("历史记录"),
@ -263,6 +269,8 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsPrefrence" : MessageLookupByLibrary.simpleMessage("首选项"),
"settingsRealDark" : MessageLookupByLibrary.simpleMessage("极黑"),
"settingsRealDarkDes" : MessageLookupByLibrary.simpleMessage("如果夜不够黑,请开启"),
"settingsRewindSec" : MessageLookupByLibrary.simpleMessage("快退时间"),
"settingsRewindSecDes" : MessageLookupByLibrary.simpleMessage("修改播放器快退时间"),
"settingsSTAuto" : MessageLookupByLibrary.simpleMessage("自动睡眠模式"),
"settingsSTAutoDes" : MessageLookupByLibrary.simpleMessage("定期开启睡眠模式"),
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("默认时长"),
@ -283,9 +291,9 @@ class MessageLookup extends MessageLookupByLibrary {
"subscribe" : MessageLookupByLibrary.simpleMessage("订阅"),
"subscribeExportDes" : MessageLookupByLibrary.simpleMessage("导出 OMPL 文件"),
"systemDefault" : MessageLookupByLibrary.simpleMessage("系统默认"),
"timeLastPlayed" : m23,
"timeLeft" : m24,
"to" : m25,
"timeLastPlayed" : m24,
"timeLeft" : m25,
"to" : m26,
"toastAddPlaylist" : MessageLookupByLibrary.simpleMessage("添加到播放列表"),
"toastDiscovery" : MessageLookupByLibrary.simpleMessage("重启应用后可查看"),
"toastFileError" : MessageLookupByLibrary.simpleMessage("文件错误,导入失败"),
@ -306,8 +314,8 @@ class MessageLookup extends MessageLookupByLibrary {
"unlike" : MessageLookupByLibrary.simpleMessage("取消喜欢"),
"unliked" : MessageLookupByLibrary.simpleMessage("从收藏移除"),
"updateDate" : MessageLookupByLibrary.simpleMessage("更新日期"),
"updateEpisodesCount" : m26,
"updateEpisodesCount" : m27,
"updateFailed" : MessageLookupByLibrary.simpleMessage("更新失败"),
"version" : m27
"version" : m28
};
}

View File

@ -1163,6 +1163,16 @@ class S {
);
}
/// `Playback control`
String get playback {
return Intl.message(
'Playback control',
name: 'playback',
desc: '',
args: [],
);
}
/// `Playing`
String get playing {
return Intl.message(
@ -1436,6 +1446,19 @@ class S {
);
}
/// `{count, plural, zero{0 sec} one{{count} sec} other{{count} sec}}`
String secCount(num count) {
return Intl.plural(
count,
zero: '0 sec',
one: '$count sec',
other: '$count sec',
name: 'secCount',
desc: '',
args: [count],
);
}
/// `{count, plural, zero{Just now} one{{count} second ago} other{{count} seconds ago}}`
String secondsAgo(num count) {
return Intl.plural(
@ -1669,6 +1692,26 @@ class S {
);
}
/// `Fast forward seconds`
String get settingsFastForwardSec {
return Intl.message(
'Fast forward seconds',
name: 'settingsFastForwardSec',
desc: '',
args: [],
);
}
/// `Change the fast forward seconds in player`
String get settingsFastForwardSecDes {
return Intl.message(
'Change the fast forward seconds in player',
name: 'settingsFastForwardSecDes',
desc: '',
args: [],
);
}
/// `Feedback`
String get settingsFeedback {
return Intl.message(
@ -1919,6 +1962,26 @@ class S {
);
}
/// `Rewind seconds`
String get settingsRewindSec {
return Intl.message(
'Rewind seconds',
name: 'settingsRewindSec',
desc: '',
args: [],
);
}
/// `Change the rewind seconds in player`
String get settingsRewindSecDes {
return Intl.message(
'Change the rewind seconds in player',
name: 'settingsRewindSecDes',
desc: '',
args: [],
);
}
/// `Auto turn on sleep timer`
String get settingsSTAuto {
return Intl.message(

View File

@ -18,8 +18,8 @@ import '../util/extension_helper.dart';
import '../util/custom_widget.dart';
import '../util/custom_slider.dart';
import '../episodes/episode_detail.dart';
import 'playlist.dart';
import '../util/audiopanel.dart';
import 'playlist.dart';
final List<BoxShadow> _customShadow = [
BoxShadow(blurRadius: 26, offset: Offset(-6, -6), color: Colors.white),
@ -1274,11 +1274,10 @@ class _ControlPanelState extends State<ControlPanel>
children: [
IconButton(
padding: EdgeInsets.symmetric(horizontal: 25.0),
onPressed: playing
? () => audio.forwardAudio(-10)
: null,
onPressed:
playing ? () => audio.rewind() : null,
iconSize: 32.0,
icon: Icon(Icons.replay_10),
icon: Icon(Icons.replay),
color: Colors.grey[500]),
Container(
margin: EdgeInsets.symmetric(horizontal: 30),
@ -1343,11 +1342,10 @@ class _ControlPanelState extends State<ControlPanel>
),
IconButton(
padding: EdgeInsets.symmetric(horizontal: 25.0),
onPressed: playing
? () => audio.forwardAudio(30)
: null,
onPressed:
playing ? () => audio.fastForward() : null,
iconSize: 32.0,
icon: Icon(Icons.forward_30),
icon: Icon(Icons.forward),
color: Colors.grey[500]),
],
),

View File

@ -272,6 +272,8 @@
"@oldestFirst": {},
"play": "Play",
"@play": {},
"playback": "Playback control",
"@playback": {},
"playing": "Playing",
"@playing": {},
"plugins": "Plugins",
@ -343,6 +345,8 @@
"@searchInvalidRss": {},
"searchPodcast": "Search podcast",
"@searchPodcast": {},
"secCount": "{count, plural, zero{0 sec} one{{count} sec} other{{count} sec}}",
"@secCount": {},
"secondsAgo": "{count, plural, zero{Just now} one{{count} second ago} other{{count} seconds ago}}",
"@secondsAgo": {},
"settings": "Settings",
@ -391,6 +395,10 @@
"@settingsEnableSyncingDes": {},
"settingsExportDes": "Export and import app settings",
"@settingsExportDes": {},
"settingsFastForwardSec": "Fast forward seconds",
"@settingsFastForwardSec": {},
"settingsFastForwardSecDes": "Change the fast forward seconds in player",
"@settingsFastForwardSecDes": {},
"settingsFeedback": "Feedback",
"@settingsFeedback": {},
"settingsFeedbackDes": "Bugs and features request",
@ -441,6 +449,10 @@
"@settingsRealDark": {},
"settingsRealDarkDes": "Turn on if you think the night is not dark enough",
"@settingsRealDarkDes": {},
"settingsRewindSec": "Rewind seconds",
"@settingsRewindSec": {},
"settingsRewindSecDes": "Change the rewind seconds in player",
"@settingsRewindSecDes": {},
"settingsSTAuto": "Auto turn on sleep timer",
"@settingsSTAuto": {},
"settingsSTAutoDes": "Auto start sleep timer at scheduled time",

View File

@ -272,6 +272,8 @@
"@oldestFirst": {},
"play": "Lecture",
"@play": {},
"playback": "Playback control",
"@playback": {},
"playing": "En cours",
"@playing": {},
"plugins": "Plugins",
@ -343,6 +345,8 @@
"@searchInvalidRss": {},
"searchPodcast": "Chercher un podcast",
"@searchPodcast": {},
"secCount": "{count, plural, zero{0 sec} one{{count} sec} other{{count} sec}}",
"@secCount": {},
"secondsAgo": "{count, plural, zero{A l'instant} one{Il y a {count} seconde} other{Il y a {count} secondes}}",
"@secondsAgo": {},
"settings": "Paramètres",
@ -391,6 +395,10 @@
"@settingsEnableSyncingDes": {},
"settingsExportDes": "Exporter et importer les paramètres de l'application",
"@settingsExportDes": {},
"settingsFastForwardSec": "Fast forward seconds",
"@settingsFastForwardSec": {},
"settingsFastForwardSecDes": "Change the fast forward seconds in player",
"@settingsFastForwardSecDes": {},
"settingsFeedback": "Feedback",
"@settingsFeedback": {},
"settingsFeedbackDes": "Report de bugs et demande d'ajout de fonction",
@ -441,6 +449,10 @@
"@settingsRealDark": {},
"settingsRealDarkDes": "Activez pour un mode sombre accentué",
"@settingsRealDarkDes": {},
"settingsRewindSec": "Rewind seconds",
"@settingsRewindSec": {},
"settingsRewindSecDes": "Change the rewind seconds in player",
"@settingsRewindSecDes": {},
"settingsSTAuto": "Activation automatique de la minuterie",
"@settingsSTAuto": {},
"settingsSTAutoDes": "Démarrer la minuterie à l'horaire programmé",

View File

@ -272,6 +272,8 @@
"@oldestFirst": {},
"play": "播放",
"@play": {},
"playback": "播放控制",
"@playback": {},
"playing": "正在播放",
"@playing": {},
"plugins": "插件",
@ -343,6 +345,8 @@
"@searchInvalidRss": {},
"searchPodcast": "搜索播客",
"@searchPodcast": {},
"secCount": "{count, plural, zero{0 秒} other{{count} 秒}}",
"@secCount": {},
"secondsAgo": "{count, plural, zero{刚刚} other{{count}秒前}}",
"@secondsAgo": {},
"settings": "设置",
@ -391,6 +395,10 @@
"@settingsEnableSyncingDes": {},
"settingsExportDes": "导出及恢复所有设置项",
"@settingsExportDes": {},
"settingsFastForwardSec": "快进时间",
"@settingsFastForwardSec": {},
"settingsFastForwardSecDes": "修改播放器快进时间",
"@settingsFastForwardSecDes": {},
"settingsFeedback": "反馈",
"@settingsFeedback": {},
"settingsFeedbackDes": "意见与建议",
@ -441,6 +449,10 @@
"@settingsRealDark": {},
"settingsRealDarkDes": "如果夜不够黑,请开启",
"@settingsRealDarkDes": {},
"settingsRewindSec": "快退时间",
"@settingsRewindSec": {},
"settingsRewindSecDes": "修改播放器快退时间",
"@settingsRewindSecDes": {},
"settingsSTAuto": "自动睡眠模式",
"@settingsSTAuto": {},
"settingsSTAutoDes": "定期开启睡眠模式",

View File

@ -14,10 +14,7 @@ import '../util/general_dialog.dart';
import '../util/extension_helper.dart';
import '../util/custom_dropdown.dart';
String stringForMins(int mins) {
if (mins == null) return null;
return '${(mins ~/ 60)}:${(mins.truncate() % 60).toString().padLeft(2, '0')}';
}
const List secondsToSelect = [10, 15, 20, 25, 30, 45, 60];
class PlaySetting extends StatelessWidget {
Widget _modeWidget(BuildContext context) {
@ -158,7 +155,7 @@ class PlaySetting extends StatelessWidget {
topLeft: Radius.circular(5)),
),
padding: const EdgeInsets.all(8.0),
child: Text(s.from(stringForMins(data.item1))),
child: Text(s.from(data.item1.toTime)),
),
),
),
@ -224,7 +221,7 @@ class PlaySetting extends StatelessWidget {
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(5),
topRight: Radius.circular(5))),
child: Text(s.to(stringForMins(data.item2)),
child: Text(s.to(data.item2.toTime),
style: TextStyle(color: Colors.white)),
),
),
@ -302,6 +299,73 @@ class PlaySetting extends StatelessWidget {
Padding(
padding: const EdgeInsets.all(10.0),
),
Container(
height: 30.0,
padding: EdgeInsets.symmetric(horizontal: 70),
alignment: Alignment.centerLeft,
child: Text(s.playback,
style: Theme.of(context)
.textTheme
.bodyText1
.copyWith(color: Theme.of(context).accentColor)),
),
ListView(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: <Widget>[
ListTile(
contentPadding: EdgeInsets.only(
left: 80.0, right: 20, bottom: 10, top: 10),
title: Text(s.settingsFastForwardSec),
subtitle: Text(s.settingsFastForwardSecDes),
trailing: Selector<SettingState, int>(
selector: (_, settings) =>
settings.fastForwardSeconds,
builder: (_, data, __) => MyDropdownButton(
hint: Text(s.secCount(data)),
underline: Center(),
elevation: 1,
displayItemCount: 5,
isDense: true,
value: data,
onChanged: (int value) =>
settings.setFastForwardSeconds = value,
items: secondsToSelect
.map<DropdownMenuItem<int>>((e) {
return DropdownMenuItem<int>(
value: e, child: Text(s.secCount(e)));
}).toList()),
),
),
ListTile(
contentPadding: EdgeInsets.only(
left: 80.0, right: 20, bottom: 10, top: 10),
title: Text(s.settingsRewindSec),
subtitle: Text(s.settingsRewindSecDes),
trailing: Selector<SettingState, int>(
selector: (_, settings) => settings.rewindSeconds,
builder: (_, data, __) => MyDropdownButton(
hint: Text(s.secCount(data)),
underline: Center(),
elevation: 1,
displayItemCount: 5,
isDense: true,
value: data,
onChanged: (int value) =>
settings.setRewindSeconds = value,
items: secondsToSelect
.map<DropdownMenuItem<int>>((e) {
return DropdownMenuItem<int>(
value: e, child: Text(s.secCount(e)));
}).toList()),
),
),
Divider(),
]),
Padding(
padding: const EdgeInsets.all(10.0),
),
Container(
height: 30.0,
padding: EdgeInsets.symmetric(horizontal: 70),
@ -337,6 +401,7 @@ class PlaySetting extends StatelessWidget {
}).toList()),
),
),
Divider(),
Selector<SettingState, bool>(
selector: (_, settings) => settings.autoSleepTimer,
builder: (_, data, __) => ListTile(
@ -376,6 +441,7 @@ class PlaySetting extends StatelessWidget {
Divider(height: 2)
],
),
SizedBox(height: 20)
],
),
],

View File

@ -36,9 +36,9 @@ MediaControl stopControl = MediaControl(
label: 'Stop',
action: MediaAction.stop,
);
MediaControl forward30 = MediaControl(
androidIcon: 'drawable/ic_stat_forward_30',
label: 'forward30',
MediaControl forward = MediaControl(
androidIcon: 'drawable/baseline_fast_forward_white_24',
label: 'forward',
action: MediaAction.fastForward,
);
@ -530,6 +530,14 @@ class AudioPlayerNotifier extends ChangeNotifier {
AudioService.seekTo(Duration(milliseconds: pos));
}
fastForward() async {
await AudioService.fastForward();
}
rewind() async {
await AudioService.rewind();
}
seekTo(int position) async {
if (_audioState != AudioProcessingState.connecting &&
_audioState != AudioProcessingState.none)
@ -848,7 +856,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
@override
void onRewind() {
_seekRelative(rewindInterval);
_seekRelative(-rewindInterval);
}
@override
@ -930,9 +938,9 @@ class AudioPlayerTask extends BackgroundAudioTask {
List<MediaControl> getControls() {
if (_playing) {
return [pauseControl, forward30, skipToNextControl, stopControl];
return [pauseControl, forward, skipToNextControl, stopControl];
} else {
return [playControl, forward30, skipToNextControl, stopControl];
return [playControl, forward, skipToNextControl, stopControl];
}
}
}

View File

@ -77,33 +77,29 @@ ThemeData lightTheme = ThemeData(
);
class SettingState extends ChangeNotifier {
KeyValueStorage themeStorage = KeyValueStorage(themesKey);
KeyValueStorage accentStorage = KeyValueStorage(accentsKey);
KeyValueStorage autoupdateStorage = KeyValueStorage(autoUpdateKey);
KeyValueStorage intervalStorage = KeyValueStorage(updateIntervalKey);
KeyValueStorage downloadUsingDataStorage =
KeyValueStorage(downloadUsingDataKey);
KeyValueStorage introStorage = KeyValueStorage(introKey);
KeyValueStorage realDarkStorage = KeyValueStorage(realDarkKey);
KeyValueStorage autoPlayStorage = KeyValueStorage(autoPlayKey);
KeyValueStorage defaultSleepTimerStorage =
KeyValueStorage(defaultSleepTimerKey);
KeyValueStorage autoSleepTimerStorage = KeyValueStorage(autoSleepTimerKey);
KeyValueStorage autoSleepTimerModeStorage =
KeyValueStorage(autoSleepTimerModeKey);
KeyValueStorage autoSleepTimerStartStorage =
KeyValueStorage(autoSleepTimerStartKey);
KeyValueStorage autoSleepTimerEndStorage =
KeyValueStorage(autoSleepTimerEndKey);
KeyValueStorage tapToOpenPopupMenuStorage =
KeyValueStorage(tapToOpenPopupMenuKey);
KeyValueStorage cacheStorage = KeyValueStorage(cacheMaxKey);
KeyValueStorage podcastLayoutStorage = KeyValueStorage(podcastLayoutKey);
KeyValueStorage favLayoutStorage = KeyValueStorage(favLayoutKey);
KeyValueStorage downloadLayoutStorage = KeyValueStorage(downloadLayoutKey);
KeyValueStorage recentLayoutStorage = KeyValueStorage(recentLayoutKey);
KeyValueStorage autoDeleteStorage = KeyValueStorage(autoDeleteKey);
KeyValueStorage autoDownloadStorage = KeyValueStorage(autoDownloadNetworkKey);
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);
Future initData() async {
await _getTheme();
@ -238,17 +234,35 @@ class SettingState extends ChangeNotifier {
_saveAutoSleepTimerEnd();
}
int _fastForwardSeconds;
int get fastForwardSeconds => _fastForwardSeconds;
set setFastForwardSeconds(int sec) {
_fastForwardSeconds = sec;
notifyListeners();
_saveFastForwardSeconds();
}
int _rewindSeconds;
int get rewindSeconds => _rewindSeconds;
set setRewindSeconds(int sec) {
_rewindSeconds = sec;
notifyListeners();
_saveRewindSeconds();
}
@override
void addListener(VoidCallback listener) {
super.addListener(listener);
_getAutoUpdate();
_getDownloadUsingData();
_getSleepTimerData();
_getPlayerSeconds();
_getUpdateInterval().then((value) async {
if (_initUpdateTag == 0)
setWorkManager(24);
//Restart worker if anythin changed in worker callback.
//varsion 2 add auto download new episodes
/// Restart worker if anythin changed in worker callback.
/// varsion 2 add auto download new episodes
else if (_autoUpdate && _initialShowIntor == 1) {
await cancelWork();
setWorkManager(_initUpdateTag);
@ -314,6 +328,12 @@ class SettingState extends ChangeNotifier {
_autoSleepTimerMode = await autoSleepTimerModeStorage.getInt();
}
Future _getPlayerSeconds() async {
_rewindSeconds = await rewindSecondsStorage.getInt(defaultValue: 10);
_fastForwardSeconds =
await fastForwardSecondsStorage.getInt(defaultValue: 30);
}
Future _saveAccentSetColor() async {
await accentStorage
.saveString(_accentSetColor.toString().substring(10, 16));
@ -363,6 +383,14 @@ class SettingState extends ChangeNotifier {
await autoSleepTimerEndStorage.saveInt(_autoSleepTimerEnd);
}
Future _saveFastForwardSeconds() async {
await fastForwardSecondsStorage.saveInt(_fastForwardSeconds);
}
Future _saveRewindSeconds() async {
await rewindSecondsStorage.saveInt(_rewindSeconds);
}
Future<SettingsBackup> backup() async {
int theme = await themeStorage.getInt();
String accentColor = await accentStorage.getString();
@ -392,6 +420,9 @@ class SettingState extends ChangeNotifier {
int defaultSleepTime = await defaultSleepTimerStorage.getInt();
bool tapToOpenPopupMenu = await KeyValueStorage(tapToOpenPopupMenuKey)
.getBool(defaultValue: false);
int fastForwardSeconds =
await fastForwardSecondsStorage.getInt(defaultValue: 30);
int rewindSeconds = await rewindSecondsStorage.getInt(defaultValue: 10);
return SettingsBackup(
theme: theme,
@ -414,7 +445,9 @@ class SettingState extends ChangeNotifier {
autoSleepTimerEnd: autoSleepTimerEnd,
autoSleepTimerMode: autoSleepTimerMode,
defaultSleepTime: defaultSleepTime,
tapToOpenPopupMenu: tapToOpenPopupMenu);
tapToOpenPopupMenu: tapToOpenPopupMenu,
fastForwardSeconds: fastForwardSeconds,
rewindSeconds: rewindSeconds);
}
Future<void> restore(SettingsBackup backup) async {
@ -440,6 +473,8 @@ class SettingState extends ChangeNotifier {
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(tapToOpenPopupMenuKey)
.saveBool(backup.tapToOpenPopupMenu);
await initData();

View File

@ -20,6 +20,8 @@ class SettingsBackup {
final int defaultSleepTime;
final int autoSleepTimerMode;
final bool tapToOpenPopupMenu;
final int fastForwardSeconds;
final int rewindSeconds;
SettingsBackup(
{this.theme,
this.accentColor,
@ -41,7 +43,9 @@ class SettingsBackup {
this.autoSleepTimerEnd,
this.defaultSleepTime,
this.autoSleepTimerMode,
this.tapToOpenPopupMenu});
this.tapToOpenPopupMenu,
this.fastForwardSeconds,
this.rewindSeconds});
Map<String, Object> toJson() {
return {
@ -64,7 +68,9 @@ class SettingsBackup {
'autoSleepTimerStart': autoSleepTimerStart,
'autoSleepTimerEnd': autoSleepTimerEnd,
'autoSleepTimerMode': autoSleepTimerMode,
'tapToOpenPopupMenu': tapToOpenPopupMenu
'tapToOpenPopupMenu': tapToOpenPopupMenu,
'fastForwardSeconds': fastForwardSeconds,
'rewindSeconds': rewindSeconds
};
}
@ -90,6 +96,8 @@ class SettingsBackup {
autoSleepTimerStart: json['autoSleepeTimerStart'] as int,
autoSleepTimerEnd: json['autoSleepTimerEnd'] as int,
autoSleepTimerMode: json['autoSleepTimerMode'] as int,
tapToOpenPopupMenu: json['tapToOpenPopupMenu'] as bool);
tapToOpenPopupMenu: json['tapToOpenPopupMenu'] as bool,
fastForwardSeconds: json['fastForwardSeconds'] as int,
rewindSeconds: json['rewindSeconds'] as int);
}
}