[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:
@@ -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}
|
||||
|
@@ -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
|
||||
|
63
src/renderer/components/TeamDropdownButton.tsx
Normal file
63
src/renderer/components/TeamDropdownButton.tsx
Normal 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;
|
Reference in New Issue
Block a user