From d6df0b1d43dc524b516e495d95a90344af969c69 Mon Sep 17 00:00:00 2001 From: valentinkolb Date: Wed, 12 Jun 2024 00:13:03 +0200 Subject: [PATCH] feat(chat): added desktop notifications --- public/stuve-logo.png | Bin 0 -> 1673 bytes src/pages/chat/components/ChatNavIcon.tsx | 73 +++++++++++++++++----- 2 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 public/stuve-logo.png diff --git a/public/stuve-logo.png b/public/stuve-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d6925bb0f5f73b8e1630a0cefb11a342b008c739 GIT binary patch literal 1673 zcmb7FX;c$u6dgom5tPM>b%A6iEH(lf*$WCbNWvlriUKMgAS~`1h_W<-3t0#u0TC^V z3lxDuU8|yk2pWzGB47bYLV?UAKpfX!a|y32F{ z0MMsW$bslH3cIy6(bdb977YM%3Ilw%dZHI zMu&;H{g#XY0#6QR4B@iGrsw}b>lSPn&y^7veNd(Z%z$y{5du>Nae6^!FP5(rJzp{8IJbTWvJWnpqC z7@Y~RFfgWw)-jg4i*B>18#KFsLPT8cM{vYCqWUZ!oo%1a-HuJrUo#lT9DotR+=4{v^6Sm|aR$0hTTx2yDvB{R&@}z6|Qioir!v&dB zp3M28%zsJd zIq|q_;<0d|T0B|PJz3W~^{Q{`Ei&DROuv&(H_N752WC3tGo3>-LdC2|F)LQgc8|>V zjL!CcQuQfS5~T_rQz2t2^b)zbzCd5myyJnJg8+>=nsevP*V5L})ze?N$iUEOvB`>+ zrZ|XTZfUh@wY81ynzf{LcJ@xrF0O7HJT{U&Dc(MQ{sDnox9tcG+qFA9B8nCpxA(xo z!$*(DC!9z;c`7M6C6%7eU}y38IT!MNE4X^Sxa3x8#httNA3l9n^ZZ3!z2Hq_b4zPm zd*{b4p{Tn@0wV*1L&GDZpOj;t$0sJIre|h9C#DNgiy9F=US#o=xcB<#x22?#J+{V* zZdrzyN7DywlCCv-CXbhPEhpDVT7Xs|q?D&WghgC*()?l3ohc_pc zRWwDW8*~H*@eM)WR&B0#PF18!)R854Pg2z1?|t&3DCI@ACEN$LR1KkkB--MT!5!DD zz0{1`1jHG|dctqV#~SiC)iGbzZL>~&+NGNI`k9mhojGOjth!~_E`Qw~N0Vdnwb@FD z##`c_&`055AxOd5&|U0DA1>^b8IoT!&uA%LHc-Myw4KE^l09kMFouBG5UQM{dEbD? z)|8G@Gi-&wh8B}8iVrEH7Bt!i@@558#+ec=Ux)4Ckm?>`yGi1~NO$H^Q-y(|>=rji zS*YPecfPioY88?e>-C`QxhXAv%rQn>NNkvJII-N#IU>%g;b4cIUwYI6otpZ}L1^W( zDHk6KJ$l*AzDB1N5N!~_-MHC9S%d8`&1-0+h7mg;VoXe|ALN=xT5LA z@cKH#j)Y8PPWtd)A-lVT$vaXemarH}i7~mFK+xo?m%9p^$(g+f&auk#}2O>9aQ}(HNn`pA^b1tBYFomK#Pe+qQK*tuFci5)FGYBJ<5YPW2OK z&W3j4dyI9uBPr0F!@i9U4 zoK$;gpH+is_Qs1vcMF#Hn|CaDV#{!kDcQ{%mxdwlCpK>(f`@)+E05bh_&B#kp43+g zR$bgd?FdyUbL;k52<2an { + const parser = new DOMParser(); + const doc = parser.parseFromString(html, 'text/html'); + return doc.body.textContent || ''; +} + +const sendDesktopNotification = (body: string, url: string) => { + if ("Notification" in window && Notification.permission === 'granted') { + const notification = new Notification(APP_NAME, { + body: body, + icon: `${APP_URL}/stuve-logo.svg`, + vibrate: [200, 100, 200], + data: {url: url} + }) + notification.onclick = () => { + window.focus() + window.open(notification.data.url); + } + } +} export default function ChatNavIcon() { - const [newMessage, setNewMessage] = useState(null); - const {start} = useTimeout(() => setNewMessage(null), 5000); + const [notificationUrl, setNotificationUrl] = useState(null); + const {start} = useTimeout(() => setNotificationUrl(null), 5000); const {user, useSubscription} = usePB() const match = useMatch("/chat/:listId") + useEffect(() => { + // Request notification permission on component mount + if ("Notification" in window && Notification.permission !== 'granted') { + Notification.requestPermission().then(() => { + sendDesktopNotification( + "Willkommen bei StuVe! Du kannst jetzt Desktop Benachrichtigungen erhalten.", + `${APP_URL}/chat` + ) + }) + } + }, []) + useSubscription({ idOrName: "messages", topic: "*", callback: (event) => { if (event.action == "create") { - if (event.record.isAnnouncement) { - start() - setNewMessage("announcements") - } else if ( - event.record.eventList - && - match?.params.listId !== event.record.eventList // check if chat page is not already open - && - event.record.sender !== user?.id // check if sender is not the user - ) { - start() - setNewMessage(event.record.eventList) + // check if chat page is not already open and if sender is not the user + if (match?.params.listId === event.record.eventList && event.record.sender === user?.id) { + return } + + const notificationUrl = `/chat/${event.record.isAnnouncement ? "announcements" : event.record.eventList}` + + setNotificationUrl(notificationUrl) + start() + + sendDesktopNotification( + parseHtmlString(event.record.content), + `${APP_URL}${notificationUrl}` + ) } } }) @@ -42,12 +81,12 @@ export default function ChatNavIcon() { } return <> -