Fixed mediacontrol buttons on mobile

This commit is contained in:
James Ketr 2025-09-16 10:46:48 -07:00
parent 1204a5ef21
commit a0148fe8b9
2 changed files with 67 additions and 4 deletions

View File

@ -1340,6 +1340,18 @@ const MediaControl: React.FC<MediaControlProps> = ({ isSelf, peer, className })
const spacerRef = useRef<HTMLDivElement>(null);
const moveableRef = useRef<any>(null);
const [isDragging, setIsDragging] = useState<boolean>(false);
// Reset drag state on pointerup/touchend/mouseup anywhere in the document
useEffect(() => {
const resetDrag = () => setIsDragging(false);
document.addEventListener("pointerup", resetDrag);
document.addEventListener("touchend", resetDrag);
document.addEventListener("mouseup", resetDrag);
return () => {
document.removeEventListener("pointerup", resetDrag);
document.removeEventListener("touchend", resetDrag);
document.removeEventListener("mouseup", resetDrag);
};
}, []);
useEffect(() => {
console.log(
@ -1600,15 +1612,15 @@ const MediaControl: React.FC<MediaControlProps> = ({ isSelf, peer, className })
>
<Box className="Controls">
{isSelf ? (
<IconButton onClick={toggleMute} onTouchStart={toggleMute}>
<IconButton onClick={toggleMute}>
{muted ? <MicOff color={colorAudio} /> : <Mic color={colorAudio} />}
</IconButton>
) : (
<IconButton onClick={toggleMute} onTouchStart={toggleMute}>
<IconButton onClick={toggleMute}>
{muted ? <VolumeOff color={colorAudio} /> : <VolumeUp color={colorAudio} />}
</IconButton>
)}
<IconButton onClick={toggleVideo} onTouchStart={toggleVideo}>
<IconButton onClick={toggleVideo}>
{videoOn ? <Videocam color={colorVideo} /> : <VideocamOff color={colorVideo} />}
</IconButton>
</Box>
@ -1651,6 +1663,15 @@ const MediaControl: React.FC<MediaControlProps> = ({ isSelf, peer, className })
origin={false}
edge
onDragStart={(e) => {
// Only block drag if the event is a pointerdown/touchstart on a button, but do not interfere with click/touch events
const controls = containerRef.current?.querySelector('.Controls');
const target = e.inputEvent?.target as HTMLElement;
if (controls && target && (target.closest('button') || target.closest('.MuiIconButton-root'))) {
if (typeof e.stopDrag === 'function') {
e.stopDrag();
}
return;
}
setIsDragging(true);
}}
onDrag={(e) => {

View File

@ -116,7 +116,7 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
const message = JSON.parse(event.data);
const data: any = message.data;
switch (message.type) {
case "lobby_state":
case "lobby_state": {
type LobbyStateData = {
participants: User[];
};
@ -128,6 +128,14 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
lobby_state.participants.sort(sortUsers);
setUsers(lobby_state.participants);
break;
}
case "update_name": {
// Update local session name immediately
if (data && typeof data.name === "string") {
session.name = data.name;
}
break;
}
default:
break;
}
@ -143,6 +151,19 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
});
}, [users, sendJsonMessage]);
// Add state for name change UI
const [newName, setNewName] = useState("");
const [changingName, setChangingName] = useState(false);
// Handler for changing name
const handleChangeName = () => {
if (!newName.trim()) return;
setChangingName(true);
sendJsonMessage({ type: "set_name", data: { name: newName } });
setNewName("");
setTimeout(() => setChangingName(false), 1000); // UI feedback
};
return (
<Box sx={{ position: "relative", width: "100%" }}>
<Paper
@ -153,6 +174,27 @@ const UserList: React.FC<UserListProps> = (props: UserListProps) => {
m: { xs: 0, sm: 2 },
}}
>
{/* Name change UI for local user */}
{session && (
<Box sx={{ mb: 2, display: "flex", alignItems: "center", gap: 1 }}>
<input
type="text"
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder="Change your name"
style={{ fontSize: "1em", padding: "4px 8px", borderRadius: 4, border: "1px solid #ccc" }}
disabled={changingName}
/>
<Button
variant="contained"
size="small"
onClick={handleChangeName}
disabled={changingName || !newName.trim()}
>
{changingName ? "Changing..." : "Change Name"}
</Button>
</Box>
)}
<MediaAgent {...{ session, socketUrl, peers, setPeers }} />
<List className="UserSelector">
{users?.map((user) => (