Split stuff
This commit is contained in:
		
							parent
							
								
									31e7aa24bc
								
							
						
					
					
						commit
						1fe598a966
					
				
					 5 changed files with 76 additions and 55 deletions
				
			
		|  | @ -3,38 +3,24 @@ import Container from '@mui/material/Container'; | ||||||
| import Typography from '@mui/material/Typography'; | import Typography from '@mui/material/Typography'; | ||||||
| import Box from '@mui/material/Box'; | import Box from '@mui/material/Box'; | ||||||
| import Link from '@mui/material/Link'; | import Link from '@mui/material/Link'; | ||||||
| import ProTip from './ProTip'; |  | ||||||
| import {useState} from "react"; | import {useState} from "react"; | ||||||
| 
 | import Subscription from './Subscription'; | ||||||
| function Copyright() { | import WsConnection from './WsConnection'; | ||||||
|     return ( |  | ||||||
|         <Typography variant="body2" color="text.secondary" align="center"> |  | ||||||
|             {'Copyright © '} |  | ||||||
|             <Link color="inherit" href="https://mui.com/"> |  | ||||||
|                 Your Website |  | ||||||
|             </Link>{' '} |  | ||||||
|             {new Date().getFullYear()} |  | ||||||
|             {'.'} |  | ||||||
|         </Typography> |  | ||||||
|     ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`; |  | ||||||
| const shortUrl = (url) => url.replaceAll(/https?:\/\//g, ""); |  | ||||||
| const shortTopicUrl = (baseUrl, topic) => shortUrl(topicUrl(baseUrl, topic)) |  | ||||||
| 
 | 
 | ||||||
| function SubscriptionList(props) { | function SubscriptionList(props) { | ||||||
|     return ( |     return ( | ||||||
|         <div className="subscriptionList"> |         <div className="subscriptionList"> | ||||||
|             {props.subscriptions.map(subscription => <SubscriptionItem key={topicUrl(subscription.base_url, subscription.topic)} {...subscription}/>)} |             {props.subscriptions.map(subscription => | ||||||
|  |                 <SubscriptionItem key={subscription.url} subscription={subscription}/>)} | ||||||
|         </div> |         </div> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function SubscriptionItem(props) { | function SubscriptionItem(props) { | ||||||
|  |     const subscription = props.subscription; | ||||||
|     return ( |     return ( | ||||||
|         <div> |         <div> | ||||||
|             <div>{shortTopicUrl(props.base_url, props.topic)}</div> |             <div>{subscription.shortUrl()}</div> | ||||||
|         </div> |         </div> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  | @ -49,7 +35,7 @@ function NotificationList(props) { | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function NotificationItem(props) { | const NotificationItem = (props) => { | ||||||
|     return ( |     return ( | ||||||
|         <div> |         <div> | ||||||
|             <div className="date">{props.time}</div> |             <div className="date">{props.time}</div> | ||||||
|  | @ -58,14 +44,14 @@ function NotificationItem(props) { | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function SubscriptionAddForm(props) { | const defaultBaseUrl = "https://ntfy.sh" | ||||||
|  | 
 | ||||||
|  | const SubscriptionAddForm = (props) => { | ||||||
|     const [topic, setTopic] = useState(""); |     const [topic, setTopic] = useState(""); | ||||||
|     const handleSubmit = (ev) => { |     const handleSubmit = (ev) => { | ||||||
|         ev.preventDefault(); |         ev.preventDefault(); | ||||||
|         props.onSubmit({ |         props.onSubmit(new Subscription(defaultBaseUrl, topic)); | ||||||
|             base_url: "https://ntfy.sh", |         setTopic(''); | ||||||
|             topic: topic, |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
|     return ( |     return ( | ||||||
|         <form onSubmit={handleSubmit}> |         <form onSubmit={handleSubmit}> | ||||||
|  | @ -80,19 +66,17 @@ function SubscriptionAddForm(props) { | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default function App() { | const App = () => { | ||||||
|     const [state, setState] = useState({ |     const [state, setState] = useState({ | ||||||
|         subscriptions: [], |         subscriptions: [], | ||||||
|     }); |     }); | ||||||
|     /*const subscriptions = [ |  | ||||||
|         {base_url: "https://ntfy.sh", topic: "mytopic"}, |  | ||||||
|         {base_url: "https://ntfy.sh", topic: "phils_alerts"}, |  | ||||||
|     ];*/ |  | ||||||
|     const notifications = [ |     const notifications = [ | ||||||
|         {id: "qGrfmhp3vK", times: 1645193395, message: "Message 1"}, |         {id: "qGrfmhp3vK", times: 1645193395, message: "Message 1"}, | ||||||
|         {id: "m4YYjfxwyT", times: 1645193428, message: "Message 2"} |         {id: "m4YYjfxwyT", times: 1645193428, message: "Message 2"} | ||||||
|     ]; |     ]; | ||||||
|     const addSubscription = (newSubscription) => { |     const addSubscription = (newSubscription) => { | ||||||
|  |         const connection = new WsConnection(newSubscription.wsUrl()); | ||||||
|  |         connection.start(); | ||||||
|         setState(prevState => ({ |         setState(prevState => ({ | ||||||
|             subscriptions: [...prevState.subscriptions, newSubscription], |             subscriptions: [...prevState.subscriptions, newSubscription], | ||||||
|         })); |         })); | ||||||
|  | @ -106,9 +90,9 @@ export default function App() { | ||||||
|                 <SubscriptionAddForm onSubmit={addSubscription}/> |                 <SubscriptionAddForm onSubmit={addSubscription}/> | ||||||
|                 <SubscriptionList subscriptions={state.subscriptions}/> |                 <SubscriptionList subscriptions={state.subscriptions}/> | ||||||
|                 <NotificationList notifications={notifications}/> |                 <NotificationList notifications={notifications}/> | ||||||
|                 <ProTip/> |  | ||||||
|                 <Copyright/> |  | ||||||
|             </Box> |             </Box> | ||||||
|         </Container> |         </Container> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export default App; | ||||||
|  |  | ||||||
|  | @ -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 ( |  | ||||||
|     <SvgIcon {...props}> |  | ||||||
|       <path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z" /> |  | ||||||
|     </SvgIcon> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default function ProTip() { |  | ||||||
|   return ( |  | ||||||
|     <Typography sx={{ mt: 6, mb: 3 }} color="text.secondary"> |  | ||||||
|       <LightBulbIcon sx={{ mr: 1, verticalAlign: 'middle' }} /> |  | ||||||
|       Pro tip: See more <Link href="https://mui.com/getting-started/templates/">templates</Link> on |  | ||||||
|       the MUI documentation. |  | ||||||
|     </Typography> |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
							
								
								
									
										19
									
								
								web/src/Subscription.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								web/src/Subscription.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -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); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								web/src/WsConnection.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								web/src/WsConnection.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -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(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								web/src/utils.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								web/src/utils.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -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)); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue