Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Desktop notification follow teammate display name (#1706)
Browse files Browse the repository at this point in the history
* Desktop notification follow teammate display name

* Feedback review

* Feedback review
  • Loading branch information
enahum authored and jwilander committed Sep 20, 2018
1 parent 217c95b commit a19bb02
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 160 deletions.
2 changes: 1 addition & 1 deletion actions/global_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ export function toggleSideBarRightMenuAction() {
}

export function emitBrowserFocus(focus) {
AppDispatcher.handleViewAction({
dispatch({
type: ActionTypes.BROWSER_CHANGE_FOCUS,
focus,
});
Expand Down
233 changes: 123 additions & 110 deletions actions/notification_actions.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {getProfilesByIds} from 'mattermost-redux/actions/users';
import {getChannel, getCurrentChannel, getMyChannelMember} from 'mattermost-redux/selectors/entities/channels';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUserId, getCurrentUser, getStatusForUserId, getUser} from 'mattermost-redux/selectors/entities/users';
import {isChannelMuted} from 'mattermost-redux/utils/channel_utils';
import {isSystemMessage} from 'mattermost-redux/utils/post_utils';

import ChannelStore from 'stores/channel_store.jsx';
import NotificationStore from 'stores/notification_store.jsx';
import UserStore from 'stores/user_store.jsx';
import store from 'stores/redux_store.jsx';
import {displayUsername} from 'mattermost-redux/utils/user_utils';

import Constants, {NotificationLevels, UserStatuses} from 'utils/constants.jsx';
import {isMacApp, isMobileApp, isWindowsApp} from 'utils/user_agent.jsx';
Expand All @@ -18,120 +18,133 @@ import {stripMarkdown} from 'utils/markdown';
const NOTIFY_TEXT_MAX_LENGTH = 50;

export function sendDesktopNotification(post, msgProps) {
if ((UserStore.getCurrentId() === post.user_id && post.props.from_webhook !== 'true')) {
return;
}

if (isSystemMessage(post)) {
return;
}

let mentions = [];
if (msgProps.mentions) {
mentions = JSON.parse(msgProps.mentions);
}
const teamId = msgProps.team_id;

let channel = ChannelStore.get(post.channel_id);
const user = UserStore.getCurrentUser();
const userStatus = UserStore.getStatus(user.id);
const member = ChannelStore.getMyMember(post.channel_id);

if (isChannelMuted(member) || userStatus === UserStatuses.DND || userStatus === UserStatuses.OUT_OF_OFFICE) {
return;
}

let notifyLevel = member && member.notify_props ? member.notify_props.desktop : NotificationLevels.DEFAULT;
if (notifyLevel === NotificationLevels.DEFAULT) {
notifyLevel = user && user.notify_props ? user.notify_props.desktop : NotificationLevels.ALL;
}

if (notifyLevel === NotificationLevels.NONE) {
return;
} else if (notifyLevel === NotificationLevels.MENTION && mentions.indexOf(user.id) === -1 && msgProps.channel_type !== Constants.DM_CHANNEL) {
return;
}

const config = getConfig(store.getState());
let username = Utils.localizeMessage('channel_loader.someone', 'Someone');
if (post.props.override_username && config.EnablePostUsernameOverride === 'true') {
username = post.props.override_username;
} else if (msgProps.sender_name) {
username = msgProps.sender_name;
} else if (UserStore.hasProfile(post.user_id)) {
username = UserStore.getProfile(post.user_id).username;
}

let title = Utils.localizeMessage('channel_loader.posted', 'Posted');
if (!channel) {
title = msgProps.channel_display_name;
channel = {
name: msgProps.channel_name,
type: msgProps.channel_type,
};
} else if (channel.type === Constants.DM_CHANNEL) {
title = Utils.localizeMessage('notification.dm', 'Direct Message');
} else {
title = channel.display_name;
}

if (title === '') {
if (msgProps.channel_type === Constants.DM_CHANNEL) {
title = Utils.localizeMessage('notification.dm', 'Direct Message');
return async (dispatch, getState) => {
const state = getState();
const currentUserId = getCurrentUserId(state);

if ((currentUserId === post.user_id && post.props.from_webhook !== 'true')) {
return;
}

if (isSystemMessage(post)) {
return;
}

let userFromPost = getUser(state, post.user_id);
if (!userFromPost) {
const missingProfileResponse = await dispatch(getProfilesByIds([post.user_id]));
if (missingProfileResponse.data && missingProfileResponse.data.length) {
userFromPost = missingProfileResponse.data[0];
}
}

let mentions = [];
if (msgProps.mentions) {
mentions = JSON.parse(msgProps.mentions);
}
const teamId = msgProps.team_id;

let channel = getChannel(state, post.channel_id);
const user = getCurrentUser(state);
const userStatus = getStatusForUserId(state, user.id);
const member = getMyChannelMember(state, post.channel_id);

if (isChannelMuted(member) || userStatus === UserStatuses.DND || userStatus === UserStatuses.OUT_OF_OFFICE) {
return;
}

let notifyLevel = member && member.notify_props ? member.notify_props.desktop : NotificationLevels.DEFAULT;
if (notifyLevel === NotificationLevels.DEFAULT) {
notifyLevel = user && user.notify_props ? user.notify_props.desktop : NotificationLevels.ALL;
}

if (notifyLevel === NotificationLevels.NONE) {
return;
} else if (notifyLevel === NotificationLevels.MENTION && mentions.indexOf(user.id) === -1 && msgProps.channel_type !== Constants.DM_CHANNEL) {
return;
}

const config = getConfig(state);
let username = '';
if (post.props.override_username && config.EnablePostUsernameOverride === 'true') {
username = post.props.override_username;
} else if (userFromPost) {
username = displayUsername(userFromPost, getTeammateNameDisplaySetting(state), false);
} else {
username = Utils.localizeMessage('channel_loader.someone', 'Someone');
}

let title = Utils.localizeMessage('channel_loader.posted', 'Posted');
if (!channel) {
title = msgProps.channel_display_name;
channel = {
name: msgProps.channel_name,
type: msgProps.channel_type,
};
} else if (channel.type === Constants.DM_CHANNEL) {
title = Utils.localizeMessage('notification.dm', 'Direct Message');
} else {
title = channel.display_name;
}

if (title === '') {
if (msgProps.channel_type === Constants.DM_CHANNEL) {
title = Utils.localizeMessage('notification.dm', 'Direct Message');
} else {
title = msgProps.channel_display_name;
}
}
}

let notifyText = post.message;

const msgPropsPost = JSON.parse(msgProps.post);
const attachments = msgPropsPost && msgPropsPost.props && msgPropsPost.props.attachments ? msgPropsPost.props.attachments : [];
let image = false;
attachments.forEach((attachment) => {
if (notifyText.length === 0) {
notifyText = attachment.fallback ||
attachment.pretext ||
attachment.text;

let notifyText = post.message;

const msgPropsPost = JSON.parse(msgProps.post);
const attachments = msgPropsPost && msgPropsPost.props && msgPropsPost.props.attachments ? msgPropsPost.props.attachments : [];
let image = false;
attachments.forEach((attachment) => {
if (notifyText.length === 0) {
notifyText = attachment.fallback ||
attachment.pretext ||
attachment.text;
}
image |= attachment.image_url.length > 0;
});

let strippedMarkdownNotifyText = stripMarkdown(notifyText);
if (strippedMarkdownNotifyText.length > NOTIFY_TEXT_MAX_LENGTH) {
strippedMarkdownNotifyText = strippedMarkdownNotifyText.substring(0, NOTIFY_TEXT_MAX_LENGTH - 1) + '...';
}
image |= attachment.image_url.length > 0;
});

let strippedMarkdownNotifyText = stripMarkdown(notifyText);
if (strippedMarkdownNotifyText.length > NOTIFY_TEXT_MAX_LENGTH) {
strippedMarkdownNotifyText = strippedMarkdownNotifyText.substring(0, NOTIFY_TEXT_MAX_LENGTH - 1) + '...';
}

let body = '';
if (strippedMarkdownNotifyText.length === 0) {
if (msgProps.image) {
body = username + Utils.localizeMessage('channel_loader.uploadedImage', ' uploaded an image');
} else if (msgProps.otherFile) {
body = username + Utils.localizeMessage('channel_loader.uploadedFile', ' uploaded a file');
} else if (image) {
body = username + Utils.localizeMessage('channel_loader.postedImage', ' posted an image');

let body = `@${username}`;
if (strippedMarkdownNotifyText.length === 0) {
if (msgProps.image) {
body += Utils.localizeMessage('channel_loader.uploadedImage', ' uploaded an image');
} else if (msgProps.otherFile) {
body += Utils.localizeMessage('channel_loader.uploadedFile', ' uploaded a file');
} else if (image) {
body += Utils.localizeMessage('channel_loader.postedImage', ' posted an image');
} else {
body += Utils.localizeMessage('channel_loader.something', ' did something new');
}
} else {
body = username + Utils.localizeMessage('channel_loader.something', ' did something new');
body += `: ${strippedMarkdownNotifyText}`;
}
} else {
body = username + Utils.localizeMessage('channel_loader.wrote', ' wrote: ') + strippedMarkdownNotifyText;
}

//Play a sound if explicitly set in settings
const sound = !user.notify_props || user.notify_props.desktop_sound === 'true';
//Play a sound if explicitly set in settings
const sound = !user.notify_props || user.notify_props.desktop_sound === 'true';

// Notify if you're not looking in the right channel or when
// the window itself is not active
const activeChannel = ChannelStore.getCurrent();
const channelId = channel ? channel.id : null;
const notify = (activeChannel && activeChannel.id !== channelId) || !NotificationStore.getFocus();
// Notify if you're not looking in the right channel or when
// the window itself is not active
const activeChannel = getCurrentChannel(state);
const channelId = channel ? channel.id : null;
const notify = (activeChannel && activeChannel.id !== channelId) || !state.views.browser.focused;

if (notify) {
Utils.notifyMe(title, body, channel, teamId, !sound);
if (notify) {
Utils.notifyMe(title, body, channel, teamId, !sound);

//Don't add extra sounds on native desktop clients
if (sound && !isWindowsApp() && !isMacApp() && !isMobileApp()) {
Utils.ding();
//Don't add extra sounds on native desktop clients
if (sound && !isWindowsApp() && !isMacApp() && !isMobileApp()) {
Utils.ding();
}
}
}
};
}
2 changes: 1 addition & 1 deletion actions/post_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function dispatchPostActions(post, websocketMessageProps) {
websocketMessageProps,
});

sendDesktopNotification(post, websocketMessageProps);
dispatch(sendDesktopNotification(post, websocketMessageProps));
}

export async function flagPost(postId) {
Expand Down
1 change: 0 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1605,7 +1605,6 @@
"channel_loader.unknown_error": "We received an unexpected status code from the server.",
"channel_loader.uploadedFile": " uploaded a file",
"channel_loader.uploadedImage": " uploaded an image",
"channel_loader.wrote": " wrote: ",
"channel_members_dropdown.channel_admin": "Channel Admin",
"channel_members_dropdown.channel_member": "Channel Member",
"channel_members_dropdown.make_channel_admin": "Make Channel Admin",
Expand Down
19 changes: 19 additions & 0 deletions reducers/views/browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {combineReducers} from 'redux';

import {ActionTypes} from 'utils/constants.jsx';

function focused(state = true, action) {
switch (action.type) {
case ActionTypes.BROWSER_CHANGE_FOCUS:
return action.focus;
default:
return state;
}
}

export default combineReducers({
focused,
});
2 changes: 2 additions & 0 deletions reducers/views/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import {combineReducers} from 'redux';

import admin from './admin';
import browser from './browser';
import channel from './channel';
import rhs from './rhs';
import posts from './posts';
Expand All @@ -16,6 +17,7 @@ import notice from './notice';

export default combineReducers({
admin,
browser,
channel,
rhs,
posts,
Expand Down
47 changes: 0 additions & 47 deletions stores/notification_store.jsx

This file was deleted.

Loading

0 comments on commit a19bb02

Please sign in to comment.