Customize the speeds available.
This commit is contained in:
parent
8aad960ed8
commit
d1668a923f
|
@ -295,6 +295,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Default time"),
|
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Default time"),
|
||||||
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("Default time for sleep timer"),
|
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("Default time for sleep timer"),
|
||||||
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("Auto sleep timer mode"),
|
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("Auto sleep timer mode"),
|
||||||
|
"settingsSpeeds" : MessageLookupByLibrary.simpleMessage("Speeds"),
|
||||||
|
"settingsSpeedsDes" : MessageLookupByLibrary.simpleMessage("Customize the speeds available"),
|
||||||
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("Manage cache and download storage"),
|
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("Manage cache and download storage"),
|
||||||
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("Syncing"),
|
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("Syncing"),
|
||||||
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("Refresh podcasts in the background"),
|
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("Refresh podcasts in the background"),
|
||||||
|
|
|
@ -295,6 +295,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Tiempo predeterminado"),
|
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Tiempo predeterminado"),
|
||||||
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("Tiempo predeterminado de temporizador de sueño"),
|
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("Tiempo predeterminado de temporizador de sueño"),
|
||||||
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("Modo automático de tempo. de sueño"),
|
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("Modo automático de tempo. de sueño"),
|
||||||
|
"settingsSpeeds" : MessageLookupByLibrary.simpleMessage("Speeds"),
|
||||||
|
"settingsSpeedsDes" : MessageLookupByLibrary.simpleMessage("Customize the speeds available"),
|
||||||
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("Administrar cache y almacenamiento de descargas"),
|
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("Administrar cache y almacenamiento de descargas"),
|
||||||
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("Sincronización"),
|
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("Sincronización"),
|
||||||
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("Actualizar podcasts en el fondo"),
|
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("Actualizar podcasts en el fondo"),
|
||||||
|
|
|
@ -295,6 +295,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Durée par défaut"),
|
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("Durée par défaut"),
|
||||||
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("Configuration de la minuterie"),
|
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("Configuration de la minuterie"),
|
||||||
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("Mode minuterie automatique"),
|
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("Mode minuterie automatique"),
|
||||||
|
"settingsSpeeds" : MessageLookupByLibrary.simpleMessage("Speeds"),
|
||||||
|
"settingsSpeedsDes" : MessageLookupByLibrary.simpleMessage("Customize the speeds avaliable"),
|
||||||
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("Gestion du cache et de l\'espace de stockage"),
|
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("Gestion du cache et de l\'espace de stockage"),
|
||||||
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("Synchronisation"),
|
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("Synchronisation"),
|
||||||
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("Actualisation des podcasts en arrière-plan"),
|
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("Actualisation des podcasts en arrière-plan"),
|
||||||
|
|
|
@ -295,6 +295,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("默认时长"),
|
"settingsSTDefaultTime" : MessageLookupByLibrary.simpleMessage("默认时长"),
|
||||||
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("睡眠模式默认时长"),
|
"settingsSTDefautTimeDes" : MessageLookupByLibrary.simpleMessage("睡眠模式默认时长"),
|
||||||
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("自动睡眠模式默认时长"),
|
"settingsSTMode" : MessageLookupByLibrary.simpleMessage("自动睡眠模式默认时长"),
|
||||||
|
"settingsSpeeds" : MessageLookupByLibrary.simpleMessage("播放速度"),
|
||||||
|
"settingsSpeedsDes" : MessageLookupByLibrary.simpleMessage("设置播放速度选项"),
|
||||||
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("管理缓存和下载空间"),
|
"settingsStorageDes" : MessageLookupByLibrary.simpleMessage("管理缓存和下载空间"),
|
||||||
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("同步"),
|
"settingsSyncing" : MessageLookupByLibrary.simpleMessage("同步"),
|
||||||
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("在后台更新播客"),
|
"settingsSyncingDes" : MessageLookupByLibrary.simpleMessage("在后台更新播客"),
|
||||||
|
|
|
@ -2172,6 +2172,26 @@ class S {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Speeds`
|
||||||
|
String get settingsSpeeds {
|
||||||
|
return Intl.message(
|
||||||
|
'Speeds',
|
||||||
|
name: 'settingsSpeeds',
|
||||||
|
desc: 'Playback speeds setting.',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Customize the speeds available`
|
||||||
|
String get settingsSpeedsDes {
|
||||||
|
return Intl.message(
|
||||||
|
'Customize the speeds available',
|
||||||
|
name: 'settingsSpeedsDes',
|
||||||
|
desc: 'Playback speed setting description',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// `Auto turn on sleep timer`
|
/// `Auto turn on sleep timer`
|
||||||
String get settingsSTAuto {
|
String get settingsSTAuto {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
|
|
|
@ -39,7 +39,6 @@ final List<BoxShadow> _customShadowNight = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const List kMinsToSelect = [10, 15, 20, 25, 30, 45, 60, 70, 80, 90, 99];
|
const List kMinsToSelect = [10, 15, 20, 25, 30, 45, 60, 70, 80, 90, 99];
|
||||||
const List kSpeedToSelect = [0.5, 0.6, 0.8, 1.0, 1.1, 1.2, 1.5, 2.0];
|
|
||||||
const List kMinPlayerHeight = <double>[70.0, 75.0, 80.0];
|
const List kMinPlayerHeight = <double>[70.0, 75.0, 80.0];
|
||||||
const List kMaxPlayerHeight = <double>[300.0, 325.0, 350.0];
|
const List kMaxPlayerHeight = <double>[300.0, 325.0, 350.0];
|
||||||
|
|
||||||
|
@ -912,7 +911,6 @@ class ControlPanel extends StatefulWidget {
|
||||||
|
|
||||||
class _ControlPanelState extends State<ControlPanel>
|
class _ControlPanelState extends State<ControlPanel>
|
||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
double _speedSelected;
|
|
||||||
double _setSpeed;
|
double _setSpeed;
|
||||||
AnimationController _controller;
|
AnimationController _controller;
|
||||||
Animation<double> _animation;
|
Animation<double> _animation;
|
||||||
|
@ -939,9 +937,13 @@ class _ControlPanelState extends State<ControlPanel>
|
||||||
color: Colors.black)
|
color: Colors.black)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Future<List<double>> _getSpeedList() async {
|
||||||
|
var storage = KeyValueStorage('speedListKey');
|
||||||
|
return await storage.getSpeedList();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_speedSelected = 0;
|
|
||||||
_setSpeed = 0;
|
_setSpeed = 0;
|
||||||
_tabController = TabController(vsync: this, length: 2)
|
_tabController = TabController(vsync: this, length: 2)
|
||||||
..addListener(() {
|
..addListener(() {
|
||||||
|
@ -1294,10 +1296,14 @@ class _ControlPanelState extends State<ControlPanel>
|
||||||
children: [
|
children: [
|
||||||
if (height <= widget.maxHeight)
|
if (height <= widget.maxHeight)
|
||||||
Selector<AudioPlayerNotifier,
|
Selector<AudioPlayerNotifier,
|
||||||
Tuple3<EpisodeBrief, bool, bool>>(
|
Tuple4<EpisodeBrief, bool, bool, double>>(
|
||||||
selector: (_, audio) => Tuple3(audio.episode,
|
selector: (_, audio) => Tuple4(
|
||||||
audio.stopOnComplete, audio.startSleepTimer),
|
audio.episode,
|
||||||
|
audio.stopOnComplete,
|
||||||
|
audio.startSleepTimer,
|
||||||
|
audio.currentSpeed),
|
||||||
builder: (_, data, __) {
|
builder: (_, data, __) {
|
||||||
|
final currentSpeed = data.item4 ?? 1.0;
|
||||||
return Container(
|
return Container(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.symmetric(horizontal: 20.0),
|
const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
|
@ -1347,69 +1353,71 @@ class _ControlPanelState extends State<ControlPanel>
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Row(
|
child: FutureBuilder<List<double>>(
|
||||||
children: kSpeedToSelect
|
future: _getSpeedList(),
|
||||||
.map<Widget>((e) => InkWell(
|
initialData: [],
|
||||||
onTap: () {
|
builder: (context, snapshot) => Row(
|
||||||
if (_setSpeed == 1) {
|
children: snapshot.data
|
||||||
setState(() =>
|
.map<Widget>((e) => InkWell(
|
||||||
_speedSelected = e);
|
onTap: () {
|
||||||
audio.setSpeed(e);
|
if (_setSpeed == 1) {
|
||||||
}
|
audio.setSpeed(e);
|
||||||
},
|
}
|
||||||
child: Container(
|
},
|
||||||
height: 30,
|
child: Container(
|
||||||
width: 30,
|
height: 30,
|
||||||
margin:
|
width: 30,
|
||||||
EdgeInsets.symmetric(
|
margin: EdgeInsets
|
||||||
horizontal: 5),
|
.symmetric(
|
||||||
decoration: e ==
|
horizontal: 5),
|
||||||
_speedSelected &&
|
decoration: e ==
|
||||||
_setSpeed > 0
|
currentSpeed &&
|
||||||
? BoxDecoration(
|
_setSpeed > 0
|
||||||
color: context
|
? BoxDecoration(
|
||||||
.accentColor,
|
color: context
|
||||||
shape: BoxShape
|
.accentColor,
|
||||||
.circle,
|
shape: BoxShape
|
||||||
boxShadow: context
|
.circle,
|
||||||
.brightness ==
|
boxShadow: context
|
||||||
Brightness
|
.brightness ==
|
||||||
.light
|
Brightness
|
||||||
? customShadow(
|
.light
|
||||||
1.0)
|
? customShadow(
|
||||||
: customShadowNight(
|
1.0)
|
||||||
1.0),
|
: customShadowNight(
|
||||||
)
|
1.0),
|
||||||
: BoxDecoration(
|
)
|
||||||
color: context
|
: BoxDecoration(
|
||||||
.primaryColor,
|
color: context
|
||||||
shape: BoxShape
|
.primaryColor,
|
||||||
.circle,
|
shape: BoxShape
|
||||||
boxShadow: context
|
.circle,
|
||||||
.brightness ==
|
boxShadow: context
|
||||||
Brightness
|
.brightness ==
|
||||||
.light
|
Brightness
|
||||||
? customShadow(1 -
|
.light
|
||||||
_setSpeed)
|
? customShadow(1 -
|
||||||
: customShadowNight(1 -
|
_setSpeed)
|
||||||
_setSpeed)),
|
: customShadowNight(1 -
|
||||||
alignment:
|
_setSpeed)),
|
||||||
Alignment.center,
|
alignment:
|
||||||
child: _setSpeed > 0
|
Alignment.center,
|
||||||
? Text(e.toString(),
|
child: _setSpeed > 0
|
||||||
style: TextStyle(
|
? Text(e.toString(),
|
||||||
fontWeight:
|
style: TextStyle(
|
||||||
FontWeight
|
fontWeight:
|
||||||
.bold,
|
FontWeight
|
||||||
color: e ==
|
.bold,
|
||||||
_speedSelected
|
color: e ==
|
||||||
? Colors
|
currentSpeed
|
||||||
.white
|
? Colors
|
||||||
: null))
|
.white
|
||||||
: Center(),
|
: null))
|
||||||
),
|
: Center(),
|
||||||
))
|
),
|
||||||
.toList(),
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1429,12 +1437,7 @@ class _ControlPanelState extends State<ControlPanel>
|
||||||
Transform.rotate(
|
Transform.rotate(
|
||||||
angle: math.pi * _setSpeed,
|
angle: math.pi * _setSpeed,
|
||||||
child: Text('X')),
|
child: Text('X')),
|
||||||
Selector<AudioPlayerNotifier, double>(
|
Text(currentSpeed.toStringAsFixed(1)),
|
||||||
selector: (_, audio) =>
|
|
||||||
audio.currentSpeed ?? 1.0,
|
|
||||||
builder: (context, value, child) =>
|
|
||||||
Text(value.toString()),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -493,6 +493,14 @@
|
||||||
"@settingsRewindSec": {},
|
"@settingsRewindSec": {},
|
||||||
"settingsRewindSecDes": "Change the rewind seconds in player",
|
"settingsRewindSecDes": "Change the rewind seconds in player",
|
||||||
"@settingsRewindSecDes": {},
|
"@settingsRewindSecDes": {},
|
||||||
|
"settingsSpeeds": "Speeds",
|
||||||
|
"@settingsSpeeds": {
|
||||||
|
"description": "Playback speeds setting."
|
||||||
|
},
|
||||||
|
"settingsSpeedsDes": "Customize the speeds available",
|
||||||
|
"@settingsSpeedsDes": {
|
||||||
|
"description": "Playback speed setting description"
|
||||||
|
},
|
||||||
"settingsSTAuto": "Auto turn on sleep timer",
|
"settingsSTAuto": "Auto turn on sleep timer",
|
||||||
"@settingsSTAuto": {},
|
"@settingsSTAuto": {},
|
||||||
"settingsSTAutoDes": "Auto start sleep timer at scheduled time",
|
"settingsSTAutoDes": "Auto start sleep timer at scheduled time",
|
||||||
|
|
|
@ -493,6 +493,14 @@
|
||||||
"@settingsRewindSec": {},
|
"@settingsRewindSec": {},
|
||||||
"settingsRewindSecDes": "Cambia los segundos de retroceso del reproductor",
|
"settingsRewindSecDes": "Cambia los segundos de retroceso del reproductor",
|
||||||
"@settingsRewindSecDes": {},
|
"@settingsRewindSecDes": {},
|
||||||
|
"settingsSpeeds": "Speeds",
|
||||||
|
"@settingsSpeeds": {
|
||||||
|
"description": "Playback speeds setting."
|
||||||
|
},
|
||||||
|
"settingsSpeedsDes": "Customize the speeds available",
|
||||||
|
"@settingsSpeedsDes": {
|
||||||
|
"description": "Playback speed setting description"
|
||||||
|
},
|
||||||
"settingsSTAuto": "Encender temporizador de sueño automáticamente",
|
"settingsSTAuto": "Encender temporizador de sueño automáticamente",
|
||||||
"@settingsSTAuto": {},
|
"@settingsSTAuto": {},
|
||||||
"settingsSTAutoDes": "Encender temporizador de sueño en un horario determinado",
|
"settingsSTAutoDes": "Encender temporizador de sueño en un horario determinado",
|
||||||
|
|
|
@ -493,6 +493,14 @@
|
||||||
"@settingsRewindSec": {},
|
"@settingsRewindSec": {},
|
||||||
"settingsRewindSecDes": "Saut arrière",
|
"settingsRewindSecDes": "Saut arrière",
|
||||||
"@settingsRewindSecDes": {},
|
"@settingsRewindSecDes": {},
|
||||||
|
"settingsSpeeds": "Speeds",
|
||||||
|
"@settingsSpeeds": {
|
||||||
|
"description": "Playback speeds setting."
|
||||||
|
},
|
||||||
|
"settingsSpeedsDes": "Customize the speeds avaliable",
|
||||||
|
"@settingsSpeedsDes": {
|
||||||
|
"description": "Playback speed setting description"
|
||||||
|
},
|
||||||
"settingsSTAuto": "Activation automatique de la minuterie",
|
"settingsSTAuto": "Activation automatique de la minuterie",
|
||||||
"@settingsSTAuto": {},
|
"@settingsSTAuto": {},
|
||||||
"settingsSTAutoDes": "Démarrer la minuterie à l'horaire programmé",
|
"settingsSTAutoDes": "Démarrer la minuterie à l'horaire programmé",
|
||||||
|
|
|
@ -493,6 +493,14 @@
|
||||||
"@settingsRewindSec": {},
|
"@settingsRewindSec": {},
|
||||||
"settingsRewindSecDes": "修改播放器快退时间",
|
"settingsRewindSecDes": "修改播放器快退时间",
|
||||||
"@settingsRewindSecDes": {},
|
"@settingsRewindSecDes": {},
|
||||||
|
"settingsSpeeds": "播放速度",
|
||||||
|
"@settingsSpeeds": {
|
||||||
|
"description": "Playback speeds setting."
|
||||||
|
},
|
||||||
|
"settingsSpeedsDes": "设置播放速度选项",
|
||||||
|
"@settingsSpeedsDes": {
|
||||||
|
"description": "Playback speed setting description"
|
||||||
|
},
|
||||||
"settingsSTAuto": "自动睡眠模式",
|
"settingsSTAuto": "自动睡眠模式",
|
||||||
"@settingsSTAuto": {},
|
"@settingsSTAuto": {},
|
||||||
"settingsSTAutoDes": "定期开启睡眠模式",
|
"settingsSTAutoDes": "定期开启睡眠模式",
|
||||||
|
|
|
@ -44,6 +44,7 @@ const String volumeGainKey = 'volumeGainKey';
|
||||||
const String hideListenedKey = 'hideListenedKey';
|
const String hideListenedKey = 'hideListenedKey';
|
||||||
const String notificationLayoutKey = 'notificationLayoutKey';
|
const String notificationLayoutKey = 'notificationLayoutKey';
|
||||||
const String showNotesFontKey = 'showNotesFontKey';
|
const String showNotesFontKey = 'showNotesFontKey';
|
||||||
|
const String speedListKey = 'speedListKey';
|
||||||
|
|
||||||
class KeyValueStorage {
|
class KeyValueStorage {
|
||||||
final String key;
|
final String key;
|
||||||
|
@ -125,6 +126,24 @@ class KeyValueStorage {
|
||||||
return list.map(int.parse).toList();
|
return list.map(int.parse).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For player speed settings.
|
||||||
|
Future<bool> saveSpeedList(List<double> list) async {
|
||||||
|
var prefs = await SharedPreferences.getInstance();
|
||||||
|
list.sort();
|
||||||
|
return await prefs.setStringList(
|
||||||
|
key, list.map((e) => e.toStringAsFixed(1)).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<double>> getSpeedList() async {
|
||||||
|
var prefs = await SharedPreferences.getInstance();
|
||||||
|
if (prefs.getStringList(key) == null || prefs.getStringList(key).isEmpty) {
|
||||||
|
await prefs.setStringList(
|
||||||
|
key, ['0.5', '0.6', '0.8', '1.0', '1.1', '1.2', '1.5', '2.0']);
|
||||||
|
}
|
||||||
|
var list = prefs.getStringList(key);
|
||||||
|
return list.map(double.parse).toList();
|
||||||
|
}
|
||||||
|
|
||||||
/// Rreverse is used for compatite bool value save before which set true = 0, false = 1
|
/// Rreverse is used for compatite bool value save before which set true = 0, false = 1
|
||||||
Future<bool> getBool(
|
Future<bool> getBool(
|
||||||
{@required bool defaultValue, bool reverse = false}) async {
|
{@required bool defaultValue, bool reverse = false}) async {
|
||||||
|
|
|
@ -14,7 +14,24 @@ import '../util/custom_dropdown.dart';
|
||||||
import '../util/custom_time_picker.dart';
|
import '../util/custom_time_picker.dart';
|
||||||
import '../util/extension_helper.dart';
|
import '../util/extension_helper.dart';
|
||||||
|
|
||||||
const List secondsToSelect = [5, 10, 15, 20, 25, 30, 45, 60];
|
const List kSecondsToSelect = [5, 10, 15, 20, 25, 30, 45, 60];
|
||||||
|
const List<double> kSpeedToSelect = [
|
||||||
|
0.5,
|
||||||
|
0.6,
|
||||||
|
0.8,
|
||||||
|
0.9,
|
||||||
|
1.0,
|
||||||
|
1.1,
|
||||||
|
1.2,
|
||||||
|
1.5,
|
||||||
|
2.0,
|
||||||
|
2.5,
|
||||||
|
3.0,
|
||||||
|
3.5,
|
||||||
|
4.0,
|
||||||
|
4.5,
|
||||||
|
5.0
|
||||||
|
];
|
||||||
|
|
||||||
class PlaySetting extends StatelessWidget {
|
class PlaySetting extends StatelessWidget {
|
||||||
String _volumeEffect(BuildContext context, int i) {
|
String _volumeEffect(BuildContext context, int i) {
|
||||||
|
@ -281,7 +298,7 @@ class PlaySetting extends StatelessWidget {
|
||||||
value: data,
|
value: data,
|
||||||
onChanged: (value) =>
|
onChanged: (value) =>
|
||||||
settings.setFastForwardSeconds = value,
|
settings.setFastForwardSeconds = value,
|
||||||
items: secondsToSelect.map<DropdownMenuItem<int>>((e) {
|
items: kSecondsToSelect.map<DropdownMenuItem<int>>((e) {
|
||||||
return DropdownMenuItem<int>(
|
return DropdownMenuItem<int>(
|
||||||
value: e, child: Text(s.secCount(e)));
|
value: e, child: Text(s.secCount(e)));
|
||||||
}).toList()),
|
}).toList()),
|
||||||
|
@ -302,7 +319,7 @@ class PlaySetting extends StatelessWidget {
|
||||||
isDense: true,
|
isDense: true,
|
||||||
value: data,
|
value: data,
|
||||||
onChanged: (value) => settings.setRewindSeconds = value,
|
onChanged: (value) => settings.setRewindSeconds = value,
|
||||||
items: secondsToSelect.map<DropdownMenuItem<int>>((e) {
|
items: kSecondsToSelect.map<DropdownMenuItem<int>>((e) {
|
||||||
return DropdownMenuItem<int>(
|
return DropdownMenuItem<int>(
|
||||||
value: e, child: Text(s.secCount(e)));
|
value: e, child: Text(s.secCount(e)));
|
||||||
}).toList()),
|
}).toList()),
|
||||||
|
@ -329,6 +346,7 @@ class PlaySetting extends StatelessWidget {
|
||||||
}).toList()),
|
}).toList()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
_SpeedList(),
|
||||||
Divider(height: 1),
|
Divider(height: 1),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(10.0),
|
padding: const EdgeInsets.all(10.0),
|
||||||
|
@ -529,3 +547,71 @@ class __NotificationLayoutState extends State<_NotificationLayout> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _SpeedList extends StatefulWidget {
|
||||||
|
_SpeedList({Key key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
__SpeedListState createState() => __SpeedListState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class __SpeedListState extends State<_SpeedList> {
|
||||||
|
Future<List<double>> _getSpeedList() async {
|
||||||
|
var storage = KeyValueStorage('speedListKey');
|
||||||
|
return await storage.getSpeedList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _saveSpeedList(List<double> list) async {
|
||||||
|
var storage = KeyValueStorage('speedListKey');
|
||||||
|
await storage.saveSpeedList(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final s = context.s;
|
||||||
|
return ListTile(
|
||||||
|
contentPadding:
|
||||||
|
EdgeInsets.only(left: 70.0, right: 20, bottom: 10, top: 10),
|
||||||
|
title: Text(s.settingsSpeeds),
|
||||||
|
subtitle: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(s.settingsSpeedsDes),
|
||||||
|
FutureBuilder<List<double>>(
|
||||||
|
future: _getSpeedList(),
|
||||||
|
initialData: [],
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
var speedSelected = snapshot.data;
|
||||||
|
return Wrap(
|
||||||
|
children: kSpeedToSelect
|
||||||
|
.map((e) => Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: FilterChip(
|
||||||
|
key: ValueKey<String>(e.toString()),
|
||||||
|
label: Text('X ${e.toStringAsFixed(1)}'),
|
||||||
|
selectedColor: context.accentColor,
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
color: snapshot.data.contains(e)
|
||||||
|
? Colors.white
|
||||||
|
: context.textColor),
|
||||||
|
elevation: 0,
|
||||||
|
showCheckmark: false,
|
||||||
|
selected: snapshot.data.contains(e),
|
||||||
|
onSelected: (value) async {
|
||||||
|
if (!value) {
|
||||||
|
speedSelected.remove(e);
|
||||||
|
} else {
|
||||||
|
speedSelected.add(e);
|
||||||
|
}
|
||||||
|
await _saveSpeedList(speedSelected);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.toList());
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -493,6 +493,7 @@ class SettingState extends ChangeNotifier {
|
||||||
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();
|
||||||
|
|
||||||
return SettingsBackup(
|
return SettingsBackup(
|
||||||
theme: theme,
|
theme: theme,
|
||||||
|
@ -522,7 +523,8 @@ class SettingState extends ChangeNotifier {
|
||||||
locale: backupLocale,
|
locale: backupLocale,
|
||||||
hideListened: hideListened,
|
hideListened: hideListened,
|
||||||
notificationLayout: notificationLayout,
|
notificationLayout: notificationLayout,
|
||||||
showNotesFont: showNotesFont);
|
showNotesFont: showNotesFont,
|
||||||
|
speedList: speedList);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> restore(SettingsBackup backup) async {
|
Future<void> restore(SettingsBackup backup) async {
|
||||||
|
@ -557,6 +559,8 @@ class SettingState extends ChangeNotifier {
|
||||||
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);
|
||||||
|
|
||||||
if (backup.locale == '') {
|
if (backup.locale == '') {
|
||||||
await localeStorage.saveStringList([]);
|
await localeStorage.saveStringList([]);
|
||||||
await S.load(Locale(Intl.systemLocale));
|
await S.load(Locale(Intl.systemLocale));
|
||||||
|
|
|
@ -27,6 +27,7 @@ class SettingsBackup {
|
||||||
final bool hideListened;
|
final bool hideListened;
|
||||||
final int notificationLayout;
|
final int notificationLayout;
|
||||||
final int showNotesFont;
|
final int showNotesFont;
|
||||||
|
final List<String> speedList;
|
||||||
SettingsBackup(
|
SettingsBackup(
|
||||||
{this.theme,
|
{this.theme,
|
||||||
this.accentColor,
|
this.accentColor,
|
||||||
|
@ -55,7 +56,8 @@ class SettingsBackup {
|
||||||
this.locale,
|
this.locale,
|
||||||
this.hideListened,
|
this.hideListened,
|
||||||
this.notificationLayout,
|
this.notificationLayout,
|
||||||
this.showNotesFont});
|
this.showNotesFont,
|
||||||
|
this.speedList});
|
||||||
|
|
||||||
Map<String, Object> toJson() {
|
Map<String, Object> toJson() {
|
||||||
return {
|
return {
|
||||||
|
@ -85,12 +87,14 @@ class SettingsBackup {
|
||||||
'locale': locale,
|
'locale': locale,
|
||||||
'hideListened': hideListened,
|
'hideListened': hideListened,
|
||||||
'notificationLayout': notificationLayout,
|
'notificationLayout': notificationLayout,
|
||||||
'showNotesFont': showNotesFont
|
'showNotesFont': showNotesFont,
|
||||||
|
'speedList': speedList
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static SettingsBackup fromJson(Map<String, Object> json) {
|
static SettingsBackup fromJson(Map<String, Object> json) {
|
||||||
var list = List<String>.from(json['episodePopupMenu']);
|
final menuList = List<String>.from(json['episodePopupMenu']);
|
||||||
|
final speedList = List<String>.from(json['speedList']);
|
||||||
return SettingsBackup(
|
return SettingsBackup(
|
||||||
theme: json['theme'] as int,
|
theme: json['theme'] as int,
|
||||||
accentColor: json['accentColor'] as String,
|
accentColor: json['accentColor'] as String,
|
||||||
|
@ -105,7 +109,7 @@ class SettingsBackup {
|
||||||
favLayout: json['favLayout'] as int,
|
favLayout: json['favLayout'] as int,
|
||||||
downloadLayout: json['downloadLayout'] as int,
|
downloadLayout: json['downloadLayout'] as int,
|
||||||
autoDownloadNetwork: json['autoDownloadNetwork'] as bool,
|
autoDownloadNetwork: json['autoDownloadNetwork'] as bool,
|
||||||
episodePopupMenu: list,
|
episodePopupMenu: menuList,
|
||||||
autoDelete: json['autoDelete'] as int,
|
autoDelete: json['autoDelete'] as int,
|
||||||
autoSleepTimer: json['autoSleepTimer'] as bool,
|
autoSleepTimer: json['autoSleepTimer'] as bool,
|
||||||
autoSleepTimerStart: json['autoSleepeTimerStart'] as int,
|
autoSleepTimerStart: json['autoSleepeTimerStart'] as int,
|
||||||
|
@ -118,6 +122,7 @@ class SettingsBackup {
|
||||||
locale: json['locale'] as String,
|
locale: json['locale'] as String,
|
||||||
hideListened: json['hideListened'] as bool,
|
hideListened: json['hideListened'] as bool,
|
||||||
notificationLayout: json['notificationLayout'] as int,
|
notificationLayout: json['notificationLayout'] as int,
|
||||||
showNotesFont: json['showNotesFont'] as int);
|
showNotesFont: json['showNotesFont'] as int,
|
||||||
|
speedList: speedList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue