Reduce Code Duplication

Extract `CustomMaterialPlayOrPauseButton` class from *mobile.dart* and `CustomMaterialDesktopPlayOrPauseButton` class from *desktop.dart* into *play_or_pause_button.dart* to eliminate code duplication and improve maintainability.
This commit is contained in:
NBA2K1 2025-05-18 01:47:12 +02:00
parent 711e5ea6ae
commit 3709163a49
4 changed files with 81 additions and 139 deletions

View file

@ -15,6 +15,7 @@ import 'package:mangayomi/models/video.dart' as vid;
import 'package:mangayomi/modules/anime/providers/anime_player_controller_provider.dart';
import 'package:mangayomi/modules/anime/widgets/aniskip_countdown_btn.dart';
import 'package:mangayomi/modules/anime/widgets/desktop.dart';
import 'package:mangayomi/modules/anime/widgets/play_or_pause_button.dart';
import 'package:mangayomi/modules/manga/reader/widgets/btn_chapter_list_dialog.dart';
import 'package:mangayomi/modules/anime/widgets/mobile.dart';
import 'package:mangayomi/modules/anime/widgets/subtitle_view.dart';
@ -870,8 +871,9 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
},
icon: const Icon(Icons.skip_previous, color: Colors.white),
),
CustomeMaterialDesktopPlayOrPauseButton(
CustomPlayOrPauseButton(
controller: _controller,
isDesktop: _isDesktop,
),
if (hasNextEpisode)
IconButton(

View file

@ -500,75 +500,6 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
}
}
// BUTTON: PLAY/PAUSE
/// A material design play/pause button.
class CustomeMaterialDesktopPlayOrPauseButton extends StatefulWidget {
final VideoController controller;
const CustomeMaterialDesktopPlayOrPauseButton({
super.key,
required this.controller,
});
@override
CustomeMaterialDesktopPlayOrPauseButtonState createState() =>
CustomeMaterialDesktopPlayOrPauseButtonState();
}
class CustomeMaterialDesktopPlayOrPauseButtonState
extends State<CustomeMaterialDesktopPlayOrPauseButton>
with SingleTickerProviderStateMixin {
late final animation = AnimationController(
vsync: this,
value: widget.controller.player.state.playing ? 1 : 0,
duration: const Duration(milliseconds: 200),
);
StreamSubscription<bool>? subscription;
@override
void setState(VoidCallback fn) {
if (mounted) {
super.setState(fn);
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
subscription ??= widget.controller.player.stream.playing.listen((event) {
if (event) {
animation.forward();
} else {
animation.reverse();
}
});
}
@override
void dispose() {
animation.dispose();
subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: widget.controller.player.playOrPause,
iconSize: 25,
color: Colors.white,
icon: AnimatedIcon(
progress: animation,
icon: AnimatedIcons.play_pause,
size: 25,
color: Colors.white,
),
);
}
}
// BUTTON: VOLUME
/// MaterialDesktop design volume button & slider.

View file

@ -10,6 +10,7 @@ import 'package:mangayomi/modules/anime/widgets/indicator_builder.dart';
import 'package:mangayomi/modules/anime/widgets/subtitle_view.dart';
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
import 'package:mangayomi/modules/more/settings/player/providers/player_state_provider.dart';
import 'package:mangayomi/modules/anime/widgets/play_or_pause_button.dart';
import 'package:volume_controller/volume_controller.dart';
import 'package:screen_brightness/screen_brightness.dart';
import 'package:flutter/material.dart';
@ -884,74 +885,6 @@ class _ForwardSeekIndicatorState extends State<_ForwardSeekIndicator> {
}
}
// BUTTON: PLAY/PAUSE
/// A material design play/pause button.
class CustomMaterialPlayOrPauseButton extends StatefulWidget {
final VideoController controller;
const CustomMaterialPlayOrPauseButton({super.key, required this.controller});
@override
CustomMaterialPlayOrPauseButtonState createState() =>
CustomMaterialPlayOrPauseButtonState();
}
class CustomMaterialPlayOrPauseButtonState
extends State<CustomMaterialPlayOrPauseButton>
with SingleTickerProviderStateMixin {
late final animation = AnimationController(
vsync: this,
value: widget.controller.player.state.playing ? 1 : 0,
duration: const Duration(milliseconds: 200),
);
StreamSubscription<bool>? subscription;
@override
void setState(VoidCallback fn) {
if (mounted) {
super.setState(fn);
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
subscription ??= widget.controller.player.stream.playing.listen((event) {
if (event) {
animation.forward();
} else {
animation.reverse();
}
});
}
@override
void dispose() {
animation.dispose();
subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: widget.controller.player.playOrPause,
iconSize: 65,
color: Colors.white,
icon: IgnorePointer(
child: AnimatedIcon(
progress: animation,
icon: AnimatedIcons.play_pause,
size: 65,
color: Colors.white,
),
),
);
}
}
List<Widget> mobilePrimaryButtonBar(
BuildContext context,
GlobalKey<VideoState> key,
@ -985,7 +918,7 @@ List<Widget> mobilePrimaryButtonBar(
),
),
const Spacer(),
CustomMaterialPlayOrPauseButton(controller: controller),
CustomPlayOrPauseButton(controller: controller, isDesktop: false),
const Spacer(),
IconButton(
onPressed:

View file

@ -0,0 +1,76 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:media_kit_video/media_kit_video.dart';
// BUTTON: PLAY/PAUSE
/// A material design play/pause button.
class CustomPlayOrPauseButton extends StatefulWidget {
final VideoController controller;
final bool isDesktop;
const CustomPlayOrPauseButton({
super.key,
required this.controller,
required this.isDesktop,
});
@override
CustomPlayOrPauseButtonState createState() => CustomPlayOrPauseButtonState();
}
class CustomPlayOrPauseButtonState extends State<CustomPlayOrPauseButton>
with SingleTickerProviderStateMixin {
late final animation = AnimationController(
vsync: this,
value: widget.controller.player.state.playing ? 1 : 0,
duration: const Duration(milliseconds: 200),
);
StreamSubscription<bool>? subscription;
double get iconSize => widget.isDesktop ? 25 : 65;
@override
void setState(VoidCallback fn) {
if (mounted) {
super.setState(fn);
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
subscription ??= widget.controller.player.stream.playing.listen((event) {
if (event) {
animation.forward();
} else {
animation.reverse();
}
});
}
@override
void dispose() {
animation.dispose();
subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: widget.controller.player.playOrPause,
iconSize: iconSize,
color: Colors.white,
icon: IgnorePointer(
child: AnimatedIcon(
progress: animation,
icon: AnimatedIcons.play_pause,
size: iconSize,
color: Colors.white,
),
),
);
}
}