Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video improvements (#452) #468

Merged
merged 15 commits into from
Jul 7, 2023
6 changes: 3 additions & 3 deletions lib/ui/page/home/page/chat/widget/desktop_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ import 'volume_bar.dart';
/// Desktop video controls for a [Chewie] player.
class DesktopControls extends StatefulWidget {
const DesktopControls({
Key? key,
super.key,
required this.controller,
this.onClose,
this.toggleFullscreen,
this.isFullscreen,
this.showInterfaceFor,
this.size,
}) : super(key: key);
});

/// [MeeduPlayerController] controlling the [MeeduVideoPlayer] functionality.
final MeeduPlayerController controller;
Expand All @@ -61,7 +61,7 @@ class DesktopControls extends StatefulWidget {
/// [Duration] to initially show an user interface for.
final Duration? showInterfaceFor;

/// [Size] of the video this [DesktopControls] used for.
/// [Size] of the video these [DesktopControls] are used for.
final Size? size;

@override
Expand Down
103 changes: 32 additions & 71 deletions lib/ui/page/home/page/chat/widget/mobile_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_meedu_videoplayer/meedu_player.dart';
import 'package:get/get.dart';

import '/l10n/l10n.dart';
import '/themes.dart';
import '/ui/widget/progress_indicator.dart';
import '/util/platform_utils.dart';
import 'rewind_indicator.dart';
import 'video_progress_bar.dart';

/// Mobile video controls for a [Chewie] player.
Expand Down Expand Up @@ -91,7 +91,7 @@ class _MobileControlsState extends State<MobileControls>

@override
Widget build(BuildContext context) {
final (style, fonts) = Theme.of(context).styles;
final style = Theme.of(context).style;

return MouseRegion(
onHover: PlatformUtils.isMobile ? null : (_) => _cancelAndRestartTimer(),
Expand All @@ -113,75 +113,26 @@ class _MobileControlsState extends State<MobileControls>

// Seek backward indicator.
Align(
alignment: Alignment.centerLeft,
child: AnimatedOpacity(
alignment: const Alignment(-0.8, 0),
child: RewindIndicator(
seconds: _seekBackwardDuration.inSeconds,
forward: false,
opacity:
_showSeekBackward && _seekBackwardDuration.inSeconds > 0
? 1
: 0,
duration: 200.milliseconds,
child: Container(
margin: EdgeInsets.only(
left: MediaQuery.of(context).size.width / 12,
),
width: 100,
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(35),
color: Colors.black.withOpacity(0.3),
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.fast_rewind, color: Colors.white),
Text(
'label_count_seconds'.l10nfmt(
{'count': _seekBackwardDuration.inSeconds},
),
style: const TextStyle(color: Colors.white),
),
],
),
),
),
),
),

// Seek forward indicator.
// Seek backward indicator.
krida2000 marked this conversation as resolved.
Show resolved Hide resolved
Align(
alignment: Alignment.centerRight,
child: AnimatedOpacity(
alignment: const Alignment(0.8, 0),
child: RewindIndicator(
seconds: _seekForwardDuration.inSeconds,
forward: true,
opacity: _showSeekForward && _seekForwardDuration.inSeconds > 0
? 1
: 0,
duration: 200.milliseconds,
child: Container(
margin: EdgeInsets.only(
right: MediaQuery.of(context).size.width / 12,
),
width: 100,
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(35),
color: Colors.black.withOpacity(0.3),
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.fast_forward, color: Colors.white),
Text(
'label_count_seconds'.l10nfmt(
{'count': _seekForwardDuration.inSeconds},
),
style:
fonts.bodyMedium?.copyWith(color: Colors.white),
),
],
),
),
),
),
),

Expand Down Expand Up @@ -423,17 +374,17 @@ class _MobileControlsState extends State<MobileControls>
});
}

/// Seeks forward for 5 second.
/// Seeks forward for the [MobileControls.seekDuration].
void _seekForward() {
if (widget.controller.position.value >= widget.controller.duration.value) {
return;
}

_hideSeekBackward(timeout: Duration.zero);
_seekForwardDuration += Duration(
seconds: (widget.controller.duration.value.inSeconds -
widget.controller.position.value.inSeconds)
.clamp(0, MobileControls.seekDuration.inSeconds),
microseconds: (widget.controller.duration.value.inMicroseconds -
widget.controller.position.value.inMicroseconds)
.clamp(0, MobileControls.seekDuration.inMicroseconds),
);
_showSeekForward = true;

Expand All @@ -445,7 +396,9 @@ class _MobileControlsState extends State<MobileControls>
_cancelAndRestartTimer();
}

setState(() {});
if (mounted) {
setState(() {});
}

_hideSeekForward();
}
Expand All @@ -456,7 +409,10 @@ class _MobileControlsState extends State<MobileControls>
_seekForwardTimer = Timer(
timeout,
() async {
setState(() => _showSeekForward = false);
if (mounted) {
setState(() => _showSeekForward = false);
}

await Future.delayed(200.milliseconds);
if (!_showSeekForward) {
_seekForwardDuration = Duration.zero;
Expand All @@ -465,16 +421,16 @@ class _MobileControlsState extends State<MobileControls>
);
}

/// Seeks backward for 5 second.
/// Seeks backward for the [MobileControls.seekDuration].
void _seekBackward() {
if (widget.controller.duration.value == Duration.zero) {
return;
}

_hideSeekForward(timeout: Duration.zero);
_seekBackwardDuration += Duration(
seconds: widget.controller.position.value.inSeconds
.clamp(0, MobileControls.seekDuration.inSeconds),
microseconds: widget.controller.position.value.inMicroseconds
.clamp(0, MobileControls.seekDuration.inMicroseconds),
);
_showSeekBackward = true;

Expand All @@ -486,7 +442,9 @@ class _MobileControlsState extends State<MobileControls>
_cancelAndRestartTimer();
}

setState(() {});
if (mounted) {
setState(() {});
}

_hideSeekBackward();
}
Expand All @@ -497,7 +455,10 @@ class _MobileControlsState extends State<MobileControls>
_seekBackwardTimer = Timer(
timeout,
() async {
setState(() => _showSeekBackward = false);
if (mounted) {
setState(() => _showSeekBackward = false);
}

await Future.delayed(200.milliseconds);
if (!_showSeekBackward) {
_seekBackwardDuration = Duration.zero;
Expand Down
59 changes: 59 additions & 0 deletions lib/ui/page/home/page/chat/widget/rewind_indicator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';

import '/l10n/l10n.dart';
import '/themes.dart';

/// Rounded [Container] indicating the rewinding for the provided [seconds]
/// forward or backward.
class RewindIndicator extends StatelessWidget {
const RewindIndicator({
super.key,
this.seconds = 1,
this.opacity = 1,
this.forward = true,
});

/// Seconds of rewind to display.
final int seconds;

/// Opacity of this [RewindIndicator].
final double opacity;

/// Indicator whether this [RewindIndicator] should display a forward rewind,
/// or backward otherwise.
final bool forward;

@override
Widget build(BuildContext context) {
final (style, fonts) = Theme.of(context).styles;

return AnimatedOpacity(
opacity: opacity,
duration: const Duration(milliseconds: 200),
child: Container(
width: 100,
height: 70,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(35),
color: style.colors.onBackgroundOpacity27,
),
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
forward ? Icons.fast_forward : Icons.fast_rewind,
color: style.colors.onPrimary,
),
Text(
'label_count_seconds'.l10nfmt({'count': seconds}),
style:
fonts.bodyMedium?.copyWith(color: style.colors.onPrimary),
),
],
),
),
),
);
}
}
Loading