Skip to content

Commit

Permalink
[MM-42385] Set title to popout window (#19)
Browse files Browse the repository at this point in the history
* Set title to popout window

* add support for thunks, and the ThunkDispatch type

Co-authored-by: Christopher Poile <cpoile@gmail.com>
  • Loading branch information
streamer45 and cpoile committed Mar 10, 2022
1 parent fa811fe commit 4d14a07
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 17 deletions.
16 changes: 16 additions & 0 deletions e2e/tests/popout.spec.ts
Expand Up @@ -24,5 +24,21 @@ test.describe('popout window', () => {

await devPage.leaveCall();
});

test('window title matches', async ({page, context}) => {
const devPage = new PlaywrightDevPage(page);
await devPage.goto();
await devPage.startCall();

const [popOut, _] = await Promise.all([
context.waitForEvent('page'),
page.click('#calls-widget-expand-button'),
]);
await expect(popOut.locator('#calls-expanded-view')).toBeVisible();
const idx = parseInt(process.env.TEST_PARALLEL_INDEX as string, 10) * 2;
await expect(popOut).toHaveTitle(`Call - calls${idx}`);

await devPage.leaveCall();
});
});

41 changes: 35 additions & 6 deletions webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions webapp/package.json
Expand Up @@ -51,6 +51,7 @@
"mattermost-webapp": "github:mattermost/mattermost-webapp#54a54c3b8da77af256b4ac8182cf4b81afe47561",
"process": "0.11.10",
"react-intl": "5.20.12",
"redux-thunk": "2.4.1",
"sass-loader": "12.1.0",
"style-loader": "3.0.0",
"webpack": "5.41.1",
Expand Down
14 changes: 13 additions & 1 deletion webapp/src/components/expanded_view/component.tsx
Expand Up @@ -4,8 +4,9 @@ import {compareSemVer} from 'semver-parser';
import {OverlayTrigger, Tooltip} from 'react-bootstrap';

import {UserProfile} from 'mattermost-redux/types/users';
import {Channel} from 'mattermost-redux/types/channels';

import {getUserDisplayName, getScreenStream} from 'src/utils';
import {getUserDisplayName, getScreenStream, isDMChannel} from 'src/utils';
import {UserState} from 'src/types/types';

import Avatar from '../avatar/avatar';
Expand Down Expand Up @@ -35,6 +36,8 @@ interface Props {
hideExpandedView: () => void,
showScreenSourceModal: () => void,
screenSharingID: string,
channel: Channel,
connectedDMUser: UserProfile | undefined,
}

interface State {
Expand Down Expand Up @@ -129,6 +132,15 @@ export default class ExpandedView extends React.PureComponent<Props, State> {
}

public componentDidUpdate(prevProps: Props, prevState: State) {
if (document.title.indexOf('Call') === -1 && this.props.channel) {
console.log('missing title');
if (isDMChannel(this.props.channel) && this.props.connectedDMUser) {
document.title = `Call - ${getUserDisplayName(this.props.connectedDMUser)}`;
} else if (!isDMChannel(this.props.channel)) {
document.title = `Call - ${this.props.channel.display_name}`;
}
}

if (this.state.screenStream && this.screenPlayer.current && this.screenPlayer?.current.srcObject !== this.state.screenStream) {
this.screenPlayer.current.srcObject = this.state.screenStream;
}
Expand Down
12 changes: 10 additions & 2 deletions webapp/src/components/expanded_view/index.ts
Expand Up @@ -4,13 +4,13 @@ import {GlobalState} from 'mattermost-redux/types/store';
import {UserProfile} from 'mattermost-redux/types/users';

import {getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';

import {Client4} from 'mattermost-redux/client';

import {UserState} from '../../types/types';

import {alphaSortProfiles, stateSortProfiles} from '../../utils';
import {alphaSortProfiles, stateSortProfiles, isDMChannel, getUserIdFromDM} from '../../utils';
import {hideExpandedView, showScreenSourceModal} from '../../actions';
import {expandedView, voiceChannelCallStartAt, connectedChannelID, voiceConnectedProfiles, voiceUsersStatuses, voiceChannelScreenSharingID} from '../../selectors';

Expand All @@ -32,6 +32,12 @@ const mapStateToProps = (state: GlobalState) => {
pictures[String(profiles[i].id)] = Client4.getProfilePictureUrl(profiles[i].id, profiles[i].last_picture_update);
}

let connectedDMUser;
if (channel && isDMChannel(channel)) {
const otherID = getUserIdFromDM(channel.name, getCurrentUserId(state));
connectedDMUser = getUser(state, otherID);
}

return {
show: expandedView(state),
currentUserID: getCurrentUserId(state),
Expand All @@ -40,6 +46,8 @@ const mapStateToProps = (state: GlobalState) => {
statuses,
callStartAt: voiceChannelCallStartAt(state, channel?.id) || 0,
screenSharingID,
channel,
connectedDMUser,
};
};

Expand Down
36 changes: 28 additions & 8 deletions webapp/src/index.tsx
@@ -1,14 +1,13 @@
import {Store, Action} from 'redux';

import {GlobalState} from 'mattermost-redux/types/store';

import axios from 'axios';

import {getCurrentChannelId, getCurrentChannel, getChannel} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';
import {getMyRoles} from 'mattermost-redux/selectors/entities/roles';
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/common';
import {getChannel as getChannelAction} from 'mattermost-redux/actions/channels';
import {getProfilesByIds as getProfilesByIdsAction} from 'mattermost-redux/actions/users';

import {isVoiceEnabled, connectedChannelID, voiceConnectedUsers, voiceChannelCallStartAt} from './selectors';

Expand All @@ -32,7 +31,15 @@ import LeaveSelfSound from './sounds/leave_self.mp3';

import reducer from './reducers';

import {getPluginPath, getPluginStaticPath, hasPermissionsToEnableCalls, getExpandedChannelID, getProfilesByIds} from './utils';
import {
getPluginPath,
getPluginStaticPath,
hasPermissionsToEnableCalls,
getExpandedChannelID,
getProfilesByIds,
isDMChannel,
getUserIdFromDM,
} from './utils';

import {
VOICE_CHANNEL_ENABLE,
Expand All @@ -57,7 +64,7 @@ import {
} from './action_types';

// eslint-disable-next-line import/no-unresolved
import {PluginRegistry} from './types/mattermost-webapp';
import {PluginRegistry, Store} from './types/mattermost-webapp';

export default class Plugin {
private unsubscribers: (() => void)[];
Expand All @@ -73,7 +80,7 @@ export default class Plugin {
});
}

private registerWebSocketEvents(registry: PluginRegistry, store: Store<GlobalState>) {
private registerWebSocketEvents(registry: PluginRegistry, store: Store) {
registry.registerWebSocketEventHandler(`custom_${pluginId}_channel_enable_voice`, (data) => {
this.unregisterChannelHeaderMenuButton();
this.registerChannelHeaderMenuButton();
Expand Down Expand Up @@ -233,7 +240,7 @@ export default class Plugin {
});
}

public async initialize(registry: PluginRegistry, store: Store<GlobalState>): Promise<void> {
public async initialize(registry: PluginRegistry, store: Store): Promise<void> {
registry.registerReducer(reducer);
const sidebarChannelLinkLabelComponentID = registry.registerSidebarChannelLinkLabelComponent(ChannelLinkLabel);
this.unsubscribers.push(() => registry.unregisterComponent(sidebarChannelLinkLabelComponentID));
Expand Down Expand Up @@ -413,10 +420,23 @@ export default class Plugin {
};

const fetchChannelData = async (channelID: string) => {
const channel = getChannel(store.getState(), channelID);
let channel = getChannel(store.getState(), channelID);
if (!channel) {
await getChannelAction(channelID)(store.dispatch as any, store.getState);
channel = getChannel(store.getState(), channelID);
}

const roles = getMyRoles(store.getState());
const cms = getMyChannelMemberships(store.getState());

if (isDMChannel(channel)) {
const otherID = getUserIdFromDM(channel.name, getCurrentUserId(store.getState()));
const dmUser = getUser(store.getState(), otherID);
if (!dmUser) {
store.dispatch(getProfilesByIdsAction([otherID]));
}
}

try {
const resp = await axios.get(`${getPluginPath()}/config`);
registry.unregisterComponent(channelHeaderMenuID);
Expand Down
11 changes: 11 additions & 0 deletions webapp/src/types/mattermost-webapp/index.d.ts
@@ -1,3 +1,7 @@
import {Store as BaseStore} from 'redux';
import {ThunkDispatch} from 'redux-thunk';
import {GlobalState} from 'mattermost-redux/types/store';

export interface PluginRegistry {
registerPostTypeComponent(typeName: string, component: React.ElementType)
registerReducer(reducer: Reducer)
Expand All @@ -14,3 +18,10 @@ export interface PluginRegistry {
unregisterComponent(componentID: string)
unregisterPostTypeComponent(componentID: string)
}

/**
* Emulated Store type used in mattermost-webapp/mattermost-redux
*/
export type Store = BaseStore<GlobalState> & {dispatch: Dispatch}

export type Dispatch = ThunkDispatch<GlobalState, any, any>

0 comments on commit 4d14a07

Please sign in to comment.