Automatic account sync with react
This commit is contained in:
		
							parent
							
								
									d666cab77a
								
							
						
					
					
						commit
						bb583eaa72
					
				
					 5 changed files with 81 additions and 57 deletions
				
			
		|  | @ -17,21 +17,17 @@ import {BrowserRouter, Outlet, Route, Routes, useOutletContext, useParams} from | |||
| import {expandUrl} from "../app/utils"; | ||||
| import ErrorBoundary from "./ErrorBoundary"; | ||||
| import routes from "./routes"; | ||||
| import {useAutoSubscribe, useBackgroundProcesses, useConnectionListeners} from "./hooks"; | ||||
| import {useAccountListener, useAutoSubscribe, useBackgroundProcesses, useConnectionListeners} from "./hooks"; | ||||
| import PublishDialog from "./PublishDialog"; | ||||
| import Messaging from "./Messaging"; | ||||
| import "./i18n"; // Translations!
 | ||||
| import {Backdrop, CircularProgress} from "@mui/material"; | ||||
| import Home from "./Home"; | ||||
| import Login from "./Login"; | ||||
| import i18n from "i18next"; | ||||
| import prefs from "../app/Prefs"; | ||||
| import session from "../app/Session"; | ||||
| import Pricing from "./Pricing"; | ||||
| import Signup from "./Signup"; | ||||
| import Account from "./Account"; | ||||
| import ResetPassword from "./ResetPassword"; | ||||
| import accountApi, {UnauthorizedError} from "../app/AccountApi"; | ||||
| 
 | ||||
| const App = () => { | ||||
|     return ( | ||||
|  | @ -87,43 +83,10 @@ const Layout = () => { | |||
|     }); | ||||
| 
 | ||||
|     useConnectionListeners(subscriptions, users); | ||||
|     useAccountListener(setAccount) | ||||
|     useBackgroundProcesses(); | ||||
|     useEffect(() => updateTitle(newNotificationsCount), [newNotificationsCount]); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         (async () => { | ||||
|             // TODO this should not live here
 | ||||
|             try { | ||||
|                 if (!session.token()) { | ||||
|                     return; | ||||
|                 } | ||||
|                 const remoteAccount = await accountApi.get(); | ||||
|                 setAccount(remoteAccount); | ||||
|                 if (remoteAccount.language) { | ||||
|                     await i18n.changeLanguage(remoteAccount.language); | ||||
|                 } | ||||
|                 if (remoteAccount.notification) { | ||||
|                     if (remoteAccount.notification.sound) { | ||||
|                         await prefs.setSound(remoteAccount.notification.sound); | ||||
|                     } | ||||
|                     if (remoteAccount.notification.delete_after) { | ||||
|                         await prefs.setDeleteAfter(remoteAccount.notification.delete_after); | ||||
|                     } | ||||
|                     if (remoteAccount.notification.min_priority) { | ||||
|                         await prefs.setMinPriority(remoteAccount.notification.min_priority); | ||||
|                     } | ||||
|                 } | ||||
|                 if (remoteAccount.subscriptions) { | ||||
|                     await subscriptionManager.syncFromRemote(remoteAccount.subscriptions); | ||||
|                 } | ||||
|             } catch (e) { | ||||
|                 console.log(`[App] Error fetching account`, e); | ||||
|                 if ((e instanceof UnauthorizedError)) { | ||||
|                     session.resetAndRedirect(routes.login); | ||||
|                 } | ||||
|             } | ||||
|         })(); | ||||
|     }, []); | ||||
|     return ( | ||||
|         <Box sx={{display: 'flex'}}> | ||||
|             <CssBaseline/> | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ import config from "../app/config"; | |||
| import ArticleIcon from '@mui/icons-material/Article'; | ||||
| import {Trans, useTranslation} from "react-i18next"; | ||||
| import session from "../app/Session"; | ||||
| import accountApi from "../app/AccountApi"; | ||||
| 
 | ||||
| const navWidth = 280; | ||||
| 
 | ||||
|  | @ -92,6 +93,11 @@ const NavList = (props) => { | |||
|        notifier.maybeRequestPermission(granted => props.onNotificationGranted(granted)) | ||||
|     }; | ||||
| 
 | ||||
|     const handleAccountClick = () => { | ||||
|         accountApi.sync(); // Dangle!
 | ||||
|         navigate(routes.account); | ||||
|     }; | ||||
| 
 | ||||
|     const showSubscriptionsList = props.subscriptions?.length > 0; | ||||
|     const showNotificationBrowserNotSupportedBox = !notifier.browserSupported(); | ||||
|     const showNotificationContextNotSupportedBox = notifier.browserSupported() && !notifier.contextSupported(); // Only show if notifications are generally supported in the browser
 | ||||
|  | @ -124,7 +130,7 @@ const NavList = (props) => { | |||
|                         <Divider sx={{my: 1}}/> | ||||
|                     </>} | ||||
|                 {session.exists() && | ||||
|                     <ListItemButton onClick={() => navigate(routes.account)} selected={location.pathname === routes.account}> | ||||
|                     <ListItemButton onClick={handleAccountClick} selected={location.pathname === routes.account}> | ||||
|                         <ListItemIcon><Person/></ListItemIcon> | ||||
|                         <ListItemText primary={t("nav_button_account")}/> | ||||
|                     </ListItemButton> | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import { | |||
|     CardContent, | ||||
|     FormControl, | ||||
|     Select, | ||||
|     Stack, styled, | ||||
|     Stack, | ||||
|     Table, | ||||
|     TableBody, | ||||
|     TableCell, | ||||
|  | @ -482,6 +482,11 @@ const Reservations = () => { | |||
|     const [dialogKey, setDialogKey] = useState(0); | ||||
|     const [dialogOpen, setDialogOpen] = useState(false); | ||||
| 
 | ||||
|     if (!session.exists() || !account) { | ||||
|         return <></>; | ||||
|     } | ||||
|     const reservations = account.reservations || []; | ||||
| 
 | ||||
|     const handleAddClick = () => { | ||||
|         setDialogKey(prev => prev+1); | ||||
|         setDialogOpen(true); | ||||
|  | @ -495,6 +500,7 @@ const Reservations = () => { | |||
|         setDialogOpen(false); | ||||
|         try { | ||||
|             await accountApi.upsertAccess(reservation.topic, reservation.everyone); | ||||
|             await accountApi.sync(); | ||||
|             console.debug(`[Preferences] Added topic reservation`, reservation); | ||||
|         } catch (e) { | ||||
|             console.log(`[Preferences] Error topic reservation.`, e); | ||||
|  | @ -502,10 +508,6 @@ const Reservations = () => { | |||
|         // FIXME handle 401/403
 | ||||
|     }; | ||||
| 
 | ||||
|     if (!session.exists() || !account) { | ||||
|         return <></>; | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|         <Card sx={{ padding: 1 }} aria-label={t("prefs_reservations_title")}> | ||||
|             <CardContent sx={{ paddingBottom: 1 }}> | ||||
|  | @ -515,7 +517,7 @@ const Reservations = () => { | |||
|                 <Paragraph> | ||||
|                     {t("prefs_reservations_description")} | ||||
|                 </Paragraph> | ||||
|                 {account.reservations.length > 0 && <ReservationsTable reservations={account.reservations}/>} | ||||
|                 {reservations.length > 0 && <ReservationsTable reservations={reservations}/>} | ||||
|             </CardContent> | ||||
|             <CardActions> | ||||
|                 <Button onClick={handleAddClick}>{t("prefs_reservations_add_button")}</Button> | ||||
|  | @ -523,7 +525,7 @@ const Reservations = () => { | |||
|                     key={`reservationAddDialog${dialogKey}`} | ||||
|                     open={dialogOpen} | ||||
|                     reservation={null} | ||||
|                     reservations={account.reservations} | ||||
|                     reservations={reservations} | ||||
|                     onCancel={handleDialogCancel} | ||||
|                     onSubmit={handleDialogSubmit} | ||||
|                 /> | ||||
|  | @ -552,6 +554,7 @@ const ReservationsTable = (props) => { | |||
|         setDialogOpen(false); | ||||
|         try { | ||||
|             await accountApi.upsertAccess(reservation.topic, reservation.everyone); | ||||
|             await accountApi.sync(); | ||||
|             console.debug(`[Preferences] Added topic reservation`, reservation); | ||||
|         } catch (e) { | ||||
|             console.log(`[Preferences] Error topic reservation.`, e); | ||||
|  | @ -562,6 +565,7 @@ const ReservationsTable = (props) => { | |||
|     const handleDeleteClick = async (reservation) => { | ||||
|         try { | ||||
|             await accountApi.deleteAccess(reservation.topic); | ||||
|             await accountApi.sync(); | ||||
|             console.debug(`[Preferences] Deleted topic reservation`, reservation); | ||||
|         } catch (e) { | ||||
|             console.log(`[Preferences] Error topic reservation.`, e); | ||||
|  |  | |||
|  | @ -96,3 +96,15 @@ export const useBackgroundProcesses = () => { | |||
|         accountApi.startWorker(); | ||||
|     }, []); | ||||
| } | ||||
| 
 | ||||
| export const useAccountListener = (setAccount) => { | ||||
|     useEffect(() => { | ||||
|         accountApi.registerListener(setAccount); | ||||
|         (async () => { | ||||
|             await accountApi.sync(); | ||||
|         })(); | ||||
|         return () => { | ||||
|             accountApi.registerListener(); | ||||
|         } | ||||
|     }, []); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue