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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ All user visible changes to this project will be documented in this file. This p
- Web:
- Unread chats badge on favicon. ([#403])
- Desktop:
- Video support. ([#445], [#438])
- Video support. ([#468], [#445], [#438])
- Mobile:
- Video rewinding indication. ([#468], [#452])

### Changed

Expand Down Expand Up @@ -101,12 +103,14 @@ All user visible changes to this project will be documented in this file. This p
[#440]: /../../pull/440
[#443]: /../../pull/443
[#445]: /../../pull/445
[#452]: /../../issues/452
[#453]: /../../pull/453
[#454]: /../../pull/454
[#456]: /../../pull/456
[#462]: /../../pull/462
[#463]: /../../pull/463
[#467]: /../../pull/467
[#468]: /../../pull/468



Expand Down
4 changes: 4 additions & 0 deletions assets/l10n/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,10 @@ label_contact_information = Contact information
label_contacts = Contacts
label_copied = Copied
label_copy = Copy
label_count_seconds = {$count} { $count ->
[1] second
*[other] seconds
}
label_create_group = Group creation
label_create_group_selected = Selected
label_create_group_users = user(s)
Expand Down
5 changes: 5 additions & 0 deletions assets/l10n/ru-RU.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,11 @@ label_contact_information = Контактная информация
label_contacts = Контакты
label_copied = Скопировано
label_copy = Копировать
label_count_seconds = {$count} { $count ->
[one] секунда
[few] секунды
*[other] секунд
}
label_create_group = Создание группы
label_create_group_selected = Выбрано
label_create_group_users = пользователь(ей)
Expand Down
61 changes: 32 additions & 29 deletions lib/ui/page/call/widget/round_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,38 +107,41 @@ class _RoundFloatingButtonState extends State<RoundFloatingButton> {
Widget build(BuildContext context) {
final (style, fonts) = Theme.of(context).styles;

Widget button = ConditionalBackdropFilter(
condition: !WebUtils.isSafari && widget.withBlur,
borderRadius: BorderRadius.circular(60),
child: Material(
key: _key,
elevation: 0,
color: widget.color,
type: MaterialType.circle,
child: InkWell(
borderRadius: BorderRadius.circular(60),
onHover: widget.hint != null
? (b) {
if (b) {
_populateOverlay();
} else {
_hintEntry?.remove();
_hintEntry = null;
Widget button = Container(
color: style.colors.transparent,
child: ConditionalBackdropFilter(
krida2000 marked this conversation as resolved.
Show resolved Hide resolved
condition: !WebUtils.isSafari && widget.withBlur,
borderRadius: BorderRadius.circular(60),
child: Material(
key: _key,
elevation: 0,
color: widget.color,
type: MaterialType.circle,
child: InkWell(
borderRadius: BorderRadius.circular(60),
onHover: widget.hint != null
? (b) {
if (b) {
_populateOverlay();
} else {
_hintEntry?.remove();
_hintEntry = null;
}
}
}
: null,
onTap: widget.onPressed,
child: widget.child ??
SizedBox(
width: max(widget.assetWidth, 60),
height: max(widget.assetWidth, 60),
child: Center(
child: SvgImage.asset(
'assets/icons/${widget.asset}.svg',
width: widget.assetWidth,
: null,
onTap: widget.onPressed,
child: widget.child ??
SizedBox(
width: max(widget.assetWidth, 60),
height: max(widget.assetWidth, 60),
child: Center(
child: SvgImage.asset(
'assets/icons/${widget.asset}.svg',
width: widget.assetWidth,
),
),
),
),
),
),
),
);
Expand Down
1 change: 1 addition & 0 deletions lib/ui/page/home/page/chat/message_field/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ class MessageFieldView extends StatelessWidget {
color: style.colors.onPrimaryOpacity50,
child: AnimatedSize(
duration: 400.milliseconds,
alignment: Alignment.bottomCenter,
curve: Curves.ease,
child: Container(
width: double.infinity,
Expand Down
152 changes: 91 additions & 61 deletions lib/ui/page/home/page/chat/widget/desktop_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import 'dart:ui';
import 'package:chewie/chewie.dart';
import 'package:chewie/src/animated_play_pause.dart';
import 'package:chewie/src/helpers/utils.dart';
import 'package:chewie/src/progress_bar.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_meedu_videoplayer/meedu_player.dart';
Expand All @@ -38,13 +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,
}) : super(key: key);
this.size,
});

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

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

@override
State<StatefulWidget> createState() => _DesktopControlsState();
}
Expand Down Expand Up @@ -95,16 +98,16 @@ class _DesktopControlsState extends State<DesktopControls>
/// [Timer] for toggling the [_showInterface] after a timeout.
Timer? _interfaceTimer;

/// [Timer] for hiding user interface on [_initialize].
Timer? _initTimer;
/// [Timer] for toggling the [_showBottomBar] after a timeout.
Timer? _bottomBarTimer;

/// [Timer] for showing user interface for a while after fullscreen toggle.
Timer? _showAfterExpandCollapseTimer;

/// [StreamSubscription] to the [MeeduPlayerController.playerStatus] changes.
StreamSubscription? _statusSubscription;

/// Indicator whether the video progress bar is being dragged.
/// Indicator whether the video or volume progress bar is being dragged.
bool _dragging = false;

@override
Expand All @@ -127,7 +130,8 @@ class _DesktopControlsState extends State<DesktopControls>
void dispose() {
_statusSubscription?.cancel();
_hideTimer?.cancel();
_initTimer?.cancel();
_interfaceTimer?.cancel();
_bottomBarTimer?.cancel();
_showAfterExpandCollapseTimer?.cancel();
_volumeEntry?.remove();
super.dispose();
Expand All @@ -147,29 +151,33 @@ class _DesktopControlsState extends State<DesktopControls>
behavior: HitTestBehavior.deferToChild,
onTap: widget.onClose,
child: Center(
child: Listener(
behavior: HitTestBehavior.translucent,
onPointerDown: (e) {
if (e.buttons & kPrimaryButton != 0 &&
_volumeEntry == null) {
_playPause();
}
},
// Double tap inside [AspectRatio] toggles fullscreen.
child: GestureDetector(
child: SizedBox.fromSize(
size: widget.size,
child: Listener(
behavior: HitTestBehavior.translucent,
onTap: () {},
onDoubleTap: _onExpandCollapse,
// Required for the [GestureDetector]s to take the full
// width and height.
child: const SizedBox(
width: double.infinity,
height: double.infinity,
onPointerDown: (e) {
if (e.buttons & kPrimaryButton != 0 &&
_volumeEntry == null) {
_playPause();
}
},
// Double tap inside [AspectRatio] toggles fullscreen.
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {},
onDoubleTap: _onExpandCollapse,
// Required for the [GestureDetector]s to take the full
// width and height.
child: const SizedBox(
width: double.infinity,
height: double.infinity,
),
),
),
),
),
),
// Play/pause button.
RxBuilder((_) {
return widget.controller.isBuffering.value
? const Center(child: CustomProgressIndicator())
Expand All @@ -191,8 +199,10 @@ class _DesktopControlsState extends State<DesktopControls>
onExit: (d) {
if (mounted) {
setState(() => _showBottomBar = false);
_volumeEntry?.remove();
_volumeEntry = null;
if (!_dragging) {
_volumeEntry?.remove();
_volumeEntry = null;
}
}
},
child: SizedBox(
Expand All @@ -213,7 +223,7 @@ class _DesktopControlsState extends State<DesktopControls>

return AnimatedSlider(
duration: const Duration(milliseconds: 300),
isOpen: _showBottomBar || _showInterface,
isOpen: _showBottomBar || _showInterface || _dragging,
translate: false,
child: Padding(
padding: const EdgeInsets.only(bottom: 8, left: 32, right: 32),
Expand Down Expand Up @@ -256,17 +266,20 @@ class _DesktopControlsState extends State<DesktopControls>
final style = Theme.of(context).style;

return Obx(
() => GestureDetector(
onTap: _onExpandCollapse,
child: SizedBox(
height: _barHeight,
child: Center(
child: Icon(
widget.isFullscreen?.value == true
? Icons.fullscreen_exit
: Icons.fullscreen,
color: style.colors.onPrimary,
size: 21,
() => MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: _onExpandCollapse,
child: SizedBox(
height: _barHeight,
child: Center(
child: Icon(
widget.isFullscreen?.value == true
? Icons.fullscreen_exit
: Icons.fullscreen,
color: style.colors.onPrimary,
size: 21,
),
),
),
),
Expand Down Expand Up @@ -321,18 +334,21 @@ class _DesktopControlsState extends State<DesktopControls>

return Transform.translate(
offset: const Offset(0, 0),
child: GestureDetector(
onTap: _playPause,
child: Container(
height: _barHeight,
color: style.colors.transparent,
child: RxBuilder((_) {
return AnimatedPlayPause(
size: 21,
playing: controller.playerStatus.playing,
color: style.colors.onPrimary,
);
}),
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: _playPause,
child: Container(
height: _barHeight,
color: style.colors.transparent,
child: RxBuilder((_) {
return AnimatedPlayPause(
size: 21,
playing: controller.playerStatus.playing,
color: style.colors.onPrimary,
);
}),
),
),
),
);
Expand All @@ -343,6 +359,7 @@ class _DesktopControlsState extends State<DesktopControls>
final style = Theme.of(context).style;

return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (_) {
if (mounted && _volumeEntry == null) {
Offset offset = Offset.zero;
Expand Down Expand Up @@ -398,7 +415,7 @@ class _DesktopControlsState extends State<DesktopControls>
child: MouseRegion(
opaque: false,
onExit: (d) {
if (mounted) {
if (mounted && !_dragging) {
_volumeEntry?.remove();
_volumeEntry = null;
setState(() {});
Expand Down Expand Up @@ -427,15 +444,28 @@ class _DesktopControlsState extends State<DesktopControls>
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
child: VideoVolumeBar(
widget.controller,
colors: ChewieProgressColors(
playedColor: style.colors.primary,
handleColor: style.colors.primary,
bufferedColor:
style.colors.background.withOpacity(0.5),
backgroundColor:
style.colors.secondary.withOpacity(0.5),
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: VideoVolumeBar(
widget.controller,
onDragStart: () {
setState(() => _dragging = true);
},
onDragEnd: () {
if (!_showBottomBar) {
_volumeEntry?.remove();
_volumeEntry = null;
}
setState(() => _dragging = false);
},
colors: ChewieProgressColors(
playedColor: style.colors.primary,
handleColor: style.colors.primary,
bufferedColor:
style.colors.background.withOpacity(0.5),
backgroundColor:
style.colors.secondary.withOpacity(0.5),
),
),
),
),
Expand Down Expand Up @@ -468,7 +498,7 @@ class _DesktopControlsState extends State<DesktopControls>
});
}

/// Returns the [VideoProgressBar] of the current video progression.
/// Returns the [ProgressBar] of the current video progression.
Widget _buildProgressBar() {
final style = Theme.of(context).style;

Expand Down
Loading