feat: instant meeting browser notifcations (#16480)
* feat: instant meeting browser notifcations * chore: support multiple notifications * chore: save progress * fix: add test notification and move file * fix: type err * chore: feedback improvements * chore: undo DENY
This commit is contained in:
1 parent
5bc0e1265d
commit
860d173f0a
9 files changed
+220
-37
No files matched your search
@@ -12,7 +12,6 @@ import type { filterQuerySchema } from "@calcom/features/bookings/lib/useFilterQ
|
||||
import { useFilterQuery } from "@calcom/features/bookings/lib/useFilterQuery";
|
||||
import Shell from "@calcom/features/shell/Shell";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { useNotifications, ButtonState } from "@calcom/lib/hooks/useNotifications";
|
||||
import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback";
|
||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
@@ -145,27 +144,6 @@ export default function Bookings() {
|
||||
)[0] || [];
|
||||
|
||||
const [animationParentRef] = useAutoAnimate<HTMLDivElement>();
|
||||
const { buttonToShow, isLoading, enableNotifications, disableNotifications } = useNotifications();
|
||||
|
||||
const actions = (
|
||||
<div>
|
||||
{buttonToShow && (
|
||||
<Button
|
||||
color="primary"
|
||||
onClick={buttonToShow === ButtonState.ALLOW ? enableNotifications : disableNotifications}
|
||||
loading={isLoading}
|
||||
disabled={buttonToShow === ButtonState.DENIED}
|
||||
tooltipSide="bottom"
|
||||
tooltip={buttonToShow === ButtonState.DENIED ? t("you_have_denied_notifications") : undefined}>
|
||||
{t(
|
||||
buttonToShow === ButtonState.DISABLE
|
||||
? "disable_browser_notifications"
|
||||
: "allow_browser_notifications"
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<Shell
|
||||
@@ -174,8 +152,7 @@ export default function Bookings() {
|
||||
heading={t("bookings")}
|
||||
subtitle={t("bookings_description")}
|
||||
title="Bookings"
|
||||
description="Create events to share for people to book on your calendar."
|
||||
actions={actions}>
|
||||
description="Create events to share for people to book on your calendar.">
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row flex-wrap justify-between">
|
||||
<HorizontalTabs tabs={tabs} />
|
||||
|
||||
@@ -1,16 +1,68 @@
|
||||
self.addEventListener("push", (event) => {
|
||||
self.addEventListener("push", async (event) => {
|
||||
let notificationData = event.data.json();
|
||||
|
||||
const title = notificationData.title || "You have new notification from Cal.com";
|
||||
const image ="/cal-com-icon.svg";
|
||||
const options = {
|
||||
...notificationData.options,
|
||||
const allClients = await clients.matchAll({
|
||||
type: 'window',
|
||||
includeUncontrolled: true
|
||||
});
|
||||
|
||||
if(!allClients.length) {
|
||||
console.log("No open tabs, skipping the push notification.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const title = notificationData.title || "You have a new notification from Cal.com";
|
||||
const image = "https://cal.com/api/logo?type=icon";
|
||||
const newNotificationOptions = {
|
||||
requireInteraction: true,
|
||||
...notificationData,
|
||||
icon: image,
|
||||
badge: image,
|
||||
data: {
|
||||
url: notificationData.data?.url || "https://app.cal.com",
|
||||
},
|
||||
silent: false,
|
||||
vibrate: [300, 100, 400],
|
||||
tag: `notification-${Date.now()}-${Math.random()}`,
|
||||
};
|
||||
self.registration.showNotification(title, options);
|
||||
|
||||
|
||||
const existingNotifications = await self.registration.getNotifications();
|
||||
|
||||
// Display each existing notification again to make sure old ones can still be clicked
|
||||
existingNotifications.forEach((notification) => {
|
||||
const options = {
|
||||
body: notification.body,
|
||||
icon: notification.icon,
|
||||
badge: notification.badge,
|
||||
data: notification.data,
|
||||
silent: notification.silent,
|
||||
vibrate: notification.vibrate,
|
||||
requireInteraction: notification.requireInteraction,
|
||||
tag: notification.tag,
|
||||
};
|
||||
self.registration.showNotification(notification.title, options);
|
||||
});
|
||||
|
||||
|
||||
// Show the new notification
|
||||
self.registration.showNotification(title, newNotificationOptions);
|
||||
});
|
||||
|
||||
self.addEventListener("notificationclick", (event) => {
|
||||
event.notification.close();
|
||||
event.waitUntil(self.clients.openWindow(event.notification.data.targetURL || "https://app.cal.com"));
|
||||
if (!event.action) {
|
||||
// Normal Notification Click
|
||||
event.notification.close();
|
||||
const url = event.notification.data.url;
|
||||
event.waitUntil(self.clients.openWindow(url));
|
||||
}
|
||||
|
||||
switch (event.action) {
|
||||
case 'connect-action':
|
||||
event.notification.close();
|
||||
const url = event.notification.data.url;
|
||||
event.waitUntil(self.clients.openWindow(url));
|
||||
break;
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user