Skip to content

Commit

Permalink
feat(notification): add desktop notification
Browse files Browse the repository at this point in the history
close #1093
  • Loading branch information
munkhorgil authored and batamar committed Aug 22, 2019
1 parent 5cb1719 commit 8d4097f
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 18 deletions.
51 changes: 51 additions & 0 deletions src/modules/common/utils/index.tsx
Expand Up @@ -230,3 +230,54 @@ export const generateRandomString = (len: number = 10) => {

return randomString;
};

/**
* Send desktop notification
*/
export const sendDesktopNotification = (doc: {
title: string;
content?: string;
}) => {
const notify = () => {
// Don't send notification to itself
if (!window.document.hidden) {
return;
}

const notification = new Notification(doc.title, {
body: doc.content,
icon: '/favicon.png',
dir: 'ltr'
});

// notify by sound
const audio = new Audio('/sound/notify.mp3');
audio.play();

notification.onclick = () => {
window.focus();
notification.close();
};
};

// Browser doesn't support Notification api
if (!('Notification' in window)) {
return;
}

if (Notification.permission === 'granted') {
return notify();
}

if (Notification.permission !== 'denied') {
Notification.requestPermission(permission => {
if (!('permission' in Notification)) {
(Notification as any).permission = permission;
}

if (permission === 'granted') {
return notify();
}
});
}
};
7 changes: 7 additions & 0 deletions src/modules/inbox/constants.ts
Expand Up @@ -4,3 +4,10 @@ export const CONVERSATION_STATUSES = {
CLOSED: 'closed',
ALL_LIST: ['new', 'open', 'closed']
};

export const NOTIFICATION_TYPE = {
gmail: 'You have a new email',
facebook: 'You have a message from facebook',
lead: 'You have got a new lead',
messenger: 'You have a new message from messenger'
};
14 changes: 11 additions & 3 deletions src/modules/inbox/containers/conversationDetail/WorkArea.tsx
@@ -1,11 +1,13 @@
import { AppConsumer } from 'appContext';
import gql from 'graphql-tag';
import DumbWorkArea from 'modules/inbox/components/conversationDetail/workarea/WorkArea';
import { NOTIFICATION_TYPE } from 'modules/inbox/constants';
import { mutations, queries, subscriptions } from 'modules/inbox/graphql';
import React from 'react';
import { compose, graphql } from 'react-apollo';
import strip from 'strip';
import { IUser } from '../../../auth/types';
import { withProps } from '../../../common/utils';
import { sendDesktopNotification, withProps } from '../../../common/utils';
import {
AddMessageMutationResponse,
AddMessageMutationVariables,
Expand Down Expand Up @@ -73,12 +75,12 @@ class WorkArea extends React.Component<FinalProps, State> {
variables: { _id: currentId },
updateQuery: (prev, { subscriptionData }) => {
const message = subscriptionData.data.conversationMessageInserted;
const kind = currentConversation.integration.kind;

// current user's message is being showed after insert message
// mutation. So to prevent from duplication we are ignoring current
// user's messages from subscription
const isMessenger =
currentConversation.integration.kind === 'messenger';
const isMessenger = kind === 'messenger';

if (isMessenger && message.userId === currentUser._id) {
return;
Expand Down Expand Up @@ -108,6 +110,12 @@ class WorkArea extends React.Component<FinalProps, State> {
conversationMessages: [...messages, message]
};

// send desktop notification
sendDesktopNotification({
title: NOTIFICATION_TYPE[kind],
content: strip(message.content) || ''
});

return next;
}
});
Expand Down
1 change: 1 addition & 0 deletions src/modules/inbox/graphql/subscriptions.ts
Expand Up @@ -20,6 +20,7 @@ const conversationClientMessageInserted = `
subscription conversationClientMessageInserted($userId: String!) {
conversationClientMessageInserted(userId: $userId) {
_id
content
}
}
`;
Expand Down
15 changes: 10 additions & 5 deletions src/modules/layout/containers/Navigation.tsx
Expand Up @@ -4,7 +4,8 @@ import { queries, subscriptions } from 'modules/inbox/graphql';
import { UnreadConversationsTotalCountQueryResponse } from 'modules/inbox/types';
import React from 'react';
import { compose, graphql } from 'react-apollo';
import { withProps } from '../../common/utils';
import strip from 'strip';
import { sendDesktopNotification, withProps } from '../../common/utils';
import Navigation from '../components/Navigation';

class NavigationContainer extends React.Component<{
Expand All @@ -18,12 +19,16 @@ class NavigationContainer extends React.Component<{
// listen for all conversation changes
document: gql(subscriptions.conversationClientMessageInserted),
variables: { userId: currentUser._id },
updateQuery: () => {
updateQuery: (prev, { subscriptionData: { data } }) => {
const { conversationClientMessageInserted } = data;
const { content } = conversationClientMessageInserted;

this.props.unreadConversationsCountQuery.refetch();

// notify by sound
const audio = new Audio('/sound/notify.mp3');
audio.play();
sendDesktopNotification({
title: 'You have a new message',
content: strip(content || '')
});
}
});
}
Expand Down
14 changes: 12 additions & 2 deletions src/modules/notifications/containers/NotificationsLatest.tsx
@@ -1,9 +1,14 @@
import gql from 'graphql-tag';
import { IUser } from 'modules/auth/types';
import Spinner from 'modules/common/components/Spinner';
import { Alert, withProps } from 'modules/common/utils';
import {
Alert,
sendDesktopNotification,
withProps
} from 'modules/common/utils';
import React from 'react';
import { compose, graphql } from 'react-apollo';
import strip from 'strip';
import NotificationsLatest from '../components/NotificationsLatest';
import { mutations, queries, subscriptions } from '../graphql';
import {
Expand All @@ -30,7 +35,12 @@ class NotificationsLatestContainer extends React.Component<FinalProps> {
notificationsQuery.subscribeToMore({
document: subscription,
variables: { userId: currentUser ? currentUser._id : null },
updateQuery: () => {
updateQuery: (prev, { subscriptionData: { data } }) => {
const { notificationInserted } = data;
const { title, content } = notificationInserted;

sendDesktopNotification({ title, content: strip(content || '') });

notificationsQuery.refetch();
}
});
Expand Down
5 changes: 4 additions & 1 deletion src/modules/notifications/graphql/subscriptions.ts
@@ -1,6 +1,9 @@
const notificationSubscription = `
subscription notificationInserted($userId: String) {
notificationInserted(userId: $userId)
notificationInserted(userId: $userId) {
title
content
}
}
`;

Expand Down
8 changes: 1 addition & 7 deletions src/modules/notifications/types.ts
Expand Up @@ -15,13 +15,7 @@ export interface INotification {

export type NotificationsQueryResponse = {
notifications: INotification[];
subscribeToMore: (
params: {
document: string;
updateQuery: () => void;
variables: { userId: string | null };
}
) => void;
subscribeToMore: any;
loading: boolean;
refetch: () => void;
};
Expand Down

0 comments on commit 8d4097f

Please sign in to comment.