diff --git a/package-lock.json b/package-lock.json
index a360337..28309aa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"classnames": "^2.3.1",
"color-hash": "^2.0.1",
"events": "^3.3.0",
+ "lodash-move": "^1.1.1",
"matrix-js-sdk": "^12.0.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
@@ -1099,6 +1100,19 @@
"verror": "1.10.0"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/lodash-move": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/lodash-move/-/lodash-move-1.1.1.tgz",
+ "integrity": "sha1-WfduDxrFfm2Gg/UxvsB8W26k40g=",
+ "dependencies": {
+ "lodash": "^4.6.1"
+ }
+ },
"node_modules/loglevel": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
@@ -2530,6 +2544,19 @@
"verror": "1.10.0"
}
},
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "lodash-move": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/lodash-move/-/lodash-move-1.1.1.tgz",
+ "integrity": "sha1-WfduDxrFfm2Gg/UxvsB8W26k40g=",
+ "requires": {
+ "lodash": "^4.6.1"
+ }
+ },
"loglevel": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
diff --git a/package.json b/package.json
index 1dbbe13..923e308 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"classnames": "^2.3.1",
"color-hash": "^2.0.1",
"events": "^3.3.0",
+ "lodash-move": "^1.1.1",
"matrix-js-sdk": "^12.0.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
diff --git a/src/GridDemo.jsx b/src/GridDemo.jsx
index ddf856e..380f270 100644
--- a/src/GridDemo.jsx
+++ b/src/GridDemo.jsx
@@ -1,8 +1,9 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import { useDrag } from "react-use-gesture";
-import { useSprings, animated, useSpring } from "@react-spring/web";
+import { useSprings, animated } from "@react-spring/web";
import styles from "./GridDemo.module.css";
import useMeasure from "react-use-measure";
+import moveArrItem from "lodash-move";
function isInside([x, y], targetTile) {
const left = targetTile.x;
@@ -128,7 +129,9 @@ export function GridDemo() {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
setStream(stream);
tileOrderRef.current.push(tileOrderRef.current.length);
+
setTileState(() => {
+ console.log("startWebcam");
const tiles = [{ stream, key: tileKey.current++, remove: false }];
const tilePositions = getTilePositions(tiles, gridBounds);
return { tiles, tilePositions };
@@ -141,6 +144,7 @@ export function GridDemo() {
tileOrderRef.current.push(tileOrderRef.current.length);
setTileState(({ tiles }) => {
+ console.log("addTile");
const newTiles = [
...tiles,
{ stream: newStream, key: tileKey.current++, remove: false },
@@ -193,10 +197,11 @@ export function GridDemo() {
}, [gridBounds]);
const animate = useCallback(
- (order) => (index) => {
- const tileIndex = order[index];
+ (tileIndex) => {
+ const tileOrder = tileOrderRef.current;
+ const order = tileOrder.indexOf(tileIndex);
const tile = tiles[tileIndex];
- const tilePosition = tilePositions[tileIndex];
+ const tilePosition = tilePositions[order];
const draggingTile = draggingTileRef.current;
const dragging = draggingTile && tile.key === draggingTile.key;
const remove = tile.remove;
@@ -205,8 +210,8 @@ export function GridDemo() {
return {
width: tilePosition.width,
height: tilePosition.height,
- x: tilePosition.x + draggingTile.x,
- y: tilePosition.y + draggingTile.y,
+ x: draggingTile.offsetX + draggingTile.x,
+ y: draggingTile.offsetY + draggingTile.y,
scale: 1.1,
opacity: 1,
zIndex: 1,
@@ -237,47 +242,62 @@ export function GridDemo() {
[tiles, tilePositions]
);
- const [springs, api] = useSprings(
- tiles.length,
- animate(tileOrderRef.current),
- [tilePositions, tiles]
- );
+ const [springs, api] = useSprings(tiles.length, animate, [
+ tilePositions,
+ tiles,
+ ]);
- const bind = useDrag(({ args: [index], active, xy, movement }) => {
- let order = tileOrderRef.current;
+ const bind = useDrag(({ args: [key], active, xy, movement }) => {
+ const tileOrder = tileOrderRef.current;
- const tileIndex = tileOrderRef.current[index];
- const tile = tiles[tileIndex];
+ const dragTileIndex = tiles.findIndex((tile) => tile.key === key);
+ const dragTile = tiles[dragTileIndex];
+
+ const dragTileOrder = tileOrder.indexOf(dragTileIndex);
const cursorPosition = [xy[0] - gridBounds.left, xy[1] - gridBounds.top];
- for (let i = 0; i < tileOrderRef.current.length; i++) {
- if (i === index) {
+ for (
+ let hoverTileIndex = 0;
+ hoverTileIndex < tiles.length;
+ hoverTileIndex++
+ ) {
+ const hoverTile = tiles[hoverTileIndex];
+ const hoverTileOrder = tileOrder.indexOf(hoverTileIndex);
+ const hoverTilePosition = tilePositions[hoverTileOrder];
+
+ if (hoverTile.key === key) {
continue;
}
- const hoverTileIndex = tileOrderRef.current[i];
- const hoverTilePosition = tilePositions[hoverTileIndex];
-
if (isInside(cursorPosition, hoverTilePosition)) {
- // TODO: Figure out swapping
- // order[i] = tileIndex;
- // order[index] = i;
+ tileOrderRef.current = moveArrItem(
+ tileOrder,
+ dragTileOrder,
+ hoverTileOrder
+ );
break;
}
}
if (active) {
- draggingTileRef.current = {
- key: tile.key,
- x: movement[0],
- y: movement[1],
- };
+ if (!draggingTileRef.current) {
+ const tilePosition = tilePositions[dragTileOrder];
+
+ draggingTileRef.current = {
+ key: dragTile.key,
+ offsetX: tilePosition.x,
+ offsetY: tilePosition.y,
+ };
+ }
+
+ draggingTileRef.current.x = movement[0];
+ draggingTileRef.current.y = movement[1];
} else {
draggingTileRef.current = null;
}
- api.start(animate(order));
+ api.start(animate);
});
return (
@@ -300,7 +320,7 @@ export function GridDemo() {
return (
);
@@ -331,6 +352,7 @@ function ParticipantTile({ style, stream, remove, tileKey, ...rest }) {
return (
+ {tileKey}
);
diff --git a/src/GridDemo.module.css b/src/GridDemo.module.css
index 7e71c6e..7dbf2e8 100644
--- a/src/GridDemo.module.css
+++ b/src/GridDemo.module.css
@@ -26,4 +26,12 @@
width: 100%;
height: 100%;
object-fit: cover;
+}
+
+.participantName {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ background-color: rgba(0, 0, 0, 0.2);
+ padding: 8px 24px;
}
\ No newline at end of file