diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index e71306d6c..1fe75c598 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -50,6 +50,7 @@ import { commentsToFlatNodes, setupTippy, favIconUrl, + notifyPost, } from '../utils'; import { i18n } from '../i18next'; @@ -426,6 +427,7 @@ export class Community extends Component { } else if (res.op == UserOperation.CreatePost) { let data = res.data as PostResponse; this.state.posts.unshift(data.post); + notifyPost(data.post, this.context.router); this.setState(this.state); } else if (res.op == UserOperation.CreatePostLike) { let data = res.data as PostResponse; diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index 3c303104a..d80c77251 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -55,6 +55,7 @@ import { commentsToFlatNodes, setupTippy, favIconUrl, + notifyPost, } from '../utils'; import { i18n } from '../i18next'; import { T } from 'inferno-i18next'; @@ -715,6 +716,7 @@ export class Main extends Component { .includes(data.post.community_id) ) { this.state.posts.unshift(data.post); + notifyPost(data.post, this.context.router); } } else { // NSFW posts @@ -728,6 +730,7 @@ export class Main extends Component { UserService.Instance.user.show_nsfw) ) { this.state.posts.unshift(data.post); + notifyPost(data.post, this.context.router); } } this.setState(this.state); diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx index 351d00b8c..0ddcbb4cd 100644 --- a/ui/src/components/navbar.tsx +++ b/ui/src/components/navbar.tsx @@ -24,12 +24,11 @@ import { pictrsAvatarThumbnail, showAvatars, fetchLimit, - isCommentType, toast, - messageToastify, - md, setTheme, getLanguage, + notifyComment, + notifyPrivateMessage, } from '../utils'; import { i18n } from '../i18next'; @@ -436,7 +435,7 @@ export class Navbar extends Component { this.state.unreadCount++; this.setState(this.state); this.sendUnreadCount(); - this.notify(data.comment); + notifyComment(data.comment, this.context.router); } } } else if (res.op == UserOperation.CreatePrivateMessage) { @@ -448,7 +447,7 @@ export class Navbar extends Component { this.state.unreadCount++; this.setState(this.state); this.sendUnreadCount(); - this.notify(data.message); + notifyPrivateMessage(data.message, this.context.router); } } } else if (res.op == UserOperation.GetSite) { @@ -542,37 +541,4 @@ export class Navbar extends Component { }); } } - - notify(reply: Comment | PrivateMessage) { - let creator_name = reply.creator_name; - let creator_avatar = reply.creator_avatar - ? reply.creator_avatar - : `${window.location.protocol}//${window.location.host}/static/assets/apple-touch-icon.png`; - let link = isCommentType(reply) - ? `/post/${reply.post_id}/comment/${reply.id}` - : `/inbox`; - let htmlBody = md.render(reply.content); - let body = reply.content; // Unfortunately the notifications API can't do html - - messageToastify( - creator_name, - creator_avatar, - htmlBody, - link, - this.context.router - ); - - if (Notification.permission !== 'granted') Notification.requestPermission(); - else { - var notification = new Notification(reply.creator_name, { - icon: creator_avatar, - body: body, - }); - - notification.onclick = () => { - event.preventDefault(); - this.context.router.history.push(link); - }; - } - } } diff --git a/ui/src/utils.ts b/ui/src/utils.ts index 005320952..ae2785a6b 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -59,6 +59,8 @@ import tippy from 'tippy.js'; import moment from 'moment'; export const favIconUrl = '/static/assets/favicon.svg'; +export const favIconPngUrl = '/static/assets/apple-touch-icon.png'; +export const defaultFavIcon = `${window.location.protocol}//${window.location.host}${favIconPngUrl}`; export const repoUrl = 'https://github.com/LemmyNet/lemmy'; export const helpGuideUrl = '/docs/about_guide.html'; export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`; @@ -526,8 +528,19 @@ export function pictrsImage(hash: string, thumbnail: boolean = false): string { return out; } -export function isCommentType(item: Comment | PrivateMessage): item is Comment { - return (item as Comment).community_id !== undefined; +export function isCommentType( + item: Comment | PrivateMessage | Post +): item is Comment { + return ( + (item as Comment).community_id !== undefined && + (item as Comment).content !== undefined + ); +} + +export function isPostType( + item: Comment | PrivateMessage | Post +): item is Post { + return (item as Post).stickied !== undefined; } export function toast(text: string, background: string = 'success') { @@ -563,18 +576,20 @@ export function pictrsDeleteToast( }).showToast(); } -export function messageToastify( - creator: string, - avatar: string, - body: string, - link: string, - router: any -) { +interface NotifyInfo { + name: string; + icon: string; + link: string; + body: string; +} + +export function messageToastify(info: NotifyInfo, router: any) { + let htmlBody = info.body ? md.render(info.body) : ''; let backgroundColor = `var(--light)`; let toast = Toastify({ - text: `${body}
${creator}`, - avatar: avatar, + text: `${htmlBody}
${info.name}`, + avatar: info.icon, backgroundColor: backgroundColor, className: 'text-dark', close: true, @@ -584,12 +599,59 @@ export function messageToastify( onClick: () => { if (toast) { toast.hideToast(); - router.history.push(link); + router.history.push(info.link); } }, }).showToast(); } +export function notifyPost(post: Post, router: any) { + let info: NotifyInfo = { + name: post.community_name, + icon: post.community_icon ? post.community_icon : defaultFavIcon, + link: `/post/${post.id}`, + body: post.name, + }; + notify(info, router); +} + +export function notifyComment(comment: Comment, router: any) { + let info: NotifyInfo = { + name: comment.creator_name, + icon: comment.creator_avatar ? comment.creator_avatar : defaultFavIcon, + link: `/post/${comment.post_id}/comment/${comment.id}`, + body: comment.content, + }; + notify(info, router); +} + +export function notifyPrivateMessage(pm: PrivateMessage, router: any) { + let info: NotifyInfo = { + name: pm.creator_name, + icon: pm.creator_avatar ? pm.creator_avatar : defaultFavIcon, + link: `/inbox`, + body: pm.content, + }; + notify(info, router); +} + +function notify(info: NotifyInfo, router: any) { + messageToastify(info, router); + + if (Notification.permission !== 'granted') Notification.requestPermission(); + else { + var notification = new Notification(info.name, { + icon: info.icon, + body: info.body, + }); + + notification.onclick = () => { + event.preventDefault(); + router.history.push(info.link); + }; + } +} + export function setupTribute(): Tribute { return new Tribute({ noMatchTemplate: function () {