Notification improvements.

- Adding a navbar notification icon for mobile.
- Adding an in-app notification toast. To be improved later.
- Fixes #607
This commit is contained in:
Dessalines 2020-03-20 16:13:54 -04:00
parent 4e8d6a551f
commit eed8f1facd
4 changed files with 65 additions and 10 deletions

View file

@ -47,3 +47,5 @@
- https://docs.rs/activitypub/0.1.4/activitypub/ - https://docs.rs/activitypub/0.1.4/activitypub/
- [Activitypub vocab.](https://www.w3.org/TR/activitystreams-vocabulary/) - [Activitypub vocab.](https://www.w3.org/TR/activitystreams-vocabulary/)
- [Activitypub main](https://www.w3.org/TR/activitypub/) - [Activitypub main](https://www.w3.org/TR/activitypub/)
- [Federation.md](https://github.com/dariusk/gathio/blob/7fc93dbe9d4d99457a0e85c6c532112f415b7af2/FEDERATION.md)
- [Activitypub implementers guide](https://socialhub.activitypub.rocks/t/draft-guide-for-new-activitypub-implementers/479)

1
ui/.eslintrc.json vendored
View file

@ -38,6 +38,7 @@
"inferno/no-direct-mutation-state": 0, "inferno/no-direct-mutation-state": 0,
"inferno/no-unknown-property": 0, "inferno/no-unknown-property": 0,
"max-statements": 0, "max-statements": 0,
"max-params": 0,
"new-cap": 0, "new-cap": 0,
"no-console": 0, "no-console": 0,
"no-duplicate-imports": 0, "no-duplicate-imports": 0,

View file

@ -26,6 +26,8 @@ import {
fetchLimit, fetchLimit,
isCommentType, isCommentType,
toast, toast,
messageToastify,
md,
} from '../utils'; } from '../utils';
import { version } from '../version'; import { version } from '../version';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
@ -100,6 +102,22 @@ export class Navbar extends Component<any, NavbarState> {
<Link title={version} class="navbar-brand" to="/"> <Link title={version} class="navbar-brand" to="/">
{this.state.siteName} {this.state.siteName}
</Link> </Link>
{this.state.isLoggedIn && (
<Link
class="ml-auto navbar-toggler nav-link"
to="/inbox"
title={i18n.t('inbox')}
>
<svg class="icon">
<use xlinkHref="#icon-bell"></use>
</svg>
{this.state.unreadCount > 0 && (
<span class="ml-1 badge badge-light">
{this.state.unreadCount}
</span>
)}
</Link>
)}
<button <button
class="navbar-toggler" class="navbar-toggler"
type="button" type="button"
@ -350,21 +368,33 @@ export class Navbar extends Component<any, NavbarState> {
} }
notify(reply: Comment | PrivateMessage) { 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 body = md.render(reply.content);
messageToastify(
creator_name,
creator_avatar,
body,
link,
this.context.router
);
if (Notification.permission !== 'granted') Notification.requestPermission(); if (Notification.permission !== 'granted') Notification.requestPermission();
else { else {
var notification = new Notification(reply.creator_name, { var notification = new Notification(reply.creator_name, {
icon: reply.creator_avatar icon: creator_avatar,
? reply.creator_avatar body: body,
: `${window.location.protocol}//${window.location.host}/static/assets/apple-touch-icon.png`,
body: `${reply.content}`,
}); });
notification.onclick = () => { notification.onclick = () => {
this.context.router.history.push( event.preventDefault();
isCommentType(reply) this.context.router.history.push(link);
? `/post/${reply.post_id}/comment/${reply.id}`
: `/inbox`
);
}; };
} }
} }

24
ui/src/utils.ts vendored
View file

@ -218,7 +218,7 @@ export function validURL(str: string) {
} }
export function validEmail(email: string) { export function validEmail(email: string) {
let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; let re = /^(([^\s"(),.:;<>@[\\\]]+(\.[^\s"(),.:;<>@[\\\]]+)*)|(".+"))@((\[(?:\d{1,3}\.){3}\d{1,3}])|(([\dA-Za-z\-]+\.)+[A-Za-z]{2,}))$/;
return re.test(String(email).toLowerCase()); return re.test(String(email).toLowerCase());
} }
@ -436,6 +436,28 @@ export function toast(text: string, background: string = 'success') {
}).showToast(); }).showToast();
} }
export function messageToastify(
creator: string,
avatar: string,
body: string,
link: string,
router: any
) {
let backgroundColor = `var(--light)`;
Toastify({
text: `${body}<br />${creator}`,
avatar: avatar,
backgroundColor: backgroundColor,
close: true,
gravity: 'top',
position: 'right',
duration: 0,
onClick: () => {
router.history.push(link);
},
}).showToast();
}
export function setupTribute(): Tribute { export function setupTribute(): Tribute {
return new Tribute({ return new Tribute({
collection: [ collection: [