Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
rework medialist and websockets
Browse files Browse the repository at this point in the history
  • Loading branch information
Gaisberg authored and Gaisberg committed Aug 19, 2024
1 parent cbfea6d commit 81000d4
Show file tree
Hide file tree
Showing 14 changed files with 464 additions and 374 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
"@testing-library/user-event": "^13.5.0",
"axios": "^1.7.2",
"install": "^0.13.0",
"lodash": "^4.17.21",
"npm": "^10.8.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-json-view": "^1.21.3",
"react-router-dom": "^6.25.1",
"react-scripts": "5.0.1",
"react-use-websocket": "^4.8.1",
"uuid": "^10.0.0",
"web-vitals": "^2.1.4"
},
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
import { AlertProvider } from './components/AlertContext';
import Content from './Content';
import { WebSocketProvider } from './components/WebSocketContext';
import EventAlert from './components/EventAlerts';

// Create a context
export const BackendContext = createContext();
Expand All @@ -16,7 +17,7 @@ function App() {
return localStorage.getItem('backendUrl') || '';
});

const [backendStatus, setBackendStatus] = useState(false);
const [backendStatus, setBackendStatus] = useState('stopped'); // Initial state


useEffect(() => {
Expand All @@ -28,6 +29,7 @@ function App() {
<BackendContext.Provider value={{ backendUrl, setBackendUrl, backendStatus, setBackendStatus }}>
<AlertProvider>
<WebSocketProvider>
<EventAlert />
<Router>
<div className="parent-container">
<div className="custom-scrollbar" style={{ overflow: 'hidden' }}>
Expand Down
22 changes: 12 additions & 10 deletions src/Content.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Content = () => {
return (
<div className="parent-container">
<AppBar position="static" />
{backendStatus ? (
{backendStatus === "running" && (
<Routes>
<Route path="/" element={<MediaList type="movie" />} />
<Route path="/movies" element={<MediaList type="movie" />} />
Expand All @@ -23,15 +23,17 @@ const Content = () => {
<Route path="/debug" element={<DebugPage />} />
<Route path="/settings" element={<SettingsPage />} />
</Routes>
) : (
<Box
display="flex"
justifyContent="center"
alignItems="center"
height="100vh">
<Typography variant="h6" color="textSecondary">
Backend is not connected
</Typography>
)}
{backendStatus === "paused" && (
<Routes>
<Route path="/" element={<SettingsPage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/debug" element={<DebugPage />} />
</Routes>
)}
{backendStatus === "stopped" && (
<Box display="flex" justifyContent="center" alignItems="center" height="100vh">
<Typography variant="h4">Cant connect to backend</Typography>
</Box>
)}
</div>
Expand Down
28 changes: 21 additions & 7 deletions src/components/AlertContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,46 @@ export const useAlert = () => useContext(AlertContext);
export const AlertProvider = ({ children }) => {
const [alerts, setAlerts] = useState([]);

const addAlert = (message, severity = 'info') => {
const addAlert = (message, severity = 'info', customComponent = null, sticky = false) => {
const id = uuidv4();
setAlerts((prevAlerts) => [
...prevAlerts,
{ id: uuidv4(), message, severity }, // Use UUID for unique IDs
{ id, message, severity, customComponent, sticky }, // Add sticky property to alert object
]);
return id; // Return the ID of the newly created alert
};

const updateAlert = (id, message, severity = 'info', customComponent = null, sticky = false) => {
setAlerts((prevAlerts) =>
prevAlerts.map((alert) =>
alert.id === id ? { ...alert, message, severity, customComponent, sticky } : alert
)
);
};

const removeAlert = (id) => {
setAlerts((prevAlerts) => prevAlerts.filter((alert) => alert.id !== id));
};

return (
<AlertContext.Provider value={{ addAlert }}>
<AlertContext.Provider value={{ addAlert, updateAlert }}>
{children}
{alerts.map((alert, index) => (
<Snackbar
key={alert.id}
open={true}
autoHideDuration={3000}
autoHideDuration={alert.sticky ? null : 3000} // Use sticky property to control autoHideDuration
onClose={() => removeAlert(alert.id)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
style={{ bottom: `${index * 60}px` }} // Adjust the offset based on the index
>
<Alert onClose={() => removeAlert(alert.id)} severity={alert.severity}>
{alert.message}
</Alert>
{alert.customComponent ? (
React.cloneElement(alert.customComponent, { onClose: () => removeAlert(alert.id) })
) : (
<Alert onClose={() => removeAlert(alert.id)} severity={alert.severity}>
{alert.message}
</Alert>
)}
</Snackbar>
))}
</AlertContext.Provider>
Expand Down
38 changes: 27 additions & 11 deletions src/components/AppBar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { useContext, useState } from 'react';
import { useContext, useState, useCallback } from 'react';
import { Link } from 'react-router-dom';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
Expand All @@ -21,22 +21,31 @@ import { isValidUrl } from '../utils/isValidUrl';
import Brightness4Icon from '@mui/icons-material/Brightness4';
import Brightness7Icon from '@mui/icons-material/Brightness7';
import '../styles.css'; // Import the styles.css file
import PauseCircleFilledRoundedIcon from '@mui/icons-material/PauseCircleFilledRounded';
import StopCircleRoundedIcon from '@mui/icons-material/StopCircleRounded';
import { debounce } from 'lodash'; // Import debounce from lodash


const pages = ['Movies', 'Shows', 'Settings', 'Debug'];

function ResponsiveAppBar() {
const { backendUrl, setBackendUrl, backendStatus } = useContext(BackendContext);
const { isDarkTheme, toggleTheme } = useContext(ThemeContext);
const [urlInput, setUrlInput] = useState(backendUrl);
const [anchorElNav, setAnchorElNav] = useState(null);

const handleUrlChange = (e) => {
const url = e.target.value;
setUrlInput(url);
if (isValidUrl(url)) {
const pages = backendStatus === 'running' ? ['Movies', 'Shows', 'Settings', 'Debug'] : ['Settings', 'Debug'];

const debouncedSetBackendUrl = useCallback(
debounce((url) => {
setBackendUrl(url);
}
}, 300), // Adjust the debounce delay as needed
[]
);

const handleUrlChange = (e) => {
const url = e.target.value;
setUrlInput(url);
debouncedSetBackendUrl(url);
};

const handleOpenNavMenu = (event) => {
Expand Down Expand Up @@ -148,19 +157,26 @@ function ResponsiveAppBar() {
placeholder="http://localhost:8000"
value={urlInput}
onChange={handleUrlChange}
error={backendStatus ? false : true}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<CheckBoxRoundedIcon color={backendStatus ? "success" : "error"} />
{backendStatus === 'running' &&
<CheckBoxRoundedIcon color="success" />
}
{backendStatus === 'paused' &&
<PauseCircleFilledRoundedIcon color="warning" />
}
{backendStatus === 'stopped' &&
<StopCircleRoundedIcon color="error" />
}
</InputAdornment>
),
}}
/>
</Box>
<IconButton sx={{ ml: 1 }} onClick={toggleTheme} color="inherit">
{/* <IconButton sx={{ ml: 1 }} onClick={toggleTheme} color="inherit">
{isDarkTheme ? <Brightness7Icon /> : <Brightness4Icon />}
</IconButton>
</IconButton> */}
</Toolbar>
</Container>
</AppBar>
Expand Down
45 changes: 45 additions & 0 deletions src/components/EventAlerts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useContext, useEffect, useState } from 'react';
import { WebSocketContext } from './WebSocketContext';
import { useAlert } from './AlertContext';
import { Box, Typography, LinearProgress, Alert } from '@mui/material';

const EventAlert = () => {
const { events } = useContext(WebSocketContext);
const { addAlert, updateAlert } = useAlert();
const [alertId, setAlertId] = useState(null);

useEffect(() => {
const totalEvents = events.running.length + events.queued.length;
const runningPercentage = (events.running.length / totalEvents) * 100;
const queuedPercentage = (events.queued.length / totalEvents) * 100;
const alertContent = (
<Alert>
<Typography variant="body1">
Running Events: {events.running.length}, Queued Events: {events.queued.length}
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', marginTop: 1 }}>
<Box sx={{ width: '100%', marginRight: 1 }}>
<LinearProgress variant="determinate" value={runningPercentage} sx={{ backgroundColor: '#e0e0e0', '& .MuiLinearProgress-bar': { backgroundColor: '#4caf50' } }} />
</Box>
<Box sx={{ width: '100%' }}>
<LinearProgress variant="determinate" value={queuedPercentage} sx={{ backgroundColor: '#e0e0e0', '& .MuiLinearProgress-bar': { backgroundColor: '#ff9800' } }} />
</Box>
</Box>
</Alert>
);

if (events.running.length > 0 || events.queued.length > 0) {
if (alertId) {
console.log("updating alert")
updateAlert(alertId, null, 'info', alertContent, true);
} else {
const newAlertId = addAlert(null, 'info', alertContent, true);
setAlertId(newAlertId);
}
}
}, [events, alertId]);

return null;
};

export default EventAlert;
Loading

0 comments on commit 81000d4

Please sign in to comment.