From dd1a85e733b04f85e203333b7fda4f21563a9304 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 20 Feb 2022 20:04:03 -0500 Subject: [PATCH] Awful use of localstorage --- web/src/app/Storage.js | 37 +++++++++++++++++++++++++++++++++++++ web/src/app/WsConnection.js | 6 +++--- web/src/components/App.js | 37 +++++++++++++++++++++++++++++++------ 3 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 web/src/app/Storage.js diff --git a/web/src/app/Storage.js b/web/src/app/Storage.js new file mode 100644 index 0000000..b591c0d --- /dev/null +++ b/web/src/app/Storage.js @@ -0,0 +1,37 @@ +import {topicUrl} from "./utils"; +import Subscription from "./Subscription"; + +const LocalStorage = { + getSubscriptions() { + const subscriptions = {}; + const rawSubscriptions = localStorage.getItem('subscriptions'); + if (rawSubscriptions === null) { + return {}; + } + try { + const serializedSubscriptions = JSON.parse(rawSubscriptions); + serializedSubscriptions.forEach(s => { + const subscription = new Subscription(s.baseUrl, s.topic); + subscription.notifications = s.notifications; + subscriptions[topicUrl(s.baseUrl, s.topic)] = subscription; + }); + return subscriptions; + } catch (e) { + console.log("LocalStorage", `Unable to deserialize subscriptions: ${e.message}`) + return {}; + } + }, + saveSubscriptions(subscriptions) { + const serializedSubscriptions = Object.keys(subscriptions).map(k => { + const subscription = subscriptions[k]; + return { + baseUrl: subscription.baseUrl, + topic: subscription.topic, + notifications: subscription.notifications + } + }); + localStorage.setItem('subscriptions', JSON.stringify(serializedSubscriptions)); + } +}; + +export default LocalStorage; diff --git a/web/src/app/WsConnection.js b/web/src/app/WsConnection.js index 4e9dfaf..6b39fa2 100644 --- a/web/src/app/WsConnection.js +++ b/web/src/app/WsConnection.js @@ -1,10 +1,10 @@ export default class WsConnection { id = ''; - constructor(subscription, onNotification) { + constructor(subscription, onChange) { this.id = subscription.id; this.subscription = subscription; - this.onNotification = onNotification; + this.onChange = onChange; this.ws = null; } start() { @@ -26,7 +26,7 @@ export default class WsConnection { } console.log('adding') this.subscription.addNotification(data); - this.onNotification(this.subscription); + this.onChange(this.subscription); } catch (e) { console.log(this.id, `[message] Error handling message: ${e}`); } diff --git a/web/src/components/App.js b/web/src/components/App.js index a60a16b..7df7691 100644 --- a/web/src/components/App.js +++ b/web/src/components/App.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import {useState} from 'react'; +import {useEffect, useState} from 'react'; import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; @@ -27,6 +27,7 @@ import Card from "@mui/material/Card"; import {CardContent, Stack} from "@mui/material"; import AddDialog from "./AddDialog"; import theme from "./theme"; +import LocalStorage from "../app/Storage"; const drawerWidth = 240; @@ -130,32 +131,56 @@ const NotificationItem = (props) => { } const App = () => { + console.log("Launching App component"); + const [drawerOpen, setDrawerOpen] = useState(true); - const [subscriptions, setSubscriptions] = useState({}); - const [selectedSubscription, setSelectedSubscription] = useState(null); + const [subscriptions, setSubscriptions] = useState(LocalStorage.getSubscriptions()); const [connections, setConnections] = useState({}); + const [selectedSubscription, setSelectedSubscription] = useState(null); const [addDialogOpen, setAddDialogOpen] = useState(false); const subscriptionChanged = (subscription) => { setSubscriptions(prev => ({...prev, [subscription.id]: subscription})); // Fake-replace }; const handleAddSubmit = (subscription) => { - setAddDialogOpen(false); const connection = new WsConnection(subscription, subscriptionChanged); + setAddDialogOpen(false); setSubscriptions(prev => ({...prev, [subscription.id]: subscription})); - setConnections(prev => ({...prev, [connection.id]: connection})); + setConnections(prev => ({...prev, [subscription.id]: connection})); connection.start(); }; const handleAddCancel = () => { + console.log(`Cancel clicked`) setAddDialogOpen(false); } const handleSubscriptionClick = (subscriptionId) => { - console.log(`handleSubscriptionClick ${subscriptionId}`) + console.log(`Selected subscription ${subscriptionId}`) setSelectedSubscription(subscriptions[subscriptionId]); }; const notifications = (selectedSubscription !== null) ? selectedSubscription.notifications : []; const toggleDrawer = () => { setDrawerOpen(!drawerOpen); }; + useEffect(() => { + console.log("Starting connections"); + Object.keys(subscriptions).forEach(topicUrl => { + console.log(`Starting connection for ${topicUrl}`); + const subscription = subscriptions[topicUrl]; + const connection = new WsConnection(subscription, subscriptionChanged); + connection.start(); + }); + return () => { + console.log("Stopping connections"); + Object.keys(connections).forEach(topicUrl => { + console.log(`Stopping connection for ${topicUrl}`); + const connection = connections[topicUrl]; + connection.cancel(); + }); + }; + }, [/* only on initial render */]); + useEffect(() => { + console.log(`Saving subscriptions`); + LocalStorage.saveSubscriptions(subscriptions); + }, [subscriptions]); return (