diff --git a/web/src/app/AccountApi.js b/web/src/app/AccountApi.js index 4a143dd..94f638d 100644 --- a/web/src/app/AccountApi.js +++ b/web/src/app/AccountApi.js @@ -256,25 +256,25 @@ class AccountApi { return null; } console.log(`[AccountApi] Syncing account`); - const remoteAccount = await this.get(); - if (remoteAccount.language) { - await i18n.changeLanguage(remoteAccount.language); + const account = await this.get(); + if (account.language) { + await i18n.changeLanguage(account.language); } - if (remoteAccount.notification) { - if (remoteAccount.notification.sound) { - await prefs.setSound(remoteAccount.notification.sound); + if (account.notification) { + if (account.notification.sound) { + await prefs.setSound(account.notification.sound); } - if (remoteAccount.notification.delete_after) { - await prefs.setDeleteAfter(remoteAccount.notification.delete_after); + if (account.notification.delete_after) { + await prefs.setDeleteAfter(account.notification.delete_after); } - if (remoteAccount.notification.min_priority) { - await prefs.setMinPriority(remoteAccount.notification.min_priority); + if (account.notification.min_priority) { + await prefs.setMinPriority(account.notification.min_priority); } } - if (remoteAccount.subscriptions) { - await subscriptionManager.syncFromRemote(remoteAccount.subscriptions); + if (account.subscriptions) { + await subscriptionManager.syncFromRemote(account.subscriptions, account.reservations); } - return remoteAccount; + return account; } catch (e) { console.log(`[AccountApi] Error fetching account`, e); if ((e instanceof UnauthorizedError)) { diff --git a/web/src/app/SubscriptionManager.js b/web/src/app/SubscriptionManager.js index c87159d..0733088 100644 --- a/web/src/app/SubscriptionManager.js +++ b/web/src/app/SubscriptionManager.js @@ -35,7 +35,7 @@ class SubscriptionManager { return subscription; } - async syncFromRemote(remoteSubscriptions) { + async syncFromRemote(remoteSubscriptions, remoteReservations) { console.log(`[SubscriptionManager] Syncing subscriptions from remote`, remoteSubscriptions); // Add remote subscriptions @@ -43,8 +43,10 @@ class SubscriptionManager { for (let i = 0; i < remoteSubscriptions.length; i++) { const remote = remoteSubscriptions[i]; const local = await this.add(remote.base_url, remote.topic); + const reservation = remoteReservations?.find(r => remote.base_url === config.baseUrl && remote.topic === r.topic) || null; await this.setRemoteId(local.id, remote.id); await this.setDisplayName(local.id, remote.display_name); + await this.setReservation(local.id, reservation); // May be null! remoteIds.push(remote.id); } @@ -174,6 +176,12 @@ class SubscriptionManager { }); } + async setReservation(subscriptionId, reservation) { + await db.subscriptions.update(subscriptionId, { + reservation: reservation + }); + } + async pruneNotifications(thresholdTimestamp) { await db.notifications .where("time").below(thresholdTimestamp) diff --git a/web/src/components/Navigation.js b/web/src/components/Navigation.js index e7c2a63..f259c3e 100644 --- a/web/src/components/Navigation.js +++ b/web/src/components/Navigation.js @@ -12,15 +12,24 @@ 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, Badge, CircularProgress, Link, ListSubheader} from "@mui/material"; +import { + Alert, + AlertTitle, + Badge, + CircularProgress, + Link, + ListItem, + ListItemSecondaryAction, + ListSubheader, Tooltip +} from "@mui/material"; import Button from "@mui/material/Button"; import Typography from "@mui/material/Typography"; import {openUrl, topicDisplayName, topicUrl} from "../app/utils"; import routes from "./routes"; import {ConnectionState} from "../app/Connection"; -import {useLocation, useNavigate} from "react-router-dom"; +import {useLocation, useNavigate, useOutletContext} from "react-router-dom"; import subscriptionManager from "../app/SubscriptionManager"; -import {ChatBubble, NotificationsOffOutlined, Send} from "@mui/icons-material"; +import {ChatBubble, Lock, MoreVert, NotificationsOffOutlined, Public, PublicOff, Send} from "@mui/icons-material"; import Box from "@mui/material/Box"; import notifier from "../app/Notifier"; import config from "../app/config"; @@ -28,6 +37,8 @@ import ArticleIcon from '@mui/icons-material/Article'; import {Trans, useTranslation} from "react-i18next"; import session from "../app/Session"; import accountApi from "../app/AccountApi"; +import IconButton from "@mui/material/IconButton"; +import CloseIcon from "@mui/icons-material/Close"; const navWidth = 280; @@ -198,9 +209,28 @@ const SubscriptionItem = (props) => { return ( {icon} - + + {subscription.reservation?.everyone && + + {subscription.reservation?.everyone === "read-write" && + + } + {subscription.reservation?.everyone === "read-only" && + + } + {subscription.reservation?.everyone === "write-only" && + + } + {subscription.reservation?.everyone === "deny-all" && + + } + + } {subscription.mutedUntil > 0 && - } + + + + } ); };