From 1fe598a966d888d36d9dd18ab6e8ba1c51f33a77 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Fri, 18 Feb 2022 14:41:01 -0500 Subject: [PATCH] Split stuff --- web/src/App.js | 50 ++++++++++++++--------------------------- web/src/ProTip.js | 22 ------------------ web/src/Subscription.js | 19 ++++++++++++++++ web/src/WsConnection.js | 34 ++++++++++++++++++++++++++++ web/src/utils.js | 6 +++++ 5 files changed, 76 insertions(+), 55 deletions(-) delete mode 100644 web/src/ProTip.js create mode 100644 web/src/Subscription.js create mode 100644 web/src/WsConnection.js create mode 100644 web/src/utils.js diff --git a/web/src/App.js b/web/src/App.js index 7d52df94..d8c1c21f 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -3,38 +3,24 @@ import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import Link from '@mui/material/Link'; -import ProTip from './ProTip'; import {useState} from "react"; - -function Copyright() { - return ( - - {'Copyright © '} - - Your Website - {' '} - {new Date().getFullYear()} - {'.'} - - ); -} - -const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`; -const shortUrl = (url) => url.replaceAll(/https?:\/\//g, ""); -const shortTopicUrl = (baseUrl, topic) => shortUrl(topicUrl(baseUrl, topic)) +import Subscription from './Subscription'; +import WsConnection from './WsConnection'; function SubscriptionList(props) { return (
- {props.subscriptions.map(subscription => )} + {props.subscriptions.map(subscription => + )}
); } function SubscriptionItem(props) { + const subscription = props.subscription; return (
-
{shortTopicUrl(props.base_url, props.topic)}
+
{subscription.shortUrl()}
); } @@ -49,7 +35,7 @@ function NotificationList(props) { ); } -function NotificationItem(props) { +const NotificationItem = (props) => { return (
{props.time}
@@ -58,14 +44,14 @@ function NotificationItem(props) { ); } -function SubscriptionAddForm(props) { +const defaultBaseUrl = "https://ntfy.sh" + +const SubscriptionAddForm = (props) => { const [topic, setTopic] = useState(""); const handleSubmit = (ev) => { ev.preventDefault(); - props.onSubmit({ - base_url: "https://ntfy.sh", - topic: topic, - }); + props.onSubmit(new Subscription(defaultBaseUrl, topic)); + setTopic(''); } return (
@@ -80,19 +66,17 @@ function SubscriptionAddForm(props) { ); } -export default function App() { +const App = () => { const [state, setState] = useState({ subscriptions: [], }); - /*const subscriptions = [ - {base_url: "https://ntfy.sh", topic: "mytopic"}, - {base_url: "https://ntfy.sh", topic: "phils_alerts"}, - ];*/ const notifications = [ {id: "qGrfmhp3vK", times: 1645193395, message: "Message 1"}, {id: "m4YYjfxwyT", times: 1645193428, message: "Message 2"} ]; const addSubscription = (newSubscription) => { + const connection = new WsConnection(newSubscription.wsUrl()); + connection.start(); setState(prevState => ({ subscriptions: [...prevState.subscriptions, newSubscription], })); @@ -106,9 +90,9 @@ export default function App() { - - ); } + +export default App; diff --git a/web/src/ProTip.js b/web/src/ProTip.js deleted file mode 100644 index 6d81f33b..00000000 --- a/web/src/ProTip.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react'; -import Link from '@mui/material/Link'; -import SvgIcon from '@mui/material/SvgIcon'; -import Typography from '@mui/material/Typography'; - -function LightBulbIcon(props) { - return ( - - - - ); -} - -export default function ProTip() { - return ( - - - Pro tip: See more templates on - the MUI documentation. - - ); -} diff --git a/web/src/Subscription.js b/web/src/Subscription.js new file mode 100644 index 00000000..7b517d4d --- /dev/null +++ b/web/src/Subscription.js @@ -0,0 +1,19 @@ +import {topicUrl, shortTopicUrl, topicUrlWs} from './utils'; + +export default class Subscription { + url = ''; + baseUrl = ''; + topic = ''; + notifications = []; + constructor(baseUrl, topic) { + this.url = topicUrl(baseUrl, topic); + this.baseUrl = baseUrl; + this.topic = topic; + } + wsUrl() { + return topicUrlWs(this.baseUrl, this.topic); + } + shortUrl() { + return shortTopicUrl(this.baseUrl, this.topic); + } +} diff --git a/web/src/WsConnection.js b/web/src/WsConnection.js new file mode 100644 index 00000000..c9d7eb3c --- /dev/null +++ b/web/src/WsConnection.js @@ -0,0 +1,34 @@ + +export default class WsConnection { + constructor(url) { + this.url = url; + this.ws = null; + } + start() { + const socket = new WebSocket(this.url); + socket.onopen = function(e) { + console.log(this.url, "[open] Connection established"); + }; + socket.onmessage = function(event) { + console.log(this.url, `[message] Data received from server: ${event.data}`); + }; + socket.onclose = function(event) { + if (event.wasClean) { + console.log(this.url, `[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`); + } else { + console.log(this.url, `[close] Connection died`); + // e.g. server process killed or network down + // event.code is usually 1006 in this case + } + }; + socket.onerror = function(error) { + console.log(this.url, `[error] ${error.message}`); + }; + this.ws = socket; + } + cancel() { + if (this.ws != null) { + this.ws.close(); + } + } +} diff --git a/web/src/utils.js b/web/src/utils.js new file mode 100644 index 00000000..b902a7e5 --- /dev/null +++ b/web/src/utils.js @@ -0,0 +1,6 @@ +export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`; +export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws` + .replaceAll("https://", "wss://") + .replaceAll("http://", "ws://"); +export const shortUrl = (url) => url.replaceAll(/https?:\/\//g, ""); +export const shortTopicUrl = (baseUrl, topic) => shortUrl(topicUrl(baseUrl, topic));