New post notifs. Fixes #1073 (#1079)

* New post notifs. Fixes #1073

* Some refactoring of browser notifs
This commit is contained in:
Dessalines 2020-08-13 10:42:52 -04:00 committed by GitHub
parent 9a343cfe8b
commit 91926b2b1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 83 additions and 50 deletions

View file

@ -50,6 +50,7 @@ import {
commentsToFlatNodes, commentsToFlatNodes,
setupTippy, setupTippy,
favIconUrl, favIconUrl,
notifyPost,
} from '../utils'; } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
@ -426,6 +427,7 @@ export class Community extends Component<any, State> {
} else if (res.op == UserOperation.CreatePost) { } else if (res.op == UserOperation.CreatePost) {
let data = res.data as PostResponse; let data = res.data as PostResponse;
this.state.posts.unshift(data.post); this.state.posts.unshift(data.post);
notifyPost(data.post, this.context.router);
this.setState(this.state); this.setState(this.state);
} else if (res.op == UserOperation.CreatePostLike) { } else if (res.op == UserOperation.CreatePostLike) {
let data = res.data as PostResponse; let data = res.data as PostResponse;

View file

@ -55,6 +55,7 @@ import {
commentsToFlatNodes, commentsToFlatNodes,
setupTippy, setupTippy,
favIconUrl, favIconUrl,
notifyPost,
} from '../utils'; } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { T } from 'inferno-i18next'; import { T } from 'inferno-i18next';
@ -715,6 +716,7 @@ export class Main extends Component<any, MainState> {
.includes(data.post.community_id) .includes(data.post.community_id)
) { ) {
this.state.posts.unshift(data.post); this.state.posts.unshift(data.post);
notifyPost(data.post, this.context.router);
} }
} else { } else {
// NSFW posts // NSFW posts
@ -728,6 +730,7 @@ export class Main extends Component<any, MainState> {
UserService.Instance.user.show_nsfw) UserService.Instance.user.show_nsfw)
) { ) {
this.state.posts.unshift(data.post); this.state.posts.unshift(data.post);
notifyPost(data.post, this.context.router);
} }
} }
this.setState(this.state); this.setState(this.state);

View file

@ -24,12 +24,11 @@ import {
pictrsAvatarThumbnail, pictrsAvatarThumbnail,
showAvatars, showAvatars,
fetchLimit, fetchLimit,
isCommentType,
toast, toast,
messageToastify,
md,
setTheme, setTheme,
getLanguage, getLanguage,
notifyComment,
notifyPrivateMessage,
} from '../utils'; } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
@ -436,7 +435,7 @@ export class Navbar extends Component<any, NavbarState> {
this.state.unreadCount++; this.state.unreadCount++;
this.setState(this.state); this.setState(this.state);
this.sendUnreadCount(); this.sendUnreadCount();
this.notify(data.comment); notifyComment(data.comment, this.context.router);
} }
} }
} else if (res.op == UserOperation.CreatePrivateMessage) { } else if (res.op == UserOperation.CreatePrivateMessage) {
@ -448,7 +447,7 @@ export class Navbar extends Component<any, NavbarState> {
this.state.unreadCount++; this.state.unreadCount++;
this.setState(this.state); this.setState(this.state);
this.sendUnreadCount(); this.sendUnreadCount();
this.notify(data.message); notifyPrivateMessage(data.message, this.context.router);
} }
} }
} else if (res.op == UserOperation.GetSite) { } else if (res.op == UserOperation.GetSite) {
@ -542,37 +541,4 @@ export class Navbar extends Component<any, NavbarState> {
}); });
} }
} }
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);
};
}
}
} }

86
ui/src/utils.ts vendored
View file

@ -59,6 +59,8 @@ import tippy from 'tippy.js';
import moment from 'moment'; import moment from 'moment';
export const favIconUrl = '/static/assets/favicon.svg'; 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 repoUrl = 'https://github.com/LemmyNet/lemmy';
export const helpGuideUrl = '/docs/about_guide.html'; export const helpGuideUrl = '/docs/about_guide.html';
export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`; export const markdownHelpUrl = `${helpGuideUrl}#markdown-guide`;
@ -526,8 +528,19 @@ export function pictrsImage(hash: string, thumbnail: boolean = false): string {
return out; return out;
} }
export function isCommentType(item: Comment | PrivateMessage): item is Comment { export function isCommentType(
return (item as Comment).community_id !== undefined; 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') { export function toast(text: string, background: string = 'success') {
@ -563,18 +576,20 @@ export function pictrsDeleteToast(
}).showToast(); }).showToast();
} }
export function messageToastify( interface NotifyInfo {
creator: string, name: string;
avatar: string, icon: string;
body: string, link: string;
link: string, body: string;
router: any }
) {
export function messageToastify(info: NotifyInfo, router: any) {
let htmlBody = info.body ? md.render(info.body) : '';
let backgroundColor = `var(--light)`; let backgroundColor = `var(--light)`;
let toast = Toastify({ let toast = Toastify({
text: `${body}<br />${creator}`, text: `${htmlBody}<br />${info.name}`,
avatar: avatar, avatar: info.icon,
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
className: 'text-dark', className: 'text-dark',
close: true, close: true,
@ -584,12 +599,59 @@ export function messageToastify(
onClick: () => { onClick: () => {
if (toast) { if (toast) {
toast.hideToast(); toast.hideToast();
router.history.push(link); router.history.push(info.link);
} }
}, },
}).showToast(); }).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 { export function setupTribute(): Tribute {
return new Tribute({ return new Tribute({
noMatchTemplate: function () { noMatchTemplate: function () {