Skip to content

Commit

Permalink
Full transfer to Mantine:
Browse files Browse the repository at this point in the history
Working:
 - Home
 - Video Upload
 - User Scene History
 - Config Selection
 - Login/Signup
Needs Functionality:
 - Account Deletion
 - Scene Deletion
 - About
 - Community / Published Scenes ( Lots Backend work )
  • Loading branch information
SimonDaKappa committed Sep 4, 2024
1 parent e0c3cbf commit 5ed6841
Show file tree
Hide file tree
Showing 40 changed files with 2,119 additions and 195 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@
"dependencies": {
"@mantine/core": "7.12.1",
"@mantine/hooks": "7.12.1",
"@react-three/drei": "^9.111.3",
"@tabler/icons-react": "^3.12.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.1"
"react-router-dom": "^6.26.1",
"react-three-fiber": "^6.0.13",
"three": "^0.167.1"
},
"devDependencies": {
"@types/node": "^22.5.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/three": "^0",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react": "^4.3.1",
Expand Down
57 changes: 57 additions & 0 deletions src/Components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @file MantineApp.tsx
* @description The main component for the Mantine App. Contains MantineProvider to pass ui context to children
* components. Contains AuthProvier to pass user context to children components. Contains AppShell to provide
*/

import {
MantineProvider,
AppShell,
ColorSchemeScript,
} from "@mantine/core";
import { theme } from "../../theme";
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";

import { AuthProvider } from "../../Context/AuthContext";
import Home from "../Home/Home";
import Login from "../Login/Login";
import Signup from "../Signup/Signup";
import Header from "../Header/Header";
import SceneHistory from "../SceneHistory/SceneHistory";
import Scene from "../Scene/Scene";
import LocalScene from "../Scene/LocalScene/LocalScene";

function MantineApp() {

return (
<MantineProvider theme={{ ...theme }} >
<ColorSchemeScript defaultColorScheme="dark" />
<Router>
<AuthProvider>
<AppShell header={{ height: 60 }} padding="md">

<AppShell.Header>
<Header />
</AppShell.Header>

<AppShell.Main>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/Home" element={<Home />} />
<Route path="/Login" element={<Login />} />
<Route path="/Signup" element={<Signup />} />
<Route path="/SceneHistory" element={<SceneHistory />} />\
<Route path="/Scene" element={<Scene />} />
<Route path="/Scene/Local" element={<LocalScene />} />
{/* Add other routes here */}
</Routes>
</AppShell.Main>

</AppShell>
</AuthProvider>
</Router>
</MantineProvider>
);
}

export default MantineApp;
45 changes: 0 additions & 45 deletions src/Components/App/MantineApp.tsx

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @file Header.tsx
* @desc This file defines the header component. Header component contains navigation links,
* color toggle, and user account dropdown. The header supports authenticated only links/additions.
*/

import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useContext } from "react";
Expand Down Expand Up @@ -25,11 +31,9 @@ import {
IconMoon,
} from "@tabler/icons-react";
import { AuthContext } from "../../Context/AuthContext";
import classes from "./MantineHeader.module.css";


import classes from "./Header.module.css";

function MantineHeader() {
function Header() {
const [opened, { toggle, close }] = useDisclosure(false);
const { isAuthenticated, username, logout } = useContext(AuthContext);
const { setColorScheme } = useMantineColorScheme();
Expand All @@ -40,11 +44,11 @@ function MantineHeader() {
const baseLinks = [
{ link: "/Home", label: "Home" },
{ link: "/About", label: "About" },
{ link: "/Scene/UploadASplatScene", label: "Render Local Scene" },
{ link: "/Scene/LocalScene", label: "Render Local Scene" },
];

if (isAuthenticated) {
baseLinks.push({ link: '/MyScenes', label: 'My Scenes' });
baseLinks.push({ link: '/SceneHistory', label: 'My Scenes' });
}

return baseLinks;
Expand All @@ -69,8 +73,7 @@ function MantineHeader() {
</a>
));



// f-string workaround for the dark mode button to function.
function cx(icon: string, light: string): string | undefined {
return `${icon} ${light}`;
}
Expand Down Expand Up @@ -219,4 +222,4 @@ function MantineHeader() {
);
}

export default MantineHeader;
export default Header;
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import { Container, Title, Text, Button, Group, Paper, Progress, Stack } from "@mantine/core";
import { useEffect, useState } from "react";
/**
* @file Home.tsx
* @desc Home component. This component should be a functionality hub for the user.
* It should allow the user to upload a video file, check the progress of the job,
* and navigate to other parts of the application. If future backend functionality is added,
* consider splitting this into smaller components.
*/

import { Container, Title, Text, Button, Group, Paper, Progress, Stack, Center } from "@mantine/core";
import { useContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { RequestMetaData, SceneProgressResponse } from "../../Types/Responses";
import { fetchSceneProgress } from "../../Fetch/CommonApiCalls";
import { useAuthFetchRetry } from "../../Fetch/Retry";
import { AuthContext } from "../../Context/AuthContext";
import VideoUpload from "./VideoUpload/VideoUpload";

function Home() {
const { isAuthenticated } = useContext(AuthContext);
const [sceneID, setSceneId] = useState<string | null>(null);
const [progress, setProgress] = useState<SceneProgressResponse | null>(null);
const [wasProcessing, setWasProcessing] = useState(false);
Expand All @@ -28,11 +38,8 @@ function Home() {
console.error(progress.error);
return;
}

setProgress(progress);

console.log("progress: ", progress);

// Scene Processing
if (!wasProcessing && progress.processing) {
console.log("Scene Processing");
Expand All @@ -51,6 +58,7 @@ function Home() {
}
}, [sceneID, wasProcessing]);

// Update new job info/error
const handleUpload = (newJobInfo: RequestMetaData) => {
if (newJobInfo.error) {
console.error(newJobInfo.error);
Expand All @@ -60,13 +68,36 @@ function Home() {
};

const handleGoToMyScenes = () => {
navigate("/MyScenes");
navigate("/SceneHistory");
};

const handleGoToScene = () => {
navigate(`/Scene?scene_id=${sceneID}`);
};

// Not Logged In - Show Landing Page
if (!isAuthenticated) {
return (
<Container size="md" style={{ height: '100vh' }}>
<Center style={{ height: '100%' }}>
<Stack align="center">
<Title order={2} ta="center">
Experience the Magic of Scene Reconstruction
</Title>
<Text size="lg" ta="center">
Create an account or login to upload your videos and watch them transform into interactive 3D scenes!
</Text>
<Group>
<Button onClick={() => navigate("/Signup")}>Create Account</Button>
<Button onClick={() => navigate("/Login")} variant="outline">Login</Button>
</Group>
</Stack>
</Center>
</Container>
);
}


return (
<Stack mih="100vh">
<Paper p="md" radius={0} >
Expand All @@ -83,6 +114,7 @@ function Home() {
happen.
</Title>
<Text ta="center" size="sm">
*Video file must smaller than 16MB. <br />
*Video file must be in .mp4 format. <br />
*TensoRF is no longer accepting new video uploads.
</Text>
Expand Down
7 changes: 7 additions & 0 deletions src/Components/Home/VideoUpload/ConfigSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* @file ConfigSelector.tsx
* @desc This component contains forms and buttons to select a training configuration.
* This component functions as a child component to one that requires a training configuration.
* Upon user input, this component will update the parent component with the new configuration.
*/

import React, { useState, useEffect } from "react";
import {
Stack,
Expand Down
43 changes: 24 additions & 19 deletions src/Components/Home/VideoUpload/VideoUpload.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import React, { useState } from 'react';
import { FileInput, Button, Alert, Stack } from '@mantine/core';
import { IconUpload, IconAlertCircle } from '@tabler/icons-react';
import { RequestMetaData } from '../../../Types/Responses';
import { fetchPostVideo } from '../../../Fetch/CommonApiCalls';
import ConfigSelector from './ConfigSelector';
import { TrainingConfig } from '../../../Types/TrainingConfig';
import { useAuthFetchRetry } from '../../../Fetch/Retry';
/**
* @file VideoUpload.tsx
* @desc This component allows the user to upload a video file and select a configuration for processing.
*/

import React, { useState } from "react";
import { FileInput, Button, Alert, Stack } from "@mantine/core";
import { IconUpload, IconAlertCircle } from "@tabler/icons-react";
import { RequestMetaData } from "../../../Types/Responses";
import { fetchPostVideo } from "../../../Fetch/CommonApiCalls";
import ConfigSelector from "./ConfigSelector";
import { TrainingConfig } from "../../../Types/TrainingConfig";
import { useAuthFetchRetry } from "../../../Fetch/Retry";

interface VideoUploadProps {
onUpload: (data: RequestMetaData) => void;
Expand All @@ -16,12 +21,11 @@ const VideoUpload: React.FC<VideoUploadProps> = ({ onUpload }) => {
const [uploading, setUploading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [config, setConfig] = useState<TrainingConfig>({
trainingMode: 'gaussian',
trainingMode: "gaussian",
outputTypes: [],
saveIterations: [],
sceneName: '',
sceneName: "",
});

const authRetryFetchPostVideo = useAuthFetchRetry(fetchPostVideo);

const handleFileChange = (file: File | null) => {
Expand All @@ -37,39 +41,40 @@ const VideoUpload: React.FC<VideoUploadProps> = ({ onUpload }) => {

const isConfigValid = () => {
return (
config.trainingMode !== '' &&
config.trainingMode !== "" &&
config.outputTypes.length > 0 &&
config.saveIterations.length > 0
);
};

// Send video and config to the backend for new scene creation
const handleUpload = async () => {
if (!file) return;

setUploading(true);
setError(null);

const response = await authRetryFetchPostVideo(file, config);

setUploading(false);

if (response !== null) {
onUpload(response);
} else {
setError('Upload failed');
setError("Upload failed");
}
};

return (
<Stack >
<Stack>
<FileInput
accept=".mp4"
label="Choose video file"
placeholder="Click to select file"
rightSection={<IconUpload size="1rem" />}
onChange={handleFileChange}
/>

{file && (
<>
<ConfigSelector onConfigChange={handleConfigChange} />
Expand All @@ -78,11 +83,11 @@ const VideoUpload: React.FC<VideoUploadProps> = ({ onUpload }) => {
disabled={uploading || !isConfigValid()}
loading={uploading}
>
{uploading ? 'Uploading...' : 'Upload Video'}
{uploading ? "Uploading..." : "Upload Video"}
</Button>
</>
)}

{error && (
<Alert icon={<IconAlertCircle size="1rem" />} title="Error" color="red">
{error}
Expand All @@ -92,4 +97,4 @@ const VideoUpload: React.FC<VideoUploadProps> = ({ onUpload }) => {
);
};

export default VideoUpload;
export default VideoUpload;
File renamed without changes.
Loading

0 comments on commit 5ed6841

Please sign in to comment.