I have a video editor written in ReactJS. I want to add the capability to have silent blocks for audio track.
All blocks are added with drag/drop thanks to react-beautiful-dnd. Silent blocks (and only these ones) can be resized, thanks to react-resizable.
My problem : Dragging takes over resizing, as when I grab the arrow to resize, the block is dragged and resizing unavailable.
I tried to link resizing and dragging with a local state -> if the user is resizing, disable the dragging capabilites, if not, activate it :
<Draggable
key={audio.id}
draggableId={audio.id}
index={i}
isDragDisabled={resizing}
>
And this is the code changing the state value :
<ResizableBox
width={50}
height={35}
resizeHandles={["e"]}
onResizeStart={() => {
console.log("-----début de resizing !-----");
setResizing(true);
}}
onResizeStop={() => {
setResizing(false);
audio.duration = draggableWidth / (FRAM_RATE * SCALE);
console.log("-----fin de resizing !-----");
}}
>
My bet is on the value received by Draggable : I think it receives the value of resizing just before it has changed, and so the dragging takes over. I tried with a ref, and with the prevState, but it works the same.
When I send true, the resizing works perfectly, but, obviously, dragging is disabled even when I'm not resizing.
Thank you for your help.
here you can find the complete code of my component :
import React, { useState } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import { useDispatch, useSelector } from "react-redux";
import { moveAudioFromtimeline } from "../../../../../Redux/actions/VideoEditorAction";
import { reorder } from "../../function";
import { SceneItemAudio } from "./Layer.styled";
import AudioThumbnail from "./AudioThumbnail";
import SilenceItem from "../../../../../components/Silence/SilenceItem";
import { ResizableBox } from "react-resizable";
import "./resizable.css";
const DragAndDropAudio = () => {
const scenesVideoSelector = useSelector((state) => state.VideoEditorReducer);
const dispatch = useDispatch();
// const [currentElement, setCurrentElement] = useState({
// id: "",
// width: 0,
// mousePos: 0,
// });
const [resizing, setResizing] = useState(false);
const [draggableWidth, setDraggableWidth] = useState(0);
const SCALE = scenesVideoSelector.scale;
const FRAM_RATE = scenesVideoSelector.frame_rate;
const updateCurrentVideo = (e) => {
try {
const target = e.target;
let lastSelected = target.ownerDocument.querySelector(
".activeContentScene"
);
if (lastSelected) {
lastSelected.classList.remove("activeContentScene");
}
target.classList.add("activeContentScene");
const id = target.dataset.sceneId;
let current = scenesVideoSelector.audios.find((audio) => audio.id == id);
let data = {
currentScene: current,
isPlaying: false,
};
dispatch(updateCurrentVideo(data));
} catch (error) {
console.log(error);
}
};
//DragNDropContext
const getItemStyle = (isDragging, draggableStyle) => ({
// change background colour if dragging
background: isDragging ? "lightgreen" : "transparent",
// styles we need to apply on draggables
...draggableStyle,
});
const getListStyle = (isDraggingOver) => ({
background: isDraggingOver ? "lightblue" : "transparent",
display: "flex",
overflowY: "hidden",
minWidth: "330px",
});
const onDragEnd = (result) => {
// dropped outside the list
if (!result.destination) {
return;
}
let updateScenesAudio = scenesVideoSelector.audios;
let indexSource = result.source.index;
let indexDestination = result.destination.index;
const items = reorder(updateScenesAudio, indexSource, indexDestination);
dispatch(
moveAudioFromtimeline({
audios: items,
currentScene: updateScenesAudio[indexDestination],
})
);
};
console.log("audios", scenesVideoSelector.audios);
console.log("resizing", resizing);
return (
<DragDropContext onDragEnd={onDragEnd}>
<Droppable
key={"286aasery"}
droppableId={"audioDragZone"}
direction="horizontal"
>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
{...provided.droppableProps}
>
{scenesVideoSelector.audios.length > 0 &&
scenesVideoSelector.audios.map((audio, i) => (
<>
<Draggable
key={audio.id}
draggableId={audio.id}
index={i}
isDragDisabled={resizing}
>
{(provided, snapshot) => (
<div
ref={(el) => {
if (el) {
provided.innerRef(el);
setDraggableWidth(
(prev) => (prev = el.offsetWidth)
);
}
}}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
{audio.silence ? (
<ResizableBox
width={50}
height={35}
resizeHandles={["e"]}
onResizeStart={() => {
console.log("-----début de resizing !-----");
setResizing(true);
}}
onResizeStop={() => {
setResizing(false);
audio.duration =
draggableWidth / (FRAM_RATE * SCALE);
console.log("-----fin de resizing !-----");
}}
>
<SceneItemAudio
isActive={
audio.id == scenesVideoSelector.currentScene &&
scenesVideoSelector.currentScene.id
}
key={audio.id}
data-duration={audio.duration}
data-scene-id={audio.id}
data-index={i}
itemWidth={audio.width}
onClick={updateCurrentVideo}
style={{
width: "100%",
}}
className="audioItem"
silence={audio.silence}
>
<SilenceItem
id={audio.id}
data-scene-id={audio.id}
indexPos={i}
duration={audio.duration}
/>
</SceneItemAudio>
</ResizableBox>
) : (
<SceneItemAudio
isActive={
audio.id == scenesVideoSelector.currentScene &&
scenesVideoSelector.currentScene.id
}
key={audio.id}
data-duration={audio.duration}
data-scene-id={audio.id}
data-index={i}
itemWidth={audio.width}
onClick={updateCurrentVideo}
style={{
width: audio.duration * FRAM_RATE * SCALE,
}}
className="audioItem"
// thumbnail={audio.thumbnail}
silence={audio.silence}
>
<AudioThumbnail
src={audio.src}
id={audio.id}
data-scene-id={audio.id}
itemWidth={audio.width}
indexPos={i}
start={audio.start}
end={audio.end}
silence={audio.silence}
/>
</SceneItemAudio>
)}
</div>
)}
</Draggable>
{/* {audio.silence ? (
<ResizableBox
width={50}
height={35}
resizeHandles={["e"]}
onResizeStart={() => {
console.log("-----début de resizing !-----");
resizing.current = true;
}}
onResizeStop={() => {
resizing.current = false;
const duration = draggableWidth / (FRAM_RATE * SCALE);
console.log("draggableWidth", draggableWidth);
console.log("duration --- parent", duration);
audio.duration = duration;
console.log("-----fin de resizing !-----");
}}
>
<Draggable
key={audio.id}
draggableId={audio.id}
index={i}
isDragDisabled={resizing.current}
>
{(provided, snapshot) => (
<div
ref={(el) => {
if (el) {
provided.innerRef(el);
setDraggableWidth(
(prev) => (prev = el.offsetWidth)
);
}
}}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<SceneItemAudio
isActive={
audio.id == scenesVideoSelector.currentScene &&
scenesVideoSelector.currentScene.id
}
key={audio.id}
data-duration={audio.duration}
data-scene-id={audio.id}
data-index={i}
itemWidth={audio.width}
onClick={udateCurrentVideo}
style={{
width: "100%",
}}
className="audioItem"
silence={audio.silence}
>
<SilenceItem
id={audio.id}
data-scene-id={audio.id}
indexPos={i}
duration={audio.duration}
/>
</SceneItemAudio>
</div>
)}
</Draggable>
</ResizableBox>
) : (
<Draggable
key={audio.id}
draggableId={audio.id}
index={i}
isDragDisabled={resizing.current}
>
{(provided, snapshot) => (
<div
ref={(el) => {
if (el) {
provided.innerRef(el);
setDraggableWidth(
(prev) => (prev = el.offsetWidth)
);
}
}}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
<SceneItemAudio
isActive={
audio.id == scenesVideoSelector.currentScene &&
scenesVideoSelector.currentScene.id
}
key={audio.id}
data-duration={audio.duration}
data-scene-id={audio.id}
data-index={i}
itemWidth={audio.width}
onClick={udateCurrentVideo}
style={{
width: audio.duration * FRAM_RATE * SCALE,
}}
className="audioItem"
// thumbnail={audio.thumbnail}
silence={audio.silence}
>
<AudioThumbnail
src={audio.src}
id={audio.id}
data-scene-id={audio.id}
itemWidth={audio.width}
indexPos={i}
start={audio.start}
end={audio.end}
silence={audio.silence}
/>
</SceneItemAudio>
</div>
)}
</Draggable>
)} */}
</>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
};
export default DragAndDropAudio;