Skip to content

Commit 0735349

Browse files
authored
Merge pull request #131 from nebulabroadcast/130-background-upload-service-overhaul
Media upload overhaul
2 parents 883b9ea + d6f9369 commit 0735349

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+867
-448
lines changed

frontend/.mise.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

frontend/src/app.jsx

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import { useLocalStorage } from '/src/hooks';
88

99
import { Routes, Route, Navigate, BrowserRouter } from 'react-router-dom';
1010

11+
import { MediaUploadMonitor } from './containers/MediaUpload/MediaUploadMonitor';
1112
import { DialogProvider } from './hooks/useDialog';
13+
import { MediaUploadProvider } from './hooks/useMediaUpload';
1214

1315
import WebsocketListener from '/src/websocket';
1416
import MainNavbar from '/src/containers/MainNavbar';
@@ -79,28 +81,35 @@ const App = () => {
7981
<Suspense fallback={<LoadingPage />}>
8082
<WebsocketListener />
8183
<DialogProvider>
82-
<BrowserRouter>
83-
<MainNavbar />
84-
<Routes>
85-
<Route path="/" exact element={<Navigate replace to="/mam/editor" />} />
86-
<Route path="/mam" exact element={<Navigate replace to="/mam/editor" />} />
87-
<Route path="/mam/:module" element={<MAMPage />} />
88-
<Route
89-
path="/jobs"
90-
exact
91-
element={<Navigate replace to="/jobs/active" />}
92-
/>
93-
<Route
94-
path="/system"
95-
exact
96-
element={<Navigate replace to="/system/services" />}
97-
/>
98-
<Route path="/jobs/:view" element={<JobsPage />} />
99-
<Route path="/system/:view" element={<SystemPage />} />
100-
<Route path="/tool/:tool" element={<ToolPage />} />
101-
<Route path="/profile" element={<ProfilePage />} />
102-
</Routes>
103-
</BrowserRouter>
84+
<MediaUploadProvider>
85+
<BrowserRouter>
86+
<MainNavbar />
87+
<Routes>
88+
<Route path="/" exact element={<Navigate replace to="/mam/editor" />} />
89+
<Route
90+
path="/mam"
91+
exact
92+
element={<Navigate replace to="/mam/editor" />}
93+
/>
94+
<Route path="/mam/:module" element={<MAMPage />} />
95+
<Route
96+
path="/jobs"
97+
exact
98+
element={<Navigate replace to="/jobs/active" />}
99+
/>
100+
<Route
101+
path="/system"
102+
exact
103+
element={<Navigate replace to="/system/services" />}
104+
/>
105+
<Route path="/jobs/:view" element={<JobsPage />} />
106+
<Route path="/system/:view" element={<SystemPage />} />
107+
<Route path="/tool/:tool" element={<ToolPage />} />
108+
<Route path="/profile" element={<ProfilePage />} />
109+
</Routes>
110+
<MediaUploadMonitor />
111+
</BrowserRouter>
112+
</MediaUploadProvider>
104113
</DialogProvider>
105114
</Suspense>
106115
);

frontend/src/components/Dialog.jsx

Lines changed: 0 additions & 132 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import styled from 'styled-components';
2+
3+
export const StyledDialog = styled.dialog`
4+
color: var(--color-text);
5+
padding: 6px;
6+
background-color: var(--color-surface-02);
7+
border-radius: 12px;
8+
display: flex;
9+
flex-direction: column;
10+
gap: 6px;
11+
min-width: 300px;
12+
min-height: 150px;
13+
max-width: 85%;
14+
max-height: 80%;
15+
border: none;
16+
17+
// Animated parameters
18+
19+
transition: all 0.3s ease;
20+
opacity: 0;
21+
transform: scale(0.9);
22+
23+
&::backdrop {
24+
background-color: rgba(0, 0, 0, 0);
25+
backdrop-filter: none;
26+
z-index: 999; // P5e04
27+
}
28+
29+
&[open] {
30+
opacity: 1;
31+
transform: scale(1);
32+
&::backdrop {
33+
background-color: rgba(0, 0, 0, 0.6);
34+
backdrop-filter: blur(2px);
35+
}
36+
}
37+
38+
// Guts
39+
40+
header,
41+
footer {
42+
padding: 12px 6px;
43+
display: flex;
44+
flex-direction: row;
45+
gap: 6px;
46+
}
47+
48+
header {
49+
font-weight: bold;
50+
border-bottom: 1px solid var(--color-surface-04);
51+
justify-content: flex-start;
52+
}
53+
54+
footer {
55+
border-top: 1px solid var(--color-surface-04);
56+
justify-content: flex-end;
57+
button {
58+
min-width: 100px !important;
59+
}
60+
}
61+
`;
62+
63+
export const DialogBody = styled.div`
64+
padding: 12px 6px;
65+
display: flex;
66+
flex-direction: column;
67+
gap: 6px;
68+
flex-grow: 1;
69+
overflow: auto;
70+
position: relative;
71+
`;

frontend/src/components/Dialog.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import clsx from 'clsx';
2+
import { useEffect, useRef } from 'react';
3+
4+
import { StyledDialog, DialogBody } from './Dialog.styled';
5+
6+
interface DialogProps {
7+
onHide: () => void;
8+
header?: React.ReactNode;
9+
footer?: React.ReactNode;
10+
children?: React.ReactNode;
11+
style?: React.CSSProperties;
12+
className?: string;
13+
headerStyle?: React.CSSProperties;
14+
bodyStyle?: React.CSSProperties;
15+
footerStyle?: React.CSSProperties;
16+
}
17+
18+
const Dialog = ({
19+
onHide,
20+
header,
21+
footer,
22+
children,
23+
style,
24+
className,
25+
headerStyle,
26+
bodyStyle,
27+
footerStyle,
28+
}: DialogProps) => {
29+
const dialogRef = useRef<HTMLDialogElement>(null);
30+
31+
useEffect(() => {
32+
if (!dialogRef.current) return;
33+
dialogRef.current.showModal();
34+
// Focus management is handled by the <dialog> element itself
35+
36+
const handleCancel = (event: Event) => {
37+
event.preventDefault();
38+
onHide();
39+
};
40+
41+
// Add event listener for the cancel event (when user attempts to close the dialog)
42+
dialogRef.current.addEventListener('cancel', handleCancel);
43+
44+
return () => {
45+
if (dialogRef.current)
46+
dialogRef.current.removeEventListener('cancel', handleCancel);
47+
};
48+
}, [onHide]);
49+
50+
const onShadeClick = (event: React.MouseEvent) => {
51+
// No need for this with native dialog, but keeping for custom hide logic
52+
if (event.currentTarget != event.target) return;
53+
if (!onHide) return;
54+
event.preventDefault();
55+
onHide();
56+
};
57+
58+
return (
59+
<StyledDialog
60+
className={clsx(className, 'enter-active')}
61+
style={style}
62+
ref={dialogRef}
63+
onClick={onShadeClick}
64+
onKeyDown={(event) => {
65+
if (event.key === 'Escape') onHide();
66+
}}
67+
>
68+
{header && <header style={headerStyle}>{header}</header>}
69+
<DialogBody style={bodyStyle}>{children}</DialogBody>
70+
{footer && <footer style={footerStyle}>{footer}</footer>}
71+
</StyledDialog>
72+
);
73+
};
74+
75+
export default Dialog;

frontend/src/components/Form.jsx renamed to frontend/src/components/Form.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ const Form = styled.div`
3636
}
3737
`;
3838

39-
const FormRow = ({ title, tooltip, section, children, ...props }) => {
39+
interface FormRowProps extends React.HTMLAttributes<HTMLDivElement> {
40+
title: string;
41+
tooltip?: string;
42+
section?: string;
43+
}
44+
45+
const FormRow = ({ title, tooltip, section, children, ...props }: FormRowProps) => {
4046
return (
4147
<>
4248
{section && <h3>{section}</h3>}

frontend/src/components/Icon.jsx renamed to frontend/src/components/Icon.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ const StyledIcon = styled.span`
55
user-drag: none !important;
66
`;
77

8-
const Icon = ({ icon, style }) => {
8+
interface IconProps {
9+
icon: string;
10+
style?: React.CSSProperties;
11+
}
12+
13+
const Icon = ({ icon, style }: IconProps) => {
914
return (
1015
<StyledIcon className="icon material-symbols-outlined" style={style}>
1116
{icon}
File renamed without changes.

frontend/src/components/InputColor.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useMemo } from 'react';
22
import styled from 'styled-components';
33

4-
import BaseInput from './BaseInput';
4+
import Input from './Input.styled';
55

6-
const BaseColorInput = styled(BaseInput)`
6+
const BaseColorInput = styled(Input)`
77
width: 30px;
88
`;
99

0 commit comments

Comments
 (0)