diff --git a/README.md b/README.md index b425b66..6410953 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ We used the _YOLOv8n-pose_ model to extract pose data efficiently on the server The frontend is implemented in Vite, while the backend is a mixture of Go and Python together with Pocketbase as a database. +![inferencing](examples/inferenced.mp4) ## References diff --git a/dance-app/src/App.tsx b/dance-app/src/App.tsx index 2a6843e..cc99337 100644 --- a/dance-app/src/App.tsx +++ b/dance-app/src/App.tsx @@ -1,11 +1,7 @@ -import { useState } from "react"; - -import PocketBase, { RecordAuthResponse } from "pocketbase"; import { AuthProvider } from "./context/AuthContext"; import { ThemeProvider } from "@emotion/react"; import { Box, createTheme, CssBaseline } from "@mui/material"; -import Login from "./sections/login"; import LandingPage from "./sections/landing"; import MainDrawerLayout from "./layouts/MainDrawerLayout"; @@ -15,10 +11,10 @@ const theme = createTheme({ }, palette: { background: { - default: "#121640", + default: "#01bfc8", }, primary: { - main: "#00c4cc", // big text + main: "#121640", }, secondary: { main: "#e43397", // small text @@ -39,8 +35,6 @@ const theme = createTheme({ }); function App() { - const pb = new PocketBase("https://junctionb.nyman.dev"); - return ( @@ -50,12 +44,12 @@ function App() { display: "flex", alignItems: "start", justifyContent: "center", - height: "100vh", + height: "100dvh", width: "100vw", }} > - + diff --git a/dance-app/src/Leaderboard.css b/dance-app/src/Leaderboard.css index 821e908..9df540f 100644 --- a/dance-app/src/Leaderboard.css +++ b/dance-app/src/Leaderboard.css @@ -1,7 +1,7 @@ .list { width: 100vw; overflow: scroll; - max-height: 100vh; + max-height: 100dvh; } .spacer { diff --git a/dance-app/src/Loader.css b/dance-app/src/Loader.css index 3d711fa..b6ff8f0 100644 --- a/dance-app/src/Loader.css +++ b/dance-app/src/Loader.css @@ -1,6 +1,6 @@ .center { width: 100%; - height: 100vh; + height: 100dvh; display: flex; justify-content: center; align-items: center; diff --git a/dance-app/src/Recording.css b/dance-app/src/Recording.css index 45f0909..ae58ff8 100644 --- a/dance-app/src/Recording.css +++ b/dance-app/src/Recording.css @@ -1,6 +1,6 @@ .App { width: 100vw; - height: 100vh; + height: 100dvh; overflow: hidden; position: relative; } @@ -43,15 +43,13 @@ display: flex; align-items: center; justify-content: center; - width: 128px; margin: auto; margin-top: 100px; - border-radius: 100px; z-index: 5; } -.record-button span { - padding: 50px; +.App-header > .record-button h2 { + font-weight: 500; } .container { @@ -67,7 +65,7 @@ flex-direction: column; align-items: center; justify-content: center; - height: 100vh; + height: 100dvh; } .video-container > video { height: 100%; diff --git a/dance-app/src/components/Drawer.tsx b/dance-app/src/components/Drawer.tsx index 51e7533..8e894f8 100644 --- a/dance-app/src/components/Drawer.tsx +++ b/dance-app/src/components/Drawer.tsx @@ -1,14 +1,8 @@ import { Box, Button, useTheme } from "@mui/material"; -import { FC } from "react"; import "../Drawer.css"; import { makeStyles } from "@mui/styles"; import { Pages } from "../context/PageContext"; -interface DrawerProps { - view: Pages; - setView: (view: Pages) => void; -} - const useStyles = makeStyles(() => ({ box: { position: "absolute", @@ -33,7 +27,12 @@ const useStyles = makeStyles(() => ({ }, })); -const Drawer: FC = ({ view, setView }) => { +type DrawerProps = { + view: Pages; + setView: (view: Pages) => void; +}; + +const Drawer = ({ view, setView }: DrawerProps) => { const theme = useTheme(); const classes = useStyles(theme); diff --git a/dance-app/src/components/Leaderboard.tsx b/dance-app/src/components/Leaderboard.tsx index 0d8b3db..c9da852 100644 --- a/dance-app/src/components/Leaderboard.tsx +++ b/dance-app/src/components/Leaderboard.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from "react"; import Loader from "./Loader"; -import PocketBase from "pocketbase"; import "../Leaderboard.css"; -import {Card, CardContent, CardMedia, Stack, Typography} from "@mui/material"; +import { Card, CardContent, CardMedia, Stack, Typography } from "@mui/material"; +import pb from "../pocketBase"; interface VideoData { id: string; @@ -20,25 +20,17 @@ interface User { email: string; name: string; } -interface LeaderboardProps { - pb: PocketBase; -} -function Leaderboard({ pb }: LeaderboardProps) { +function Leaderboard() { const [isLoading, setIsLoading] = useState(true); const [videos, setVideos] = useState([]); useEffect(() => { - const getVideos = async () => { - const newVideos = await pb - .collection("videos") - .getFullList({ expand: "user" }); - console.log(newVideos); - setVideos(newVideos); - setIsLoading(false); - }; - getVideos(); - }, [pb]); + pb.collection("videos") + .getFullList({ expand: "user" }) + .then((newVideos) => setVideos(newVideos)) + .then(() => setIsLoading(false)); + }, []); if (isLoading) { return ; @@ -57,26 +49,30 @@ function Leaderboard({ pb }: LeaderboardProps) { Todays high scores - {scoredVideos.map(({ id, collectionId, video, tier, score, expand }) => ( - - - - Tier {tier} - - {expand?.user?.name} - {': '} - {score} - - - - ))} + {scoredVideos.map( + ({ id, collectionId, video, tier, score, expand }) => ( + + + + + Tier {tier} + + + {expand?.user?.name} + {": "} + {score} + + + + ), + )} ); diff --git a/dance-app/src/components/LoginForm.tsx b/dance-app/src/components/LoginForm.tsx index 5ac6be2..f53eb1e 100644 --- a/dance-app/src/components/LoginForm.tsx +++ b/dance-app/src/components/LoginForm.tsx @@ -2,8 +2,8 @@ import { useState, FormEvent, useContext } from "react"; import Button from "@mui/material/Button"; import TextField from "@mui/material/TextField"; import Typography from "@mui/material/Typography"; -import Paper from "@mui/material/Paper"; import { makeStyles } from "@mui/styles"; +import { Box, useTheme } from "@mui/material"; import { AuthContext } from "../context/AuthContext"; const useStyles = makeStyles(() => ({ @@ -16,11 +16,12 @@ const useStyles = makeStyles(() => ({ margin: "auto", marginTop: 3, borderRadius: 10, - backgroundColor: "#4c0bd1", + zIndex: "15", }, })); const LoginForm = () => { + const theme = useTheme(); const classes = useStyles(); const { login } = useContext(AuthContext); @@ -42,12 +43,18 @@ const LoginForm = () => { }; return ( - + <> - + Login -
+ { onChange={handleUsernameChange} fullWidth margin="normal" + sx={{ + input: { color: "white" }, + }} /> { onChange={handlePasswordChange} fullWidth margin="normal" + sx={{ + input: { color: "white" }, + }} />
- -
+ ); }; diff --git a/dance-app/src/components/logo.tsx b/dance-app/src/components/logo.tsx index 66d3dc9..e7aeaad 100644 --- a/dance-app/src/components/logo.tsx +++ b/dance-app/src/components/logo.tsx @@ -81,8 +81,8 @@ const Logo = (props: SVGProps) => ( /> ); diff --git a/dance-app/src/context/PocketBaseContext.tsx b/dance-app/src/context/PocketBaseContext.tsx deleted file mode 100644 index e50a5b4..0000000 --- a/dance-app/src/context/PocketBaseContext.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { RecordAuthResponse } from "pocketbase"; -import { ReactNode, createContext, useContext, useState } from "react"; -import PocketBase from "pocketbase"; - -interface Auth { - login: () -} - -export const AuthContext = createContext(null); - -export const AuthContextProvider = ({ children }: { children: ReactNode }) => { - const [auth, setAuth] = useState(null); - const {pb} = usePocketBase("https://junctionb.nyman.dev") - - return {children}; -}; - -export const useAuth = () => useContext(AuthContext); diff --git a/dance-app/src/index.css b/dance-app/src/index.css index 209f675..a63bdce 100644 --- a/dance-app/src/index.css +++ b/dance-app/src/index.css @@ -28,7 +28,7 @@ body { display: flex; place-items: center; min-width: 320px; - min-height: 100vh; + min-height: 100dvh; } h1 { diff --git a/dance-app/src/layouts/MainDrawerLayout.tsx b/dance-app/src/layouts/MainDrawerLayout.tsx index 566ddb1..87bd5b1 100644 --- a/dance-app/src/layouts/MainDrawerLayout.tsx +++ b/dance-app/src/layouts/MainDrawerLayout.tsx @@ -13,7 +13,7 @@ const useStyles = makeStyles(() => ({ root: { position: "relative", display: "flex", - height: "100vh", + height: "100dvh", width: "100vw", alignItems: "center", // justifyContent: "center", diff --git a/dance-app/src/sections/home.tsx b/dance-app/src/sections/home.tsx new file mode 100644 index 0000000..78581e8 --- /dev/null +++ b/dance-app/src/sections/home.tsx @@ -0,0 +1,97 @@ +import { Container, Typography, Button, Grid } from "@mui/material"; +import RecordingPage from "./recording"; +import { useEffect, useState } from "react"; +import pb from "../pocketBase"; + +export interface RefVideo { + id: string; + collectionId: string; + tier: string; + video: string; +} + +// eslint-disable-next-line react-refresh/only-export-components +export enum Tier { + Tier1 = 1, + Tier2 = 2, + Tier3 = 3, + Tier4 = 4, + Tier5 = 5, +} + +const HomeSection = () => { + const [selectedTier, setSelectedTier] = useState(null); + const handleButtonClick = (tier: Tier) => setSelectedTier(tier); + const [refVideos, setRefVideos] = useState([]); + + useEffect(() => { + pb.collection("source_videos") + .getFullList() + .then((videos) => setRefVideos(videos)); + }, []); + + return ( + <> + {selectedTier ? ( + video.tier === selectedTier.toString(), + )} + pb={pb} + goBack={setSelectedTier} + /> + ) : ( + + + + + Ur fat! + + + Explore our amazing features! + + + + + + + + + + + + + + )} + + ); +}; + +export default HomeSection; diff --git a/dance-app/src/sections/landing.tsx b/dance-app/src/sections/landing.tsx index a2ce473..3ae7147 100644 --- a/dance-app/src/sections/landing.tsx +++ b/dance-app/src/sections/landing.tsx @@ -1,124 +1,11 @@ -import { useContext, useEffect, useState } from "react"; -import { Container, Typography, Button, Grid } from "@mui/material"; -import PocketBase from "pocketbase"; -import RecordingPage from "./recording"; +import { useContext } from "react"; import { PageContext } from "../context/PageContext"; import Leaderboard from "../components/Leaderboard"; -import { AuthContext } from "../context/AuthContext"; +import HomeSection from "./home"; -interface LandingProps { - pb: PocketBase; -} - -export interface RefVideo { - id: string; - collectionId: string; - tier: string; - video: string; -} - -// eslint-disable-next-line react-refresh/only-export-components -export enum Tier { - Tier1 = 1, - Tier2 = 2, - Tier3 = 3, - Tier4 = 4, - Tier5 = 5, -} - -const LandingPage = ({ pb }: LandingProps) => { +const LandingPage = () => { const page = useContext(PageContext); - const [selectedTier, setSelectedTier] = useState(null); - const [refVideos, setRefVideos] = useState([]); - const { user } = useContext(AuthContext); - - useEffect(() => { - if (user?.token !== "") { - } - }, [user]); - - useEffect(() => { - const getRefVideos = async () => { - const videos = await pb - .collection("source_videos") - .getFullList(); - setRefVideos(videos); - }; - getRefVideos(); - }, []); - - const handleButtonClick = (tier: Tier) => { - setSelectedTier(tier); - }; - - return ( - <> - {page === "home" ? ( - <> - {selectedTier ? ( - video.tier === selectedTier.toString(), - )} - pb={pb} - goBack={setSelectedTier} - /> - ) : ( - - - - - Ur fat! - - - Explore our amazing features! - - - - - - - - - - - - - - )} - - ) : ( - - )} - - ); + return page === "home" ? : ; }; export default LandingPage; diff --git a/dance-app/src/sections/recording.tsx b/dance-app/src/sections/recording.tsx index 2598a95..844c285 100644 --- a/dance-app/src/sections/recording.tsx +++ b/dance-app/src/sections/recording.tsx @@ -4,17 +4,20 @@ import { Recording } from "react-record-webcam/dist/useRecording"; import Leaderboard from "../components/Leaderboard"; import Submit from "../Submit"; import "../Recording.css"; -import { RefVideo, Tier } from "./landing"; import Pocketbase from "pocketbase"; import { PageContext } from "../context/PageContext"; -import { Button, useTheme } from "@mui/material"; +import { Button, Typography, useTheme } from "@mui/material"; import { makeStyles } from "@mui/styles"; +import { RefVideo, Tier } from "./home"; const useStyles = makeStyles(() => ({ backButton: { marginTop: "10px!important", zIndex: "10", }, + recordButton: { + borderRadius: "150px!important", + }, })); enum VideoState { @@ -89,12 +92,17 @@ const RecordingPage = ({ refVideo, pb, goBack }: RecordingPageProps) => { - +
+ +
{activeRecordings.map((recording) => ( @@ -127,7 +135,7 @@ const RecordingPage = ({ refVideo, pb, goBack }: RecordingPageProps) => {
- +