Skip to content

Commit

Permalink
Frontend 2.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Luligu committed Jan 1, 2025
1 parent e5e18bd commit 723f90e
Show file tree
Hide file tree
Showing 25 changed files with 438 additions and 260 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Matterbridge edge is now released. The default mode is still the normal mode to
The frontend has a new dark and light mode. The dark mode is now the default mode.
It is possible to change the mode (Classic, Dark or Light) in Settings, Matterbridge settings.

## [1.6.8-dev.21] - 2024-12-31
## [1.6.8-dev.22] - 2025-01-01

### Added

Expand All @@ -30,6 +30,7 @@ It is possible to change the mode (Classic, Dark or Light) in Settings, Matterbr
- [storage]: Added conversion for childbridge mode.
- [package]: Update README.md and README-SERVICE.md to include instructions for using SSL on port 443.
- [platform]: Added checkEndpointNumbers() to detect endpoint numbers changes.
- [frontend]: Frontend v.2.2.1
- [frontend]: Added dark and light mode to the frontend. Dark mode is now the default mode. It is possible to change the mode in Settings, Matterbridge settings.
- [frontend]: Custom rfjsreact-jsonschema-form for the config editor.
- [unregister]: Added unregister for Matterbridge edge.
Expand Down
12 changes: 6 additions & 6 deletions frontend/build/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"files": {
"main.css": "./static/css/main.2196886d.css",
"main.js": "./static/js/main.96010f0a.js",
"main.css": "./static/css/main.c6d8f9ea.css",
"main.js": "./static/js/main.04b8a114.js",
"static/js/453.abd36b29.chunk.js": "./static/js/453.abd36b29.chunk.js",
"static/media/roboto-latin-700-normal.woff2": "./static/media/roboto-latin-700-normal.4535474e1cf8598695ad.woff2",
"static/media/roboto-latin-500-normal.woff2": "./static/media/roboto-latin-500-normal.7077203b1982951ecf76.woff2",
Expand Down Expand Up @@ -60,12 +60,12 @@
"static/media/roboto-greek-ext-300-normal.woff": "./static/media/roboto-greek-ext-300-normal.b590dbe5c639944366d1.woff",
"static/media/roboto-greek-ext-400-normal.woff": "./static/media/roboto-greek-ext-400-normal.16eb83b4a3b1ea994243.woff",
"index.html": "./index.html",
"main.2196886d.css.map": "./static/css/main.2196886d.css.map",
"main.96010f0a.js.map": "./static/js/main.96010f0a.js.map",
"main.c6d8f9ea.css.map": "./static/css/main.c6d8f9ea.css.map",
"main.04b8a114.js.map": "./static/js/main.04b8a114.js.map",
"453.abd36b29.chunk.js.map": "./static/js/453.abd36b29.chunk.js.map"
},
"entrypoints": [
"static/css/main.2196886d.css",
"static/js/main.96010f0a.js"
"static/css/main.c6d8f9ea.css",
"static/js/main.04b8a114.js"
]
}
2 changes: 1 addition & 1 deletion frontend/build/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.96010f0a.js"></script><link href="./static/css/main.2196886d.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.04b8a114.js"></script><link href="./static/css/main.c6d8f9ea.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/build/static/js/main.04b8a114.js.map

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion frontend/build/static/js/main.96010f0a.js.map

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "frontend",
"version": "2.2.0",
"version": "2.2.1",
"private": true,
"homepage": "./",
"scripts": {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@
}

::-webkit-scrollbar-track {
background: var(--div-bg-color);
background: 'inherit';
/* var(--div-bg-color);*/
}

/* For Firefox (it uses scrollbar-color and scrollbar-width) */
Expand Down
1 change: 1 addition & 0 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ function LoginForm() {
onChange={e => setPassword(e.target.value)}
style={inputStyle}
placeholder="password"
autocomplete="current-password"
/>
<button type="submit" style={{ color: 'var(--main-button-color)', backgroundColor: 'var(--main-button-bg-color)', borderColor: 'var(--div-bg-color)' }}>Log in</button>
</div>
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/components/Devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React, { useEffect, useState, useContext } from 'react';

// Frontend
import { Connecting } from './Connecting';
import { OnlineContext } from './OnlineProvider';
import { WebSocketContext } from './WebSocketProvider';

function Devices() {
const [devices, setDevices] = useState([]);
Expand All @@ -15,15 +15,14 @@ function Devices() {
const [selectedPluginName, setSelectedPluginName] = useState('none'); // -1 no selection, 0 or greater for selected row
const [selectedDeviceEndpoint, setSelectedDeviceEndpoint] = useState('none'); // -1 no selection, 0 or greater for selected row
const [clusters, setClusters] = useState([]);
const { online } = useContext(OnlineContext);
const { online } = useContext(WebSocketContext);

useEffect(() => {
// Fetch Devices
fetch('./api/devices')
.then(response => response.json())
.then(data => setDevices(data))
.catch(error => console.error('Error fetching devices:', error));

}, []);

useEffect(() => {
Expand All @@ -32,7 +31,6 @@ function Devices() {
.then(response => response.json())
.then(data => setClusters(data))
.catch(error => console.error('Error fetching devices_clusters:', error));

}, [selectedDeviceEndpoint, selectedPluginName]);

const handleSort = (column) => {
Expand Down
118 changes: 71 additions & 47 deletions frontend/src/components/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,32 @@
// React
import React, { useEffect, useState, useRef, useContext, useMemo } from 'react';

// @mui
import { Dialog, DialogTitle, DialogContent, TextField, Alert, Snackbar, Tooltip, IconButton, Button, MenuItem, Menu, ThemeProvider } from '@mui/material';
import { DeleteForever, Download, Add, PublishedWithChanges, Settings, Favorite, Help, Announcement, QrCode2, MoreVert, Unpublished } from '@mui/icons-material';
// @mui/material
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import TextField from '@mui/material/TextField';
import Alert from '@mui/material/Alert';
import Snackbar from '@mui/material/Snackbar';
import Tooltip from '@mui/material/Tooltip';
import IconButton from '@mui/material/IconButton';
import Button from '@mui/material/Button';
import MenuItem from '@mui/material/MenuItem';
import Menu from '@mui/material/Menu';
import { ThemeProvider } from '@mui/material';

// @mui/icons-material
import DeleteForever from '@mui/icons-material/DeleteForever';
import Download from '@mui/icons-material/Download';
import Add from '@mui/icons-material/Add';
import PublishedWithChanges from '@mui/icons-material/PublishedWithChanges';
import Settings from '@mui/icons-material/Settings';
import Favorite from '@mui/icons-material/Favorite';
import Help from '@mui/icons-material/Help';
import Announcement from '@mui/icons-material/Announcement';
import QrCode2 from '@mui/icons-material/QrCode2';
import MoreVert from '@mui/icons-material/MoreVert';
import Unpublished from '@mui/icons-material/Unpublished';

// @rjsf
import Form from '@rjsf/mui';
Expand All @@ -20,7 +43,6 @@ import { sendCommandToMatterbridge } from './sendApiCommand';
import { WebSocketLogs } from './WebSocketLogs';
import { WebSocketContext } from './WebSocketProvider';
import { Connecting } from './Connecting';
import { OnlineContext } from './OnlineProvider';
import { SystemInfoTable } from './SystemInfoTable';
import { MatterbridgeInfoTable } from './MatterbridgeInfoTable';
import { ConfirmCancelForm } from './ConfirmCancelForm';
Expand All @@ -39,11 +61,10 @@ function Home() {
const [selectedPluginSchema, setSelectedPluginSchema] = useState({});
const [openSnack, setOpenSnack] = useState(false);
const [openConfig, setOpenConfig] = useState(false);
const [logFilterLevel, setLogFilterLevel] = useState(localStorage.getItem('logFilterLevel')??'info');
const [logFilterSearch, setLogFilterSearch] = useState(localStorage.getItem('logFilterSearch')??'*');
const [logFilterLevel] = useState(localStorage.getItem('logFilterLevel')??'info');
const [logFilterSearch] = useState(localStorage.getItem('logFilterSearch')??'*');

const { logMessage } = useContext(WebSocketContext);
const { online } = useContext(OnlineContext);
const { logMessage, addListener, removeListener, online, sendMessage } = useContext(WebSocketContext);

const refAddRemove = useRef(null);
const refRegisteredPlugins = useRef(null);
Expand Down Expand Up @@ -82,45 +103,11 @@ function Home() {
[]
);

const fetchSettings = () => {
// console.log('From home fetchSettings');

fetch('./api/settings')
.then(response => response.json())
.then(data => {
// console.log('From home /api/settings:', data);
if(data.matterbridgeInformation.bridgeMode==='bridge') {
setQrCode(data.matterbridgeInformation.matterbridgeQrPairingCode);
setPairingCode(data.matterbridgeInformation.matterbridgeManualPairingCode);
}
setSystemInfo(data.systemInformation);
setMatterbridgeInfo(data.matterbridgeInformation);
})
.catch(error => console.error('Error fetching settings:', error));

fetch('./api/plugins')
.then(response => response.json())
.then(data => {
// console.log('From home /api/plugins:', data)
setPlugins(data);
})
.catch(error => console.error('Error fetching plugins:', error));
};

useEffect(() => {
// Call fetchSettings immediately and then every 1 minute
fetchSettings();
const intervalId = setInterval(fetchSettings, 1 * 60 * 1000);

// Clear the interval when the component is unmounted
return () => clearInterval(intervalId);

}, []);

// Function to reload settings on demand
const reloadSettings = () => {
fetchSettings();
// console.log('reloadSettings');
console.log('reloadSettings');
sendMessage({ method: "/api/settings", src: "Frontend", dst: "Matterbridge", params: {} });
sendMessage({ method: "/api/plugins", src: "Frontend", dst: "Matterbridge", params: {} });
};

const handleSelectQRCode = (row) => {
Expand Down Expand Up @@ -234,6 +221,43 @@ function Home() {
setShowConfirmCancelForm(false);
};

const handleWebSocketMessage = (msg) => {
// console.log('Home Received WebSocket Message:', msg);
if (msg.src === 'Matterbridge' && msg.dst === 'Frontend') {
if (msg.method === 'refresh_required') {
console.log('Home received refresh_required');
reloadSettings();
}
if (msg.method === '/api/settings') {
console.log('Home received settings:', msg.response);
if(msg.response.matterbridgeInformation.bridgeMode==='bridge') {
setQrCode(msg.response.matterbridgeInformation.matterbridgeQrPairingCode);
setPairingCode(msg.response.matterbridgeInformation.matterbridgeManualPairingCode);
}
setSystemInfo(msg.response.systemInformation);
setMatterbridgeInfo(msg.response.matterbridgeInformation);
}
if (msg.method === '/api/plugins') {
console.log('Home received plugins:', msg.response);
setPlugins(msg.response);
}
}
};

useEffect(() => {
addListener(handleWebSocketMessage);
console.log('Home added WebSocket listener');
return () => {
removeListener(handleWebSocketMessage);
console.log('Home removed WebSocket listener');
};
}, [addListener, removeListener]);

useEffect(() => {
console.log('Home received online');
reloadSettings();
}, [online]);

if (!online) {
return ( <Connecting /> );
}
Expand Down Expand Up @@ -328,7 +352,7 @@ function Home() {
<div style={{ display: 'flex', flexDirection: 'row', flex: '1 1 auto', gap: '5px' }}>

<Snackbar anchorOrigin={{vertical: 'bottom', horizontal: 'right'}} open={openSnack} onClose={handleSnackClose} autoHideDuration={10000}>
<Alert onClose={handleSnackClose} severity="info" variant="filled" sx={{ width: '100%', bgcolor: '#4CAF50' }}>Restart needed!</Alert>
<Alert onClose={handleSnackClose} severity="info" variant="filled" sx={{ width: '100%', bgcolor: 'var(--primary-color)' }}>Restart needed!</Alert>
</Snackbar>
{plugin.error ?
<>
Expand Down Expand Up @@ -428,7 +452,7 @@ function AddRemovePlugins({ reloadSettings }) {
return (
<div style={{ display: 'flex', flexDirection: 'row', flex: '1 1 auto', alignItems: 'center', justifyContent: 'space-between', margin: '0px', padding: '10px', gap: '20px' }}>
<Snackbar anchorOrigin={{vertical: 'bottom', horizontal: 'right'}} open={open} onClose={handleSnackClose} autoHideDuration={5000}>
<Alert onClose={handleSnackClose} severity="info" variant="filled" sx={{ width: '100%', bgcolor: '#4CAF50' }}>Restart required</Alert>
<Alert onClose={handleSnackClose} severity="info" variant="filled" sx={{ width: '100%', bgcolor: 'var(--primary-color)' }}>Restart required</Alert>
</Snackbar>
<TextField value={pluginName} onChange={(event) => { setPluginName(event.target.value); }} size="small" id="plugin-name" label="Plugin name or plugin path" variant="outlined" fullWidth/>
<IconButton onClick={handleClickVertical}>
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/components/Logs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ import Select from '@mui/material/Select';
import { WebSocketLogs } from './WebSocketLogs';
import { WebSocketContext } from './WebSocketProvider';
import { Connecting } from './Connecting';
import { OnlineContext } from './OnlineProvider';

function Logs() {
const [logFilterLevel, setLogFilterLevel] = useState(localStorage.getItem('logFilterLevel')??'info');
const [logFilterSearch, setLogFilterSearch] = useState(localStorage.getItem('logFilterSearch')??'*');
const { setLogFilters } = useContext(WebSocketContext);
const { online } = useContext(OnlineContext);
const { setLogFilters, online } = useContext(WebSocketContext);

const handleChangeLevel = (event) => {
setLogFilterLevel(event.target.value);
Expand Down
46 changes: 42 additions & 4 deletions frontend/src/components/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,29 @@
// React
import React, { useState, useEffect, useContext } from 'react';

// @mui
import { Snackbar, Alert, Radio, RadioGroup, FormControlLabel, FormLabel, TextField, Select, MenuItem, Checkbox, Box } from '@mui/material';
// @mui/material
import Snackbar from '@mui/material/Snackbar';
import Alert from '@mui/material/Alert';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormLabel from '@mui/material/FormLabel';
import TextField from '@mui/material/TextField';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import Checkbox from '@mui/material/Checkbox';
import Box from '@mui/material/Box';

// Frontend
import { sendCommandToMatterbridge } from './sendApiCommand';
import { Connecting } from './Connecting';
import { OnlineContext } from './OnlineProvider';
import { WebSocketContext } from './WebSocketProvider';

function Settings() {
const { online, matterbridgeInfo } = useContext(OnlineContext);
const { online, addListener, removeListener, sendMessage } = useContext(WebSocketContext);
const [showSnackbar, setShowSnackbar] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState('');
const [matterbridgeInfo, setMatterbridgeInfo] = useState({});

const handleSnackbarClose = () => {
setShowSnackbar(false);
Expand All @@ -29,6 +40,33 @@ function Settings() {
}, timeout * 1000);
};

const handleWebSocketMessage = (msg) => {
if (msg.src === 'Matterbridge' && msg.dst === 'Frontend') {
if (msg.method === 'refresh_required') {
console.log('Settings received refresh_required');
sendMessage({ method: "/api/settings", src: "Frontend", dst: "Matterbridge", params: {} });
}
if (msg.method === '/api/settings') {
console.log('Settings received /api/settings:', msg.response);
setMatterbridgeInfo(msg.response.matterbridgeInformation);
}
}
};

useEffect(() => {
addListener(handleWebSocketMessage);
console.log('Settings added WebSocket listener');
return () => {
removeListener(handleWebSocketMessage);
console.log('Settings removed WebSocket listener');
};
}, [addListener, removeListener]);

useEffect(() => {
console.log('Settings received online');
sendMessage({ method: "/api/settings", src: "Frontend", dst: "Matterbridge", params: {} });
}, [online]);

if (!online) {
return ( <Connecting /> );
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/SystemInfoTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export function SystemInfoTable({ systemInfo, compact }) {
}

return (
<div className="MbfWindowDiv" style={{ minWidth: '302px' }}>
<div className="MbfWindowDivTable">
<table>
<div className="MbfWindowDiv" style={{ minWidth: '302px', overflow: 'hidden' }}>
<div className="MbfWindowDivTable" style={{ overflow: 'hidden' }}>
<table >
<thead>
<tr>
<th colSpan="2">System Information</th>
Expand Down
Loading

0 comments on commit 723f90e

Please sign in to comment.