Skip to content

Commit

Permalink
Merge pull request #14 from AppFlowy-IO/feat/callbacks
Browse files Browse the repository at this point in the history
feat: add callbacks for mobile
  • Loading branch information
Xazin committed May 30, 2024
2 parents 8c6f98d + 1a24a98 commit de4d47f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 28 deletions.
6 changes: 6 additions & 0 deletions packages/appflowy_editor_plugins/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.0.6

- Improve Video Block component
- Add callback options to Video Block component for enhanced mobile support
- Add preventClose to Video Block to persist menu

## 0.0.5

- Fix a possibly critical bug with the editorState logic in the Code Block component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class ResizableVidePlayer extends StatefulWidget {
required this.width,
required this.alignment,
required this.controller,
this.onLongPress,
this.onDoubleTap,
});

final String src;
Expand All @@ -25,6 +27,8 @@ class ResizableVidePlayer extends StatefulWidget {
final double width;
final Alignment alignment;
final VideoController controller;
final VoidCallback? onLongPress;
final VoidCallback? onDoubleTap;

@override
State<ResizableVidePlayer> createState() => _ResizableVidePlayerState();
Expand Down Expand Up @@ -61,12 +65,16 @@ class _ResizableVidePlayerState extends State<ResizableVidePlayer> {
onExit: (_) => setState(() => onFocus = false),
child: Stack(
children: [
Video(
controls: (state) => AdaptiveVideoControls(state),
controller: widget.controller,
width: 1080,
height: 720,
wakelock: false,
GestureDetector(
onLongPress: widget.onLongPress,
onDoubleTap: widget.onDoubleTap,
child: Video(
controls: (state) => AdaptiveVideoControls(state),
controller: widget.controller,
width: 1080,
height: 720,
wakelock: false,
),
),
_buildEdgeGesture(
context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import 'package:media_kit_video/media_kit_video.dart';
import 'package:provider/provider.dart';
import 'package:string_validator/string_validator.dart';

typedef VoidVideoCallback = void Function(BuildContext, Node, EditorState);

class VideoBlockKit {
static void ensureInitialized() => MediaKit.ensureInitialized();
}
Expand Down Expand Up @@ -75,6 +77,8 @@ class VideoBlockComponentBuilder extends BlockComponentBuilder {
this.menuBuilder,
this.placeholderBuilder,
this.errorBuilder,
this.onLongPress,
this.onDoubleTap,
});

/// Whether to show the menu of this block component.
Expand All @@ -94,6 +98,20 @@ class VideoBlockComponentBuilder extends BlockComponentBuilder {
///
final VideoBlockWidgetBuilder? errorBuilder;

/// A callback that once the video player is long pressed, will be invoked.
///
/// This is especially useful for Mobile, where the context menu is not as easily
/// available as on Desktop.
///
final VoidVideoCallback? onLongPress;

/// A callback that once the video player is double tapped, will be invoked.
///
/// This is especially useful for Mobile, where the context menu is not as easily
/// available as on Desktop.
///
final VoidVideoCallback? onDoubleTap;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
final node = blockComponentContext.node;
Expand All @@ -107,6 +125,8 @@ class VideoBlockComponentBuilder extends BlockComponentBuilder {
menuBuilder: menuBuilder,
placeholderBuilder: placeholderBuilder,
errorBuilder: errorBuilder,
onLongPress: onLongPress,
onDoubleTap: onDoubleTap,
);
}

Expand All @@ -125,6 +145,8 @@ class VideoBlockComponent extends BlockComponentStatefulWidget {
this.menuBuilder,
this.placeholderBuilder,
this.errorBuilder,
this.onLongPress,
this.onDoubleTap,
});

/// Whether to show the menu of this block component.
Expand All @@ -144,6 +166,20 @@ class VideoBlockComponent extends BlockComponentStatefulWidget {
///
final VideoBlockWidgetBuilder? errorBuilder;

/// A callback that once the video player is long pressed, will be invoked.
///
/// This is especially useful for Mobile, where the context menu is not as easily
/// available as on Desktop.
///
final VoidVideoCallback? onLongPress;

/// A callback that once the video player is double tapped, will be invoked.
///
/// This is especially useful for Mobile, where the context menu is not as easily
/// available as on Desktop.
///
final VoidVideoCallback? onDoubleTap;

@override
State<VideoBlockComponent> createState() => VideoBlockComponentState();
}
Expand All @@ -163,43 +199,39 @@ class VideoBlockComponentState extends State<VideoBlockComponent>

final showActionsNotifier = ValueNotifier<bool>(false);

bool alwaysShowMenu = false;
late final bool _alwaysShowMenu;

bool preventClose = false;

late final player = Player();
late final controller = VideoController(player);

@override
void initState() {
super.initState();
_alwaysShowMenu = PlatformExtension.isMobile;

final src = node.attributes[VideoBlockKeys.url];
if (src == null || src.isEmpty || !_checkIfURLIsValid(src)) {
return;
}

player
..open(Media(src))
..pause();

if (PlatformExtension.isMobile) {
alwaysShowMenu = true;
}
player.open(Media(src), play: false);
}

@override
void didUpdateWidget(covariant VideoBlockComponent oldWidget) {
super.didUpdateWidget(oldWidget);
final src = node.attributes[VideoBlockKeys.url];

final src = node.attributes[VideoBlockKeys.url];
if (src == null || src.isEmpty || !_checkIfURLIsValid(src)) {
return;
}

if (player.state.playlist.medias.isEmpty ||
player.state.playlist.medias.first.uri != src) {
WidgetsBinding.instance.addPostFrameCallback((_) {
player
..open(Media(src))
..pause();
player.open(Media(src), play: false);
});
}
}
Expand Down Expand Up @@ -238,6 +270,8 @@ class VideoBlockComponentState extends State<VideoBlockComponent>
width: width,
alignment: alignment,
controller: controller,
onLongPress: () => widget.onLongPress?.call(context, node, editorState),
onDoubleTap: () => widget.onDoubleTap?.call(context, node, editorState),
onResize: (width) {
final transaction = editorState.transaction
..updateNode(node, {VideoBlockKeys.width: width});
Expand All @@ -255,21 +289,17 @@ class VideoBlockComponentState extends State<VideoBlockComponent>
}

if (widget.showMenu && widget.menuBuilder != null) {
if (alwaysShowMenu) {
if (_alwaysShowMenu || preventClose) {
child = Stack(
children: [
child,
if (src.isNotEmpty == true) widget.menuBuilder!(node, this),
if (src?.isNotEmpty == true) widget.menuBuilder!(node, this),
],
);
} else {
child = MouseRegion(
onEnter: (_) => showActionsNotifier.value = true,
onExit: (_) {
if (!alwaysShowMenu) {
showActionsNotifier.value = false;
}
},
onExit: (_) => showActionsNotifier.value = false,
hitTestBehavior: HitTestBehavior.opaque,
opaque: false,
child: ValueListenableBuilder<bool>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,14 @@ class _AlignButtonState extends State<_AlignButton> {
}

void preventMenuClose() {
widget.state.alwaysShowMenu = true;
widget.state.preventClose = true;
editorState.service.selectionService.registerGestureInterceptor(
gestureInterceptor,
);
}

void allowMenuClose() {
widget.state.alwaysShowMenu = false;
widget.state.preventClose = false;
editorState.service.selectionService.unregisterGestureInterceptor(
interceptorKey,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/appflowy_editor_plugins/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: appflowy_editor_plugins
description: "A collection of plugins and custom block components for the AppFlowy Editor."
version: 0.0.5
version: 0.0.6
homepage: https://github.com/AppFlowy-IO/appflowy-plugins

topics:
Expand Down

0 comments on commit de4d47f

Please sign in to comment.