Skip to content

Commit

Permalink
MM-53809 - Prevent desktop notification when the calls thread is open…
Browse files Browse the repository at this point in the history
… in the expanded view (#485)

* no ping when we have the thread open in the expanded view (webapp only)

* Revert "no ping when we have the thread open in the expanded view (webapp only)"

This reverts commit 967f80f17cd15965372ccee2ca91e58b42d61072.

* do not notify if the user is in the notification thread's call

* but do notify if they were directly mentioned

* PR comment: rename selectors
  • Loading branch information
cpoile authored Sep 8, 2023
1 parent d693d45 commit 00a57a6
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 9 deletions.
4 changes: 2 additions & 2 deletions webapp/src/components/expanded_view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
hostIDForCurrentCall,
hostChangeAtForCurrentCall,
callStartAtForCurrentCall,
callThreadIDForCallInChannel,
threadIDForCallInChannel,
screenSharingIDForCurrentCall,
usersStatusesInCurrentCall,
profilesInCurrentCall,
Expand All @@ -44,7 +44,7 @@ const mapStateToProps = (state: GlobalState) => {
const channel = channelForCurrentCall(state);
const channelTeam = getTeam(state, channel?.team_id || '');
const screenSharingID = screenSharingIDForCurrentCall(state);
const threadID = callThreadIDForCallInChannel(state, channel?.id || '');
const threadID = threadIDForCallInChannel(state, channel?.id || '');

const sortedProfiles = (profiles: UserProfile[], statuses: { [key: string]: UserState }) => {
return [...profiles].sort(alphaSortProfiles).sort(stateSortProfiles(profiles, statuses, screenSharingID, true));
Expand Down
30 changes: 28 additions & 2 deletions webapp/src/desktop_notifications.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import {Channel} from '@mattermost/types/channels';
import {Post} from '@mattermost/types/posts';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {DesktopNotificationArgs, Store} from 'src/types/mattermost-webapp';

import {CALL_START_POST_TYPE} from 'src/constants';
import {ringingEnabled} from 'src/selectors';
import {
threadIDForCurrentCall,
channelIDForCurrentCall,
ringingEnabled,
} from 'src/selectors';
import {RealNewPostMessageProps} from 'src/types/types';
import {isDmGmChannel} from 'src/utils';

export function desktopNotificationHandler(store: Store, post: Post, channel: Channel, args: DesktopNotificationArgs): {error?: string, args?: DesktopNotificationArgs} {
export function desktopNotificationHandler(
store: Store,
post: Post,
msgProps: RealNewPostMessageProps,
channel: Channel,
args: DesktopNotificationArgs,
): { error?: string, args?: DesktopNotificationArgs } {
if (args.notify) {
// Calls will notify if:
// 1. it's a custom_calls post (call has started)
Expand All @@ -21,6 +33,20 @@ export function desktopNotificationHandler(store: Store, post: Post, channel: Ch
ringingEnabled(store.getState())) {
return {args: {...args, notify: false}};
}

// Do not notify for a call's thread if the user is currently in that call...
if (channelIDForCurrentCall(store.getState()) === post.channel_id &&
threadIDForCurrentCall(store.getState()) === post.root_id) {
let mentions = [];
if (msgProps.mentions) {
mentions = JSON.parse(msgProps.mentions);
}

// ...and wasn't directly mentioned.
if (!mentions.includes(getCurrentUserId(store.getState()))) {
return {args: {...args, notify: false}};
}
}
}

return {args};
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ export default class Plugin {
});

registry.registerDesktopNotificationHook?.(async (post, msgProps, channel, teamId, args) => {
return desktopNotificationHandler(store, post, channel, args);
return desktopNotificationHandler(store, post, msgProps, channel, args);
});

const connectToCall = async (channelId: string, teamId: string, title?: string, rootId?: string) => {
Expand Down
5 changes: 4 additions & 1 deletion webapp/src/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,13 @@ export const screenSharingIDForCurrentCall: (state: GlobalState) => string =
(ids, channelID) => ids[channelID] || '',
);

export const callThreadIDForCallInChannel = (state: GlobalState, channelID: string) => {
export const threadIDForCallInChannel = (state: GlobalState, channelID: string) => {
return pluginState(state).calls[channelID]?.threadID || '';
};

export const threadIDForCurrentCall = (state: GlobalState) =>
callInCurrentChannel(state).threadID;

const recordingsForCalls = (state: GlobalState): callsRecordingsState => {
return pluginState(state).recordings;
};
Expand Down
4 changes: 3 additions & 1 deletion webapp/src/types/mattermost-webapp/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {GlobalState} from '@mattermost/types/store';
import {Store as BaseStore} from 'redux';
import {ThunkDispatch} from 'redux-thunk';

import {RealNewPostMessageProps} from 'src/types/types';

export type Translations = {
[key: string]: string;
};
Expand Down Expand Up @@ -49,7 +51,7 @@ export interface PluginRegistry {
registerSlashCommandWillBePostedHook(hook: (message: string, args: CommandArgs) => SlashCommandWillBePostedReturn);

// registerDesktopNotificationHook requires MM v8.1
registerDesktopNotificationHook(hook: (post: Post, msgProps: NewPostMessageProps, channel: Channel, teamId: string, args: DesktopNotificationArgs) => Promise<{
registerDesktopNotificationHook(hook: (post: Post, msgProps: RealNewPostMessageProps, channel: Channel, teamId: string, args: DesktopNotificationArgs) => Promise<{
error?: string;
args?: DesktopNotificationArgs;
}>)
Expand Down
11 changes: 11 additions & 0 deletions webapp/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,14 @@ export const UserStatuses = {
ONLINE: 'online',
DND: 'dnd',
};

export type RealNewPostMessageProps = {
channel_display_name: string;
channel_name: string;
channel_type: ChannelType;
mentions: string; // JSON string[]
post: string; // JSON Post
sender_name: string; // @username
set_online: boolean;
team_id: string;
}
4 changes: 2 additions & 2 deletions webapp/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import CallsClient from 'src/client';

import {logDebug, logErr, logWarn} from './log';
import {pluginId} from './manifest';
import {callThreadIDForCallInChannel} from './selectors';
import {threadIDForCallInChannel} from './selectors';
import JoinSelfSound from './sounds/join_self.mp3';
import JoinUserSound from './sounds/join_user.mp3';
import LeaveSelfSound from './sounds/leave_self.mp3';
Expand Down Expand Up @@ -345,7 +345,7 @@ export async function followThread(store: Store, channelID: string, teamID: stri
logDebug('followThread: no team for channel');
return;
}
const threadID = callThreadIDForCallInChannel(store.getState(), channelID);
const threadID = threadIDForCallInChannel(store.getState(), channelID);
if (threadID) {
store.dispatch(setThreadFollow(getCurrentUserId(store.getState()), teamID, threadID, true));
} else {
Expand Down

0 comments on commit 00a57a6

Please sign in to comment.