Fix refreshing things when permission is granted
We refreshed some things but not everything, this makes it more responsive if you have the settings page open when granting permissions, for example.pull/791/head
parent
64ac111d55
commit
9ce3545901
|
@ -8,7 +8,6 @@ import { AllSubscriptions, SingleSubscription } from "./Notifications";
|
||||||
import themeOptions, { darkPalette, lightPalette } from "./theme";
|
import themeOptions, { darkPalette, lightPalette } from "./theme";
|
||||||
import Navigation from "./Navigation";
|
import Navigation from "./Navigation";
|
||||||
import ActionBar from "./ActionBar";
|
import ActionBar from "./ActionBar";
|
||||||
import notifier from "../app/Notifier";
|
|
||||||
import Preferences from "./Preferences";
|
import Preferences from "./Preferences";
|
||||||
import subscriptionManager from "../app/SubscriptionManager";
|
import subscriptionManager from "../app/SubscriptionManager";
|
||||||
import userManager from "../app/UserManager";
|
import userManager from "../app/UserManager";
|
||||||
|
@ -91,7 +90,6 @@ const Layout = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const { account, setAccount } = useContext(AccountContext);
|
const { account, setAccount } = useContext(AccountContext);
|
||||||
const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false);
|
const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false);
|
||||||
const [notificationsGranted, setNotificationsGranted] = useState(notifier.granted());
|
|
||||||
const [sendDialogOpenMode, setSendDialogOpenMode] = useState("");
|
const [sendDialogOpenMode, setSendDialogOpenMode] = useState("");
|
||||||
const users = useLiveQuery(() => userManager.all());
|
const users = useLiveQuery(() => userManager.all());
|
||||||
const subscriptions = useLiveQuery(() => subscriptionManager.all());
|
const subscriptions = useLiveQuery(() => subscriptionManager.all());
|
||||||
|
@ -115,10 +113,8 @@ const Layout = () => {
|
||||||
<Navigation
|
<Navigation
|
||||||
subscriptions={subscriptionsWithoutInternal}
|
subscriptions={subscriptionsWithoutInternal}
|
||||||
selectedSubscription={selected}
|
selectedSubscription={selected}
|
||||||
notificationsGranted={notificationsGranted}
|
|
||||||
mobileDrawerOpen={mobileDrawerOpen}
|
mobileDrawerOpen={mobileDrawerOpen}
|
||||||
onMobileDrawerToggle={() => setMobileDrawerOpen(!mobileDrawerOpen)}
|
onMobileDrawerToggle={() => setMobileDrawerOpen(!mobileDrawerOpen)}
|
||||||
onNotificationGranted={setNotificationsGranted}
|
|
||||||
onPublishMessageClick={() => setSendDialogOpenMode(PublishDialog.OPEN_MODE_DEFAULT)}
|
onPublishMessageClick={() => setSendDialogOpenMode(PublishDialog.OPEN_MODE_DEFAULT)}
|
||||||
/>
|
/>
|
||||||
<Main>
|
<Main>
|
||||||
|
|
|
@ -43,6 +43,7 @@ import UpgradeDialog from "./UpgradeDialog";
|
||||||
import { AccountContext } from "./App";
|
import { AccountContext } from "./App";
|
||||||
import { PermissionDenyAll, PermissionRead, PermissionReadWrite, PermissionWrite } from "./ReserveIcons";
|
import { PermissionDenyAll, PermissionRead, PermissionReadWrite, PermissionWrite } from "./ReserveIcons";
|
||||||
import { SubscriptionPopup } from "./SubscriptionPopup";
|
import { SubscriptionPopup } from "./SubscriptionPopup";
|
||||||
|
import { useNotificationPermissionListener } from "./hooks";
|
||||||
|
|
||||||
const navWidth = 280;
|
const navWidth = 280;
|
||||||
|
|
||||||
|
@ -109,17 +110,12 @@ const NavList = (props) => {
|
||||||
const isPaid = account?.billing?.subscription;
|
const isPaid = account?.billing?.subscription;
|
||||||
const showUpgradeBanner = config.enable_payments && !isAdmin && !isPaid;
|
const showUpgradeBanner = config.enable_payments && !isAdmin && !isPaid;
|
||||||
const showSubscriptionsList = props.subscriptions?.length > 0;
|
const showSubscriptionsList = props.subscriptions?.length > 0;
|
||||||
const [showNotificationPermissionRequired, setShowNotificationPermissionRequired] = useState(notifier.notRequested());
|
const showNotificationPermissionRequired = useNotificationPermissionListener(() => notifier.notRequested());
|
||||||
const [showNotificationPermissionDenied, setShowNotificationPermissionDenied] = useState(notifier.denied());
|
const showNotificationPermissionDenied = useNotificationPermissionListener(() => notifier.denied());
|
||||||
const showNotificationIOSInstallRequired = notifier.iosSupportedButInstallRequired();
|
const showNotificationIOSInstallRequired = notifier.iosSupportedButInstallRequired();
|
||||||
const showNotificationBrowserNotSupportedBox = !showNotificationIOSInstallRequired && !notifier.browserSupported();
|
const showNotificationBrowserNotSupportedBox = !showNotificationIOSInstallRequired && !notifier.browserSupported();
|
||||||
const showNotificationContextNotSupportedBox = notifier.browserSupported() && !notifier.contextSupported(); // Only show if notifications are generally supported in the browser
|
const showNotificationContextNotSupportedBox = notifier.browserSupported() && !notifier.contextSupported(); // Only show if notifications are generally supported in the browser
|
||||||
|
|
||||||
const refreshPermissions = () => {
|
|
||||||
setShowNotificationPermissionRequired(notifier.notRequested());
|
|
||||||
setShowNotificationPermissionDenied(notifier.denied());
|
|
||||||
};
|
|
||||||
|
|
||||||
const alertVisible =
|
const alertVisible =
|
||||||
showNotificationPermissionRequired ||
|
showNotificationPermissionRequired ||
|
||||||
showNotificationPermissionDenied ||
|
showNotificationPermissionDenied ||
|
||||||
|
@ -131,7 +127,7 @@ const NavList = (props) => {
|
||||||
<>
|
<>
|
||||||
<Toolbar sx={{ display: { xs: "none", sm: "block" } }} />
|
<Toolbar sx={{ display: { xs: "none", sm: "block" } }} />
|
||||||
<List component="nav" sx={{ paddingTop: alertVisible ? "0" : "" }}>
|
<List component="nav" sx={{ paddingTop: alertVisible ? "0" : "" }}>
|
||||||
{showNotificationPermissionRequired && <NotificationPermissionRequired refreshPermissions={refreshPermissions} />}
|
{showNotificationPermissionRequired && <NotificationPermissionRequired />}
|
||||||
{showNotificationPermissionDenied && <NotificationPermissionDeniedAlert />}
|
{showNotificationPermissionDenied && <NotificationPermissionDeniedAlert />}
|
||||||
{showNotificationBrowserNotSupportedBox && <NotificationBrowserNotSupportedAlert />}
|
{showNotificationBrowserNotSupportedBox && <NotificationBrowserNotSupportedAlert />}
|
||||||
{showNotificationContextNotSupportedBox && <NotificationContextNotSupportedAlert />}
|
{showNotificationContextNotSupportedBox && <NotificationContextNotSupportedAlert />}
|
||||||
|
@ -354,11 +350,10 @@ const SubscriptionItem = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const NotificationPermissionRequired = ({ refreshPermissions }) => {
|
const NotificationPermissionRequired = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const requestPermission = async () => {
|
const requestPermission = async () => {
|
||||||
await notifier.maybeRequestPermission();
|
await notifier.maybeRequestPermission();
|
||||||
refreshPermissions();
|
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Alert severity="warning" sx={{ paddingTop: 2 }}>
|
<Alert severity="warning" sx={{ paddingTop: 2 }}>
|
||||||
|
|
|
@ -49,7 +49,7 @@ import { ReserveAddDialog, ReserveDeleteDialog, ReserveEditDialog } from "./Rese
|
||||||
import { UnauthorizedError } from "../app/errors";
|
import { UnauthorizedError } from "../app/errors";
|
||||||
import { subscribeTopic } from "./SubscribeDialog";
|
import { subscribeTopic } from "./SubscribeDialog";
|
||||||
import notifier from "../app/Notifier";
|
import notifier from "../app/Notifier";
|
||||||
import { useIsLaunchedPWA } from "./hooks";
|
import { useIsLaunchedPWA, useNotificationPermissionListener } from "./hooks";
|
||||||
|
|
||||||
const maybeUpdateAccountSettings = async (payload) => {
|
const maybeUpdateAccountSettings = async (payload) => {
|
||||||
if (!session.exists()) {
|
if (!session.exists()) {
|
||||||
|
@ -79,6 +79,7 @@ const Preferences = () => (
|
||||||
const Notifications = () => {
|
const Notifications = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isLaunchedPWA = useIsLaunchedPWA();
|
const isLaunchedPWA = useIsLaunchedPWA();
|
||||||
|
const pushPossible = useNotificationPermissionListener(() => notifier.pushPossible());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card sx={{ p: 3 }} aria-label={t("prefs_notifications_title")}>
|
<Card sx={{ p: 3 }} aria-label={t("prefs_notifications_title")}>
|
||||||
|
@ -89,7 +90,7 @@ const Notifications = () => {
|
||||||
<Sound />
|
<Sound />
|
||||||
<MinPriority />
|
<MinPriority />
|
||||||
<DeleteAfter />
|
<DeleteAfter />
|
||||||
{!isLaunchedPWA && notifier.pushPossible() && <WebPushEnabled />}
|
{!isLaunchedPWA && pushPossible && <WebPushEnabled />}
|
||||||
</PrefGroup>
|
</PrefGroup>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
@ -136,8 +136,31 @@ export const useAutoSubscribe = (subscriptions, selected) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const webPushBroadcastChannel = new BroadcastChannel("web-push-broadcast");
|
const webPushBroadcastChannel = new BroadcastChannel("web-push-broadcast");
|
||||||
const matchMedia = window.matchMedia("(display-mode: standalone)");
|
|
||||||
const isIOSStandalone = window.navigator.standalone === true;
|
/**
|
||||||
|
* Hook to return a value that's refreshed when the notification permission changes
|
||||||
|
*/
|
||||||
|
export const useNotificationPermissionListener = (query) => {
|
||||||
|
const [result, setResult] = useState(query());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = () => {
|
||||||
|
setResult(query());
|
||||||
|
};
|
||||||
|
|
||||||
|
if ("permissions" in navigator) {
|
||||||
|
navigator.permissions.query({ name: "notifications" }).then((permission) => {
|
||||||
|
permission.addEventListener("change", handler);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
permission.removeEventListener("change", handler);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the Web Push subscriptions when the list of topics changes,
|
* Updates the Web Push subscriptions when the list of topics changes,
|
||||||
|
@ -146,10 +169,11 @@ const isIOSStandalone = window.navigator.standalone === true;
|
||||||
*/
|
*/
|
||||||
const useWebPushListener = (topics) => {
|
const useWebPushListener = (topics) => {
|
||||||
const [lastTopics, setLastTopics] = useState();
|
const [lastTopics, setLastTopics] = useState();
|
||||||
|
const pushPossible = useNotificationPermissionListener(() => notifier.pushPossible());
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const topicsChanged = JSON.stringify(topics) !== JSON.stringify(lastTopics);
|
const topicsChanged = JSON.stringify(topics) !== JSON.stringify(lastTopics);
|
||||||
if (!notifier.pushPossible() || !topicsChanged) {
|
if (!pushPossible || !topicsChanged) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,25 +207,7 @@ const useWebPushListener = (topics) => {
|
||||||
* automatically.
|
* automatically.
|
||||||
*/
|
*/
|
||||||
export const useWebPushTopics = () => {
|
export const useWebPushTopics = () => {
|
||||||
const [pushPossible, setPushPossible] = useState(notifier.pushPossible());
|
const pushPossible = useNotificationPermissionListener(() => notifier.pushPossible());
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handler = () => {
|
|
||||||
const newPushPossible = notifier.pushPossible();
|
|
||||||
console.log(`[useWebPushTopics] Notification Permission changed`, { pushPossible: newPushPossible });
|
|
||||||
setPushPossible(newPushPossible);
|
|
||||||
};
|
|
||||||
|
|
||||||
if ("permissions" in navigator) {
|
|
||||||
navigator.permissions.query({ name: "notifications" }).then((permission) => {
|
|
||||||
permission.addEventListener("change", handler);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
permission.removeEventListener("change", handler);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const topics = useLiveQuery(
|
const topics = useLiveQuery(
|
||||||
async () => subscriptionManager.webPushTopics(pushPossible),
|
async () => subscriptionManager.webPushTopics(pushPossible),
|
||||||
|
@ -214,6 +220,9 @@ export const useWebPushTopics = () => {
|
||||||
return topics;
|
return topics;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const matchMedia = window.matchMedia("(display-mode: standalone)");
|
||||||
|
const isIOSStandalone = window.navigator.standalone === true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Watches the "display-mode" to detect if the app is running as a standalone app (PWA).
|
* Watches the "display-mode" to detect if the app is running as a standalone app (PWA).
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue