Customize the speeds available.

This commit is contained in:
stonegate 2020-09-10 18:01:28 +08:00
parent 8aad960ed8
commit d1668a923f
14 changed files with 261 additions and 84 deletions

View File

@ -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"),

View File

@ -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"),

View File

@ -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"),

View File

@ -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("在后台更新播客"),

View File

@ -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(

View File

@ -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()),
),
], ],
), ),
), ),

View File

@ -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",

View File

@ -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",

View File

@ -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é",

View File

@ -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": "定期开启睡眠模式",

View File

@ -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 {

View File

@ -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());
}),
],
),
);
}
}

View File

@ -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));

View File

@ -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);
} }
} }