Skip to content

Commit

Permalink
feat: custom speeds
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Apr 3, 2024
1 parent 654f06a commit 0efb32e
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 4 deletions.
8 changes: 6 additions & 2 deletions lib/base/settings_file_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ mixin SettingsFileWriter {

Future<void> _writeToStorageRaw() async {
final path = filePath;
await File(path).writeAsJson(jsonToWrite);
printy("Setting File Write: ${path.getFilenameWOExt}");
try {
await File(path).writeAsJson(jsonToWrite);
printy("Setting file write: $path");
} catch (e) {
printy("Setting file write failed: ${path.getFilenameWOExt} => $e", isError: true);
}
}

Timer? _writeTimer;
Expand Down
8 changes: 8 additions & 0 deletions lib/controller/settings.player.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: invalid_use_of_protected_member

import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart';

Expand All @@ -18,6 +20,8 @@ class PlayerSettings with SettingsFileWriter {
final speed = 1.0.obs;
final pitch = 1.0.obs;

var speeds = <double>[0.25, 0.5, 0.75, 0.9, 1.0, 1.1, 1.25, 1.5, 1.75, 2.0];

final seekDurationInSeconds = 5.obs;
final seekDurationInPercentage = 2.obs;
final isSeekDurationPercentage = false.obs;
Expand Down Expand Up @@ -59,6 +63,7 @@ class PlayerSettings with SettingsFileWriter {
double? volume,
double? speed,
double? pitch,
List<double>? speeds,
int? seekDurationInSeconds,
int? seekDurationInPercentage,
bool? isSeekDurationPercentage,
Expand Down Expand Up @@ -88,6 +93,7 @@ class PlayerSettings with SettingsFileWriter {
if (volume != null) this.volume.value = volume;
if (speed != null) this.speed.value = speed;
if (pitch != null) this.pitch.value = pitch;
if (speeds != null) this.speeds = speeds;
if (seekDurationInSeconds != null) this.seekDurationInSeconds.value = seekDurationInSeconds;
if (seekDurationInPercentage != null) this.seekDurationInPercentage.value = seekDurationInPercentage;
if (isSeekDurationPercentage != null) this.isSeekDurationPercentage.value = isSeekDurationPercentage;
Expand Down Expand Up @@ -130,6 +136,7 @@ class PlayerSettings with SettingsFileWriter {
volume.value = json['volume'] ?? volume.value;
speed.value = json['speed'] ?? speed.value;
pitch.value = json['pitch'] ?? pitch.value;
speeds = (json['speeds'] as List?)?.cast<double>() ?? speeds;
seekDurationInSeconds.value = json['seekDurationInSeconds'] ?? seekDurationInSeconds.value;
seekDurationInPercentage.value = json['seekDurationInPercentage'] ?? seekDurationInPercentage.value;
isSeekDurationPercentage.value = json['isSeekDurationPercentage'] ?? isSeekDurationPercentage.value;
Expand Down Expand Up @@ -177,6 +184,7 @@ class PlayerSettings with SettingsFileWriter {
'volume': volume.value,
'speed': speed.value,
'pitch': pitch.value,
'speeds': speeds,
'seekDurationInSeconds': seekDurationInSeconds.value,
'seekDurationInPercentage': seekDurationInPercentage.value,
'isSeekDurationPercentage': isSeekDurationPercentage.value,
Expand Down
137 changes: 135 additions & 2 deletions lib/ui/widgets/video_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
import 'package:get/get.dart';
import 'package:namida/youtube/yt_utils.dart';
import 'package:newpipeextractor_dart/newpipeextractor_dart.dart';

import 'package:namida/class/track.dart';
Expand All @@ -22,11 +21,13 @@ import 'package:namida/core/icon_fonts/broken_icons.dart';
import 'package:namida/core/namida_converter_ext.dart';
import 'package:namida/core/translations/language.dart';
import 'package:namida/packages/three_arched_circle.dart';
import 'package:namida/ui/dialogs/edit_tags_dialog.dart';
import 'package:namida/ui/widgets/artwork.dart';
import 'package:namida/ui/widgets/custom_widgets.dart';
import 'package:namida/youtube/controller/youtube_controller.dart';
import 'package:namida/youtube/seek_ready_widget.dart';
import 'package:namida/youtube/widgets/yt_thumbnail.dart';
import 'package:namida/youtube/yt_utils.dart';

class NamidaVideoControls extends StatefulWidget {
final bool showControls;
Expand Down Expand Up @@ -774,7 +775,7 @@ class NamidaVideoControlsState extends State<NamidaVideoControls> with TickerPro
setControlsVisibily(true);
},
children: () => [
...[0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0].map((speed) {
...settings.player.speeds.map((speed) {
return Obx(
() {
final isSelected = Player.inst.currentSpeed == speed;
Expand Down Expand Up @@ -806,6 +807,28 @@ class NamidaVideoControlsState extends State<NamidaVideoControls> with TickerPro
},
);
}).toList(),
NamidaInkWell(
onTap: () {
_startTimer();
Navigator.of(context).pop();
NamidaNavigator.inst.navigateDialog(dialog: const _SpeedsEditorDialog());
},
decoration: const BoxDecoration(),
borderRadius: 6.0,
bgColor: null,
margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
const Icon(Broken.add_circle, size: 20.0),
const SizedBox(width: 12.0),
Text(
lang.ADD,
style: context.textTheme.displayMedium?.copyWith(fontSize: 13.0.multipliedFontScale),
),
],
),
),
],
child: Padding(
padding: const EdgeInsets.all(4.0),
Expand Down Expand Up @@ -1536,3 +1559,113 @@ class NamidaVideoControlsState extends State<NamidaVideoControls> with TickerPro
);
}
}

class _SpeedsEditorDialog extends StatefulWidget {
const _SpeedsEditorDialog();

@override
State<_SpeedsEditorDialog> createState() => __SpeedsEditorDialogState();
}

class __SpeedsEditorDialogState extends State<_SpeedsEditorDialog> {
final speedsController = TextEditingController();
final formKey = GlobalKey<FormState>();

@override
void dispose() {
speedsController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Form(
key: formKey,
child: CustomBlurryDialog(
title: lang.CONFIGURE,
actions: [
TextButton(
onPressed: NamidaNavigator.inst.closeDialog,
child: Text(lang.DONE),
),
NamidaButton(
text: lang.ADD,
onPressed: () {
formKey.currentState?.validate();
},
),
],
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Wrap(
children: settings.player.speeds
.map(
(e) => IgnorePointer(
ignoring: e == 1.0,
child: Opacity(
opacity: e == 1.0 ? 0.5 : 1.0,
child: Container(
margin: const EdgeInsets.all(4.0),
padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 10.0),
decoration: BoxDecoration(
color: context.theme.cardTheme.color,
borderRadius: BorderRadius.circular(16.0.multipliedRadius),
),
child: InkWell(
onTap: () {
if (e == 1.0) return snackyy(message: lang.ERROR);
if (settings.player.speeds.length <= 4) return showMinimumItemsSnack(4);

settings.player.speeds
..remove(e)
..sort();
settings.player.save(speeds: settings.player.speeds);
setState(() {});
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(e.toString()),
const SizedBox(width: 6.0),
const Icon(
Broken.close_circle,
size: 18.0,
)
],
),
),
),
),
),
)
.toList(),
),
Padding(
padding: const EdgeInsets.only(top: 14.0),
child: CustomTagTextField(
controller: speedsController,
hintText: lang.VALUE,
labelText: lang.SPEED,
isNumeric: true,
validator: (value) {
value ??= '';
if (value.isEmpty) return lang.EMPTY_VALUE;
final sp = double.parse(speedsController.text);
if (settings.player.speeds.contains(sp)) return lang.ERROR;
settings.player.speeds
..add(sp)
..sort();
settings.player.save(speeds: settings.player.speeds);
speedsController.clear();
setState(() {});
return null;
},
),
)
],
),
),
);
}
}

0 comments on commit 0efb32e

Please sign in to comment.