ntfy/web/src/components/App.js

121 lines
5.2 KiB
JavaScript
Raw Normal View History

2022-02-18 14:49:51 +00:00
import * as React from 'react';
2022-02-21 01:04:03 +00:00
import {useEffect, useState} from 'react';
2022-02-18 14:49:51 +00:00
import Box from '@mui/material/Box';
2022-02-25 01:18:46 +00:00
import {ThemeProvider} from '@mui/material/styles';
2022-02-20 00:48:33 +00:00
import CssBaseline from '@mui/material/CssBaseline';
import Toolbar from '@mui/material/Toolbar';
2022-02-21 21:24:13 +00:00
import NotificationList from "./NotificationList";
2022-02-20 03:26:58 +00:00
import theme from "./theme";
import api from "../app/Api";
import repository from "../app/Repository";
import connectionManager from "../app/ConnectionManager";
import Subscriptions from "../app/Subscriptions";
2022-02-25 17:46:22 +00:00
import Navigation from "./Navigation";
import ActionBar from "./ActionBar";
import Users from "../app/Users";
2022-02-25 01:18:46 +00:00
2022-02-18 19:41:01 +00:00
const App = () => {
console.log(`[App] Rendering main view`);
2022-02-21 01:04:03 +00:00
2022-02-25 01:18:46 +00:00
const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false);
const [subscriptions, setSubscriptions] = useState(new Subscriptions());
const [users, setUsers] = useState(new Users());
2022-02-21 01:04:03 +00:00
const [selectedSubscription, setSelectedSubscription] = useState(null);
const handleNotification = (subscriptionId, notification) => {
setSubscriptions(prev => {
const newSubscription = prev.get(subscriptionId).addNotification(notification);
return prev.update(newSubscription).clone();
});
};
const handleSubscribeSubmit = (subscription, user) => {
console.log(`[App] New subscription: ${subscription.id}`);
if (user !== null) {
setUsers(prev => prev.add(user).clone());
}
setSubscriptions(prev => prev.add(subscription).clone());
2022-02-23 04:22:30 +00:00
setSelectedSubscription(subscription);
api.poll(subscription.baseUrl, subscription.topic, user)
2022-02-23 04:22:30 +00:00
.then(messages => {
setSubscriptions(prev => {
const newSubscription = prev.get(subscription.id).addNotifications(messages);
return prev.update(newSubscription).clone();
});
2022-02-23 04:22:30 +00:00
});
};
const handleDeleteNotification = (subscriptionId, notificationId) => {
console.log(`[App] Deleting notification ${notificationId} from ${subscriptionId}`);
setSubscriptions(prev => {
const newSubscription = prev.get(subscriptionId).deleteNotification(notificationId);
return prev.update(newSubscription).clone();
});
};
const handleDeleteAllNotifications = (subscriptionId) => {
2022-02-24 17:26:07 +00:00
console.log(`[App] Deleting all notifications from ${subscriptionId}`);
setSubscriptions(prev => {
const newSubscription = prev.get(subscriptionId).deleteAllNotifications();
return prev.update(newSubscription).clone();
});
};
const handleUnsubscribe = (subscriptionId) => {
console.log(`[App] Unsubscribing from ${subscriptionId}`);
2022-02-23 03:10:50 +00:00
setSubscriptions(prev => {
const newSubscriptions = prev.remove(subscriptionId).clone();
setSelectedSubscription(newSubscriptions.firstOrNull());
2022-02-23 03:10:50 +00:00
return newSubscriptions;
});
};
2022-02-24 20:17:47 +00:00
useEffect(() => {
setSubscriptions(repository.loadSubscriptions());
setUsers(repository.loadUsers());
2022-02-24 20:17:47 +00:00
}, [/* initial render only */]);
2022-02-21 01:04:03 +00:00
useEffect(() => {
connectionManager.refresh(subscriptions, users, handleNotification);
repository.saveSubscriptions(subscriptions);
repository.saveUsers(users);
}, [subscriptions, users]);
2022-02-18 14:49:51 +00:00
return (
2022-02-20 03:26:58 +00:00
<ThemeProvider theme={theme}>
2022-02-25 01:18:46 +00:00
<CssBaseline/>
<Box sx={{display: 'flex'}}>
<CssBaseline/>
<ActionBar
selectedSubscription={selectedSubscription}
users={users}
onClearAll={handleDeleteAllNotifications}
2022-02-25 01:18:46 +00:00
onUnsubscribe={handleUnsubscribe}
onMobileDrawerToggle={() => setMobileDrawerOpen(!mobileDrawerOpen)}
/>
2022-02-25 17:46:22 +00:00
<Box component="nav" sx={{width: {sm: Navigation.width}, flexShrink: {sm: 0}}}>
<Navigation
2022-02-25 01:18:46 +00:00
subscriptions={subscriptions}
selectedSubscription={selectedSubscription}
mobileDrawerOpen={mobileDrawerOpen}
onMobileDrawerToggle={() => setMobileDrawerOpen(!mobileDrawerOpen)}
onSubscriptionClick={(subscriptionId) => setSelectedSubscription(subscriptions.get(subscriptionId))}
onSubscribeSubmit={handleSubscribeSubmit}
/>
</Box>
2022-02-20 00:48:33 +00:00
<Box
component="main"
sx={{
flexGrow: 1,
2022-02-25 01:18:46 +00:00
p: 3,
2022-02-25 17:46:22 +00:00
width: {sm: `calc(100% - ${Navigation.width}px)`},
2022-02-20 00:48:33 +00:00
height: '100vh',
overflow: 'auto',
2022-02-25 01:18:46 +00:00
backgroundColor: (theme) => theme.palette.mode === 'light' ? theme.palette.grey[100] : theme.palette.grey[900]
}}>
<Toolbar/>
{selectedSubscription !== null &&
<NotificationList
subscription={selectedSubscription}
onDeleteNotification={handleDeleteNotification}
/>}
2022-02-20 00:48:33 +00:00
</Box>
2022-02-18 14:49:51 +00:00
</Box>
2022-02-20 00:48:33 +00:00
</ThemeProvider>
2022-02-18 14:49:51 +00:00
);
}
2022-02-18 19:41:01 +00:00
export default App;