Skip to content

Commit

Permalink
work on game finished dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
naueramant committed Jun 15, 2024
1 parent 0e68f6d commit 9fd081f
Show file tree
Hide file tree
Showing 9 changed files with 393 additions and 86 deletions.
33 changes: 33 additions & 0 deletions src/hooks/camera.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useEffect, useState } from "react";

export const useVideoDevices = () => {
const [devices, setDevices] = useState<MediaDeviceInfo[] | null>(null);
const [error, setError] = useState<unknown | null>(null);

const getDevices = async () => {
try {
await navigator.mediaDevices.getUserMedia({
video: true,
audio: false,
});

const allDevices = await navigator.mediaDevices.enumerateDevices();
const videoInputDevices = allDevices.filter(
(device) => device.kind === "videoinput",
);

setDevices(videoInputDevices);
} catch (error) {
setError(error);
}
};

useEffect(() => {
getDevices();
}, []);

return {
devices,
error,
};
};
12 changes: 12 additions & 0 deletions src/theme/dark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ dark.components = {
},
},
},
MuiInputBase: {
styleOverrides: {
root: {
"& input": {
"&:-webkit-autofill": {
// Hack to prevent autofill from changing the text color
transitionDelay: "9999999999999999s",
},
},
},
},
},
};

export { dark };
12 changes: 12 additions & 0 deletions src/theme/light.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ light.components = {
},
},
},
MuiInputBase: {
styleOverrides: {
root: {
"& input": {
"&:-webkit-autofill": {
// Hack to prevent autofill from changing the text color
transitionDelay: "9999999999999999s",
},
},
},
},
},
};

export { light };
3 changes: 3 additions & 0 deletions src/views/Game/components/ChugDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ const ChugDialog: FunctionComponent<ChugDialogProps> = (props) => {
useEffect(() => {
if (props.open) {
reset();
} else {
clearInterval(intervalRef);
setIntervalRef(undefined);
}
}, [props.open]);

Expand Down
237 changes: 155 additions & 82 deletions src/views/Game/components/GamFinishedDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,119 +1,192 @@
import {
Box,
Button,
ButtonBase,
Dialog,
DialogActions,
DialogContent,
DialogProps,
DialogTitle,
Divider,
Fab,
IconButton,
Stack,
useTheme,
} from "@mui/material";
import { FunctionComponent } from "react";
import { FunctionComponent, useEffect, useState } from "react";
import { BsCamera } from "react-icons/bs";
import { HiOutlinePlusSm } from "react-icons/hi";
import { PiCameraRotate } from "react-icons/pi";
import { useVideoDevices } from "../../../hooks/camera";
import useGame from "../../../stores/game";

interface GameFinishedDialogProps extends DialogProps {}

const GameFinishedDialog: FunctionComponent<GameFinishedDialogProps> = (
props,
) => {
const theme = useTheme();

const game = useGame((state) => ({
Exit: state.Exit,
}));

const theme = useTheme();

return (
<Dialog {...props}>
<DialogTitle textAlign="center" variant="h4">
Game finished!
</DialogTitle>

<DialogContent
sx={{
textAlign: "center",
minWidth: 500,
height: "fit-content",
}}
>
{/* Row of players in their rank order */}
<>
<Dialog {...props}>
<DialogTitle textAlign="center" variant="h4">
Game finished!
</DialogTitle>

<ButtonBase
<DialogContent sx={{}}>
<Stack>
{/* <Camera /> */}

<textarea
style={{
height: 50,
resize: "none",
border: "none",
outline: "none",
color: theme.palette.text.primary,
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadius + "px",
borderColor: theme.palette.divider,
borderStyle: "solid",
borderWidth: "1px",
marginTop: theme.spacing(2),
padding: theme.spacing(1),
}}
placeholder="Write a description"
maxLength={1000}
/>
</Stack>
</DialogContent>

<DialogActions
sx={{
borderRadius: (t) => t.shape.borderRadius + "px",
overflow: "hidden",
width: "100%",
padding: 2,
}}
>
<Box
sx={{
height: 350,
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: (t) => t.palette.grey[200],
// backgroundImage:
// "url(https://source.unsplash.com/random/800x600)",
}}
>
<Box sx={{ position: "relative" }}>
<BsCamera size={64} />
<HiOutlinePlusSm
size={32}
style={{
position: "absolute",
right: -20,
top: -5,
}}
/>
</Box>
</Box>
</ButtonBase>

<Divider
sx={{
marginTop: 2,
marginBottom: 2,
}}
/>

<textarea
style={{
width: "100%",
height: 50,
resize: "none",
border: "none",
outline: "none",
color: theme.palette.text.primary,
backgroundColor: "transparent",
}}
placeholder="Write a description"
maxLength={1000}
/>
</DialogContent>

<DialogActions
sx={{
padding: 2,
}}
>
<Stack flex="1" spacing={1}>
<Button
variant="contained"
fullWidth
variant="contained"
size="large"
onClick={() => game.Exit()}
>
Submit
Submit and exit
</Button>
</Stack>
</DialogActions>
</Dialog>
</DialogActions>
</Dialog>
</>
);
};

const Camera: FunctionComponent = () => {
const theme = useTheme();

const { devices: cameraDevices, error: cameraError } = useVideoDevices();
const [selectedDevice, setSelectedDevice] = useState<MediaDeviceInfo | null>(
null,
);

const hasNoDevices = cameraDevices && cameraDevices.length === 0;
const hasMultipleDevices = cameraDevices && cameraDevices.length > 1;

useEffect(() => {
if (cameraDevices) {
setSelectedDevice(cameraDevices[0]);
}
}, [cameraDevices]);

const takePicture = async () => {
if (!selectedDevice) {
return;
}

const video = document.querySelector("video") as HTMLVideoElement;

const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;

const context = canvas.getContext("2d");
context?.drawImage(video, 0, 0, canvas.width, canvas.height);

canvas.toBlob((blob) => {
if (!blob) {
return;
}

// TODO
});
};

const changeCamera = () => {
if (!cameraDevices) {
return;
}

const currentIndex = cameraDevices.findIndex(
(d) => d.deviceId === selectedDevice?.deviceId,
);

const nextIndex = (currentIndex + 1) % cameraDevices.length;

setSelectedDevice(cameraDevices[nextIndex]);
};

if (!cameraDevices || cameraDevices.length === 0 || !!cameraError) {
return null;
}

return (
<Stack spacing={1} alignItems={"center"} sx={{ flex: 1 }}>
<video
id="video"
autoPlay
playsInline
style={{
borderRadius: theme.shape.borderRadius + "px",
}}
ref={(video) => {
if (video && selectedDevice) {
navigator.mediaDevices
.getUserMedia({
video: {
deviceId: selectedDevice.deviceId,
},
})
.then((stream) => {
video.srcObject = stream;
});
}
}}
/>

<Stack
spacing={1}
direction="row"
justifyContent="space-between"
alignItems="center"
>
<Box sx={{ width: "30%", textAlign: "left" }} />

<Box sx={{ width: "40%" }}>
<Fab onClick={takePicture} size="large" color="primary">
<BsCamera size={32} />
</Fab>
</Box>

<Box sx={{ width: "30%" }}>
<IconButton
onClick={changeCamera}
sx={{
display: hasNoDevices || !hasMultipleDevices ? "none" : undefined,
}}
>
<PiCameraRotate size={32} />
</IconButton>
</Box>
</Stack>
</Stack>
);
};

Expand Down
Loading

0 comments on commit 9fd081f

Please sign in to comment.