diff --git a/client/package.json b/client/package.json index 0fc2300..9eaa7d1 100644 --- a/client/package.json +++ b/client/package.json @@ -21,6 +21,8 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-moment": "^1.1.1", + "react-movable": "^3.0.4", + "react-moveable": "^0.31.1", "react-router-dom": "^6.2.1", "react-scripts": "5.0.0", "socket.io-client": "^4.4.1", diff --git a/client/src/MediaControl.css b/client/src/MediaControl.css index ad28b63..d365bf7 100644 --- a/client/src/MediaControl.css +++ b/client/src/MediaControl.css @@ -1,23 +1,44 @@ +.MediaControlSpacer { + display: flex; + width: 5rem; + min-width: 5rem; + height: 3.75rem; + min-height: 3.75rem; + background-color: #444; + border-radius: 0.25rem; +} + .MediaControl { display: flex; - position: relative; + position: fixed; flex-direction: row; justify-content: flex-end; align-items: center; + width: 5rem; + height: 3.75rem; + min-width: 5rem; + min-height: 3.75rem; + z-index: 50000; } .MediaControl .Video { + position: relative; + width: 100%; + height: 100%; + /* width: 5rem; height: 3.75rem; + /* max-width: 5rem; max-height: 3.75rem; + */ background-color: #444; border-radius: 0.25rem; border: 1px solid black; } .MediaControl.Medium .Video { - position: relative; + /* display: flex; width: 11.5em; height: 8.625em; @@ -67,4 +88,13 @@ .MediaControl .Controls > div:hover { background-color: #d0d0d0; +} + +.moveable-control-box { + border: none; + --moveable-color: unset !important; +} + +.moveable-control-box .moveable-direction { + border: none !important; } \ No newline at end of file diff --git a/client/src/MediaControl.js b/client/src/MediaControl.js index ecd1919..e702950 100644 --- a/client/src/MediaControl.js +++ b/client/src/MediaControl.js @@ -1,5 +1,7 @@ import React, { useState, useEffect, useRef, useCallback, useContext } from "react"; +import Moveable from "react-moveable"; + import "./MediaControl.css"; import VolumeOff from '@mui/icons-material/VolumeOff'; @@ -494,7 +496,7 @@ const MediaAgent = ({setPeers}) => { }); canvas.getContext('2d').fillRect(0, 0, width, height); const stream = canvas.captureStream(); - return Object.assign(stream.getVideoTracks()[0], { + return Object.assign(stream.getVideoTracks()[1], { enabled: true }); } @@ -563,7 +565,15 @@ const MediaControl = ({isSelf, peer, className}) => { const [media, setMedia] = useState(undefined); const [muted, setMuted] = useState(undefined); const [videoOn, setVideoOn] = useState(undefined); - + const [target, setTarget] = useState(); + const [frame, setFrame] = useState({ + translate: [0, 0], + }); + + useEffect(() => { + setTarget(document.querySelectorAll(".MediaControl")[0]); + }, []); + /* local state is used to trigger re-renders, and the global * state is kept up to date in the peers object so re-assignment * of sessions doesn't kill the peer or change the mute/video states */ @@ -625,27 +635,62 @@ const MediaControl = ({isSelf, peer, className}) => { colorAudio = (isValid && media.hasAudio) ? 'primary' : 'disabled', colorVideo = (isValid && media.hasVideo) ? 'primary' : 'disabled'; - return