Conn state listener, click action button
This commit is contained in:
		
							parent
							
								
									3bce0ad4ae
								
							
						
					
					
						commit
						5878d7e5a6
					
				
					 8 changed files with 120 additions and 27 deletions
				
			
		|  | @ -23,11 +23,8 @@ import userManager from "../app/UserManager"; | |||
| // TODO make default server functional
 | ||||
| // TODO routing
 | ||||
| // TODO embed into ntfy server
 | ||||
| // TODO connection indicator in subscription list
 | ||||
| 
 | ||||
| const App = () => { | ||||
|     console.log(`[App] Rendering main view`); | ||||
| 
 | ||||
|     const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false); | ||||
|     const [prefsOpen, setPrefsOpen] = useState(false); | ||||
|     const [selectedSubscription, setSelectedSubscription] = useState(null); | ||||
|  | @ -75,18 +72,26 @@ const App = () => { | |||
|         setTimeout(() => load(), 5000); | ||||
|     }, [/* initial render */]); | ||||
|     useEffect(() => { | ||||
|         const notificationClickFallback = (subscription) => setSelectedSubscription(subscription); | ||||
|         const handleNotification = async (subscriptionId, notification) => { | ||||
|             try { | ||||
|                 const added = await subscriptionManager.addNotification(subscriptionId, notification); | ||||
|                 if (added) { | ||||
|                     await notificationManager.notify(subscriptionId, notification, notificationClickFallback) | ||||
|                     const defaultClickAction = (subscription) => setSelectedSubscription(subscription); | ||||
|                     await notificationManager.notify(subscriptionId, notification, defaultClickAction) | ||||
|                 } | ||||
|             } catch (e) { | ||||
|                 console.error(`[App] Error handling notification`, e); | ||||
|             } | ||||
|         }; | ||||
|         connectionManager.refresh(subscriptions, users, handleNotification); // Dangle
 | ||||
|         connectionManager.registerStateListener(subscriptionManager.updateState); | ||||
|         connectionManager.registerNotificationListener(handleNotification); | ||||
|         return () => { | ||||
|             connectionManager.resetStateListener(); | ||||
|             connectionManager.resetNotificationListener(); | ||||
|         } | ||||
|     }, [/* initial render */]); | ||||
|     useEffect(() => { | ||||
|         connectionManager.refresh(subscriptions, users); // Dangle
 | ||||
|     }, [subscriptions, users]); | ||||
|     useEffect(() => { | ||||
|         const subscriptionId = (selectedSubscription) ? selectedSubscription.id : ""; | ||||
|  |  | |||
|  | @ -11,10 +11,11 @@ import List from "@mui/material/List"; | |||
| import SettingsIcon from "@mui/icons-material/Settings"; | ||||
| import AddIcon from "@mui/icons-material/Add"; | ||||
| import SubscribeDialog from "./SubscribeDialog"; | ||||
| import {Alert, AlertTitle, ListSubheader} from "@mui/material"; | ||||
| import {Alert, AlertTitle, CircularProgress, ListSubheader} from "@mui/material"; | ||||
| import Button from "@mui/material/Button"; | ||||
| import Typography from "@mui/material/Typography"; | ||||
| import {topicShortUrl} from "../app/utils"; | ||||
| import {ConnectionState} from "../app/Connection"; | ||||
| 
 | ||||
| const navWidth = 240; | ||||
| 
 | ||||
|  | @ -117,19 +118,29 @@ const SubscriptionList = (props) => { | |||
|     return ( | ||||
|         <> | ||||
|             {props.subscriptions.map(subscription => | ||||
|                 <ListItemButton | ||||
|                 <SubscriptionItem | ||||
|                     key={subscription.id} | ||||
|                     onClick={() => props.onSubscriptionClick(subscription.id)} | ||||
|                     subscription={subscription} | ||||
|                     selected={props.selectedSubscription && !props.prefsOpen && props.selectedSubscription.id === subscription.id} | ||||
|                 > | ||||
|                     <ListItemIcon><ChatBubbleOutlineIcon /></ListItemIcon> | ||||
|                     <ListItemText primary={topicShortUrl(subscription.baseUrl, subscription.topic)}/> | ||||
|                 </ListItemButton> | ||||
|             )} | ||||
|                     onClick={() => props.onSubscriptionClick(subscription.id)} | ||||
|             />)} | ||||
|         </> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| const SubscriptionItem = (props) => { | ||||
|     const subscription = props.subscription; | ||||
|     const icon = (subscription.state === ConnectionState.Connecting) | ||||
|         ? <CircularProgress size="24px"/> | ||||
|         : <ChatBubbleOutlineIcon/>; | ||||
|     return ( | ||||
|         <ListItemButton onClick={props.onClick} selected={props.selected}> | ||||
|             <ListItemIcon>{icon}</ListItemIcon> | ||||
|             <ListItemText primary={topicShortUrl(subscription.baseUrl, subscription.topic)}/> | ||||
|         </ListItemButton> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const PermissionAlert = (props) => { | ||||
|     return ( | ||||
|         <> | ||||
|  |  | |||
|  | @ -4,7 +4,15 @@ import Card from "@mui/material/Card"; | |||
| import Typography from "@mui/material/Typography"; | ||||
| import * as React from "react"; | ||||
| import {useState} from "react"; | ||||
| import {formatBytes, formatMessage, formatShortDateTime, formatTitle, topicShortUrl, unmatchedTags} from "../app/utils"; | ||||
| import { | ||||
|     formatBytes, | ||||
|     formatMessage, | ||||
|     formatShortDateTime, | ||||
|     formatTitle, | ||||
|     openUrl, | ||||
|     topicShortUrl, | ||||
|     unmatchedTags | ||||
| } from "../app/utils"; | ||||
| import IconButton from "@mui/material/IconButton"; | ||||
| import CloseIcon from '@mui/icons-material/Close'; | ||||
| import {LightboxBackdrop, Paragraph, VerticallyCenteredContainer} from "./styles"; | ||||
|  | @ -49,6 +57,9 @@ const NotificationItem = (props) => { | |||
|         await subscriptionManager.deleteNotification(notification.id) | ||||
|     } | ||||
|     const expired = attachment && attachment.expires && attachment.expires < Date.now()/1000; | ||||
|     const showAttachmentActions = attachment && !expired; | ||||
|     const showClickAction = notification.click; | ||||
|     const showActions = showAttachmentActions || showClickAction; | ||||
|     return ( | ||||
|         <Card sx={{ minWidth: 275, padding: 1 }}> | ||||
|             <CardContent> | ||||
|  | @ -69,10 +80,13 @@ const NotificationItem = (props) => { | |||
|                 {attachment && <Attachment attachment={attachment}/>} | ||||
|                 {tags && <Typography sx={{ fontSize: 14 }} color="text.secondary">Tags: {tags}</Typography>} | ||||
|             </CardContent> | ||||
|             {attachment && !expired && | ||||
|             {showActions && | ||||
|                 <CardActions sx={{paddingTop: 0}}> | ||||
|                     <Button onClick={() => navigator.clipboard.writeText(attachment.url)}>Copy URL</Button> | ||||
|                     <Button onClick={() => window.open(attachment.url)}>Open</Button> | ||||
|                     {showAttachmentActions && <> | ||||
|                         <Button onClick={() => navigator.clipboard.writeText(attachment.url)}>Copy URL</Button> | ||||
|                         <Button onClick={() => openUrl(attachment.url)}>Open attachment</Button> | ||||
|                     </>} | ||||
|                     {showClickAction && <Button onClick={() => openUrl(notification.click)}>Open link</Button>} | ||||
|                 </CardActions> | ||||
|             } | ||||
|         </Card> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue