[MM-36421] Replace server tabs with dropdown menu (#1647)

* WIP

* WIP

* PoC for dropdown - logic stuff

* Most of the logic for the dropdown

* Working dropdown menu to pick servers

* Mentions, unreads and expired working. Many styles are working.

* Some more styles

* Dark mode and other stuff

* Some cleanup

* Generate build

* PR feedback

* More PR feedback
This commit is contained in:
Devin Binnie
2021-07-07 18:49:48 -04:00
committed by GitHub
parent 4130c2c37d
commit 880af87ddf
32 changed files with 1792 additions and 117 deletions

View File

@@ -36,6 +36,8 @@ import {
ADD_SERVER,
FOCUS_THREE_DOT_MENU,
GET_FULL_SCREEN_STATUS,
CLOSE_TEAMS_DROPDOWN,
OPEN_TEAMS_DROPDOWN,
} from 'common/communication';
import restoreButton from '../../assets/titlebar/chrome-restore.svg';
@@ -48,6 +50,7 @@ import {playSound} from '../notificationSounds';
import TabBar from './TabBar';
import ExtraBar from './ExtraBar';
import ErrorView from './ErrorView';
import TeamDropdownButton from './TeamDropdownButton';
enum Status {
LOADING = 1,
@@ -78,6 +81,7 @@ type State = {
modalOpen?: boolean;
fullScreen?: boolean;
showExtraBar?: boolean;
isMenuOpen: boolean;
};
type TabStatus = {
@@ -107,6 +111,7 @@ export default class MainPage extends React.PureComponent<Props, State> {
maximized: false,
tabStatus: new Map(this.props.teams.map((server) => [server.name, {status: Status.LOADING}])),
darkMode: this.props.darkMode,
isMenuOpen: false,
};
}
@@ -228,6 +233,14 @@ export default class MainPage extends React.PureComponent<Props, State> {
this.setState({unreadCounts: newUnreads, mentionCounts: newMentionCounts, sessionsExpired: expired});
});
window.ipcRenderer.on(CLOSE_TEAMS_DROPDOWN, () => {
this.setState({isMenuOpen: false});
});
window.ipcRenderer.on(OPEN_TEAMS_DROPDOWN, () => {
this.setState({isMenuOpen: true});
});
if (window.process.platform !== 'darwin') {
window.ipcRenderer.on(FOCUS_THREE_DOT_MENU, () => {
if (this.threeDotMenu.current) {
@@ -305,6 +318,7 @@ export default class MainPage extends React.PureComponent<Props, State> {
focusOnWebView = () => {
window.ipcRenderer.send(FOCUS_BROWSERVIEW);
window.ipcRenderer.send(CLOSE_TEAMS_DROPDOWN);
}
render() {
@@ -385,6 +399,8 @@ export default class MainPage extends React.PureComponent<Props, State> {
);
}
const totalMentionCount = Object.values(this.state.mentionCounts).reduce((sum, value) => sum + value, 0);
const totalUnreadCount = Object.values(this.state.unreadCounts).reduce((sum, value) => sum + value, 0);
const topRow = (
<Row
className={topBarClassName}
@@ -403,6 +419,13 @@ export default class MainPage extends React.PureComponent<Props, State> {
>
<DotsVerticalIcon/>
</button>
<TeamDropdownButton
activeServerName={this.props.teams[this.state.key].name}
totalMentionCount={totalMentionCount}
hasUnreads={totalUnreadCount > 0}
isMenuOpen={this.state.isMenuOpen}
darkMode={this.state.darkMode}
/>
{tabsRow}
{overlayGradient}
{titleBarButtons}

View File

@@ -165,6 +165,8 @@ export default class TabBar extends React.PureComponent<Props, State> { // need
);
}
// TODO: Replace with products
tabs.length = 0;
return (
<DragDropContext onDragEnd={this.props.onDrop}>
<Droppable

View File

@@ -0,0 +1,63 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import classNames from 'classnames';
import React from 'react';
import {CLOSE_TEAMS_DROPDOWN, OPEN_TEAMS_DROPDOWN} from 'common/communication';
import '../css/components/TeamDropdownButton.scss';
import '../css/compass-icons.css';
type Props = {
activeServerName: string;
totalMentionCount: number;
hasUnreads: boolean;
isMenuOpen: boolean;
darkMode: boolean;
}
const TeamDropdownButton: React.FC<Props> = (props: Props) => {
const {activeServerName, totalMentionCount, hasUnreads, isMenuOpen, darkMode} = props;
const handleToggleButton = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
event.stopPropagation();
window.ipcRenderer.send(isMenuOpen ? CLOSE_TEAMS_DROPDOWN : OPEN_TEAMS_DROPDOWN);
};
let badgeDiv: React.ReactNode;
if (totalMentionCount > 0) {
badgeDiv = (
<div className='TeamDropdownButton__badge-count'>
<span>{totalMentionCount > 99 ? '99+' : totalMentionCount}</span>
</div>
);
} else if (hasUnreads) {
badgeDiv = (
<div className='TeamDropdownButton__badge-unreads'/>
);
}
return (
<button
className={classNames('TeamDropdownButton', {
isMenuOpen,
darkMode,
})}
onClick={handleToggleButton}
onDoubleClick={(event) => {
event.stopPropagation();
}}
>
<div className='TeamDropdownButton__badge'>
<i className='icon-server-variant'/>
{badgeDiv}
</div>
<span>{activeServerName}</span>
<i className='icon-chevron-down'/>
</button>
);
};
export default TeamDropdownButton;