Webatrice: Update nav (#4380)
* wip: subnav debug * nav redesign * remove unnecessary code * remove subnav * add leaveRoom button Co-authored-by: Jeremy Letto <jeremy.letto@datasite.com>
This commit is contained in:
parent
da9222929b
commit
c9ddd042fc
7 changed files with 205 additions and 115 deletions
|
@ -38,11 +38,74 @@
|
||||||
.Header-nav {
|
.Header-nav {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Header-nav__menu {
|
.Header-nav__links {
|
||||||
margin-left: 10px;
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
padding-left: 50px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link:hover {
|
||||||
|
background: rgba(0, 0, 0, .125);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link:hover .Header-nav__link-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link-btn {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link-btn__icon {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link-menu {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
transform: translateY(100%);
|
||||||
|
min-width: 150px;
|
||||||
|
background: #3f51b5;
|
||||||
|
box-shadow: 1px 1px 2px 0px black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link-menu__item {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__link-menu__btn {
|
||||||
|
padding: 6px 16px;
|
||||||
|
width: 100%;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__actions {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__action {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.Header-nav__action button {
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.temp-subnav__rooms {
|
.temp-subnav__rooms {
|
||||||
|
|
|
@ -2,11 +2,13 @@ import React, { Component } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { NavLink, withRouter, generatePath } from "react-router-dom";
|
import { NavLink, withRouter, generatePath } from "react-router-dom";
|
||||||
import AppBar from "@material-ui/core/AppBar";
|
import AppBar from "@material-ui/core/AppBar";
|
||||||
import Chip from "@material-ui/core/Chip";
|
|
||||||
import IconButton from "@material-ui/core/IconButton";
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import Menu from "@material-ui/core/Menu";
|
import Menu from "@material-ui/core/Menu";
|
||||||
import MenuItem from "@material-ui/core/MenuItem";
|
import MenuItem from "@material-ui/core/MenuItem";
|
||||||
import Toolbar from "@material-ui/core/Toolbar";
|
import Toolbar from "@material-ui/core/Toolbar";
|
||||||
|
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
|
||||||
|
import CloseIcon from '@material-ui/icons/Close';
|
||||||
|
import MailOutlineRoundedIcon from '@material-ui/icons/MailOutline';
|
||||||
import MenuRoundedIcon from '@material-ui/icons/MenuRounded';
|
import MenuRoundedIcon from '@material-ui/icons/MenuRounded';
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
|
|
||||||
|
@ -21,20 +23,18 @@ class Header extends Component<HeaderProps> {
|
||||||
state: HeaderState;
|
state: HeaderState;
|
||||||
options: string[] = [
|
options: string[] = [
|
||||||
'Account',
|
'Account',
|
||||||
'Decks',
|
|
||||||
'Replays',
|
'Replays',
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = { anchorEl: null };
|
||||||
anchorEl: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.handleMenuClick = this.handleMenuClick.bind(this);
|
this.handleMenuOpen = this.handleMenuOpen.bind(this);
|
||||||
this.handleMenuItemClick = this.handleMenuItemClick.bind(this);
|
this.handleMenuItemClick = this.handleMenuItemClick.bind(this);
|
||||||
this.handleMenuClose = this.handleMenuClose.bind(this);
|
this.handleMenuClose = this.handleMenuClose.bind(this);
|
||||||
|
this.leaveRoom = this.leaveRoom.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
|
@ -47,24 +47,28 @@ class Header extends Component<HeaderProps> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMenuClick({ target }) {
|
handleMenuOpen(event) {
|
||||||
this.setState({ anchorEl: target });
|
this.setState({ anchorEl: event.target });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMenuItemClick(option: string) {
|
handleMenuItemClick(option: string) {
|
||||||
const route = RouteEnum[option.toUpperCase()];
|
const route = RouteEnum[option.toUpperCase()];
|
||||||
this.props.history.push(generatePath(route));
|
this.props.history.push(generatePath(route));
|
||||||
|
|
||||||
this.handleMenuClose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMenuClose() {
|
handleMenuClose() {
|
||||||
this.setState({ anchorEl: null });
|
this.setState({ anchorEl: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leaveRoom(event, roomId) {
|
||||||
|
event.preventDefault();
|
||||||
|
RoomsService.leaveRoom(roomId);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { joinedRooms, server, state, user } = this.props;
|
const { joinedRooms, state, user } = this.props;
|
||||||
const anchorEl = this.state.anchorEl;
|
const { anchorEl } = this.state;
|
||||||
|
|
||||||
let options = [ ...this.options ];
|
let options = [ ...this.options ];
|
||||||
|
|
||||||
if (user && AuthenticationService.isModerator(user)) {
|
if (user && AuthenticationService.isModerator(user)) {
|
||||||
|
@ -76,36 +80,70 @@ class Header extends Component<HeaderProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<AppBar className="Header" position="static">
|
||||||
{/*<header className="Header">*/}
|
<Toolbar variant="dense">
|
||||||
<AppBar position="static">
|
<div className="Header__logo">
|
||||||
<Toolbar variant="dense">
|
<NavLink to={RouteEnum.SERVER}>
|
||||||
<div className="Header__logo">
|
<img src={logo} alt="logo" />
|
||||||
<NavLink to={RouteEnum.SERVER}>
|
</NavLink>
|
||||||
<img src={logo} alt="logo" />
|
|
||||||
</NavLink>
|
|
||||||
{ AuthenticationService.isConnected(state) && (
|
|
||||||
<span className="Header-server__indicator"></span>
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
{ AuthenticationService.isConnected(state) && (
|
{ AuthenticationService.isConnected(state) && (
|
||||||
<div className="Header-content">
|
<span className="Header-server__indicator"></span>
|
||||||
<nav className="Header-nav">
|
) }
|
||||||
<div className="Header-nav__menu">
|
</div>
|
||||||
<IconButton
|
{ AuthenticationService.isConnected(state) && (
|
||||||
aria-label="more"
|
<div className="Header-content">
|
||||||
aria-controls="long-menu"
|
<nav className="Header-nav">
|
||||||
aria-haspopup="true"
|
<nav className="Header-nav__links">
|
||||||
onClick={this.handleMenuClick}
|
<div className="Header-nav__link">
|
||||||
|
<NavLink
|
||||||
|
className="Header-nav__link-btn"
|
||||||
|
to={ joinedRooms.length ? generatePath(RouteEnum.ROOM, { roomId: joinedRooms[0].roomId }) : RouteEnum.SERVER }
|
||||||
>
|
>
|
||||||
<MenuRoundedIcon />
|
Rooms
|
||||||
|
<ArrowDropDownIcon className="Header-nav__link-btn__icon" fontSize="small" />
|
||||||
|
</NavLink>
|
||||||
|
<div className="Header-nav__link-menu">
|
||||||
|
{joinedRooms.map(({ name, roomId }) => (
|
||||||
|
<MenuItem className="Header-nav__link-menu__item" key={roomId}>
|
||||||
|
<NavLink className="Header-nav__link-menu__btn" to={ generatePath(RouteEnum.ROOM, { roomId: roomId }) }>
|
||||||
|
{name}
|
||||||
|
|
||||||
|
<IconButton size="small" edge="end" onClick={event => this.leaveRoom(event, roomId)}>
|
||||||
|
<CloseIcon style={{ fontSize: 10, color: 'white' }} />
|
||||||
|
</IconButton>
|
||||||
|
</NavLink>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="Header-nav__link">
|
||||||
|
<NavLink className="Header-nav__link-btn" to={ RouteEnum.GAME }>
|
||||||
|
Games
|
||||||
|
<ArrowDropDownIcon className="Header-nav__link-btn__icon" fontSize="small" />
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
<div className="Header-nav__link">
|
||||||
|
<NavLink className="Header-nav__link-btn" to={ RouteEnum.DECKS }>
|
||||||
|
Decks
|
||||||
|
<ArrowDropDownIcon className="Header-nav__link-btn__icon" fontSize="small" />
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div className="Header-nav__actions">
|
||||||
|
<div className="Header-nav__action">
|
||||||
|
<IconButton>
|
||||||
|
<MailOutlineRoundedIcon style={{ color: 'inherit' }} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
<div className="Header-nav__action">
|
||||||
|
<IconButton onClick={this.handleMenuOpen}>
|
||||||
|
<MenuRoundedIcon style={{ color: 'inherit' }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu
|
<Menu
|
||||||
id="long-menu"
|
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
keepMounted
|
keepMounted
|
||||||
open={!!anchorEl}
|
open={!!anchorEl}
|
||||||
onClose={this.handleMenuClose}
|
onClose={() => this.handleMenuClose()}
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
style: {
|
style: {
|
||||||
marginTop: '32px',
|
marginTop: '32px',
|
||||||
|
@ -114,55 +152,22 @@ class Header extends Component<HeaderProps> {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{options.map((option) => (
|
{options.map((option) => (
|
||||||
<MenuItem key={option} onClick={() => this.handleMenuItemClick(option)}>
|
<MenuItem key={option} onClick={(event) => this.handleMenuItemClick(option)}>
|
||||||
{option}
|
{option}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
) }
|
</div>
|
||||||
</Toolbar>
|
) }
|
||||||
</AppBar>
|
</Toolbar>
|
||||||
<div className="temp-subnav">
|
</AppBar>
|
||||||
{
|
|
||||||
!!joinedRooms.length && (
|
|
||||||
<Rooms rooms={joinedRooms} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<div className="temp-subnav__games">
|
|
||||||
</div>
|
|
||||||
<div className="temp-subnav__chats">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Rooms = props => {
|
|
||||||
|
|
||||||
const onLeaveRoom = (event, roomId) => {
|
|
||||||
event.preventDefault();
|
|
||||||
RoomsService.leaveRoom(roomId);
|
|
||||||
};
|
|
||||||
|
|
||||||
return <div className="temp-subnav__rooms">
|
|
||||||
<span>Rooms: </span>
|
|
||||||
{
|
|
||||||
_.reduce(props.rooms, (rooms, { name, roomId}) => {
|
|
||||||
rooms.push(
|
|
||||||
<NavLink to={generatePath(RouteEnum.ROOM, { roomId })} className="temp-chip" key={roomId}>
|
|
||||||
<Chip label={name} color="primary" onDelete={(event) => onLeaveRoom(event, roomId)} />
|
|
||||||
</NavLink>
|
|
||||||
);
|
|
||||||
return rooms;
|
|
||||||
}, [])
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
state: number;
|
state: number;
|
||||||
server: string;
|
server: string;
|
||||||
|
@ -172,7 +177,7 @@ interface HeaderProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HeaderState {
|
interface HeaderState {
|
||||||
anchorEl: Element;
|
anchorEl: Element
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
|
|
|
@ -26,9 +26,11 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.three-pane-layout .grid-main__top.fixedHeight,
|
.three-pane-layout .grid-main__top.fixedHeight,
|
||||||
.three-pane-layout .grid-main__bottom.fixedHeight {
|
.three-pane-layout .grid-main__bottom.fixedHeight {
|
||||||
height: 50%;
|
height: 50%;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.room-view,
|
.room-view,
|
||||||
|
.room-view__main,
|
||||||
.room-view__games,
|
.room-view__games,
|
||||||
.room-view__messages,
|
.room-view__messages,
|
||||||
.room-view__messages-content,
|
.room-view__messages-content,
|
||||||
|
@ -6,12 +7,17 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.room-view,
|
||||||
.room-view__messages,
|
.room-view__messages,
|
||||||
.room-view__side {
|
.room-view__side {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.room-view__main {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.room-view__messages-sayMessage {
|
.room-view__messages-sayMessage {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 10px auto 2px;
|
margin: 10px auto 2px;
|
||||||
|
|
|
@ -53,45 +53,48 @@ class Room extends Component<any> {
|
||||||
return (
|
return (
|
||||||
<div className="room-view">
|
<div className="room-view">
|
||||||
<AuthGuard />
|
<AuthGuard />
|
||||||
<ThreePaneLayout
|
|
||||||
fixedHeight
|
|
||||||
|
|
||||||
top={(
|
<div className="room-view__main">
|
||||||
<Paper className="room-view__games overflow-scroll">
|
<ThreePaneLayout
|
||||||
<Games room={room} />
|
fixedHeight
|
||||||
</Paper>
|
|
||||||
)}
|
|
||||||
|
|
||||||
bottom={(
|
top={(
|
||||||
<div className="room-view__messages">
|
<Paper className="room-view__games overflow-scroll">
|
||||||
<Paper className="room-view__messages-content overflow-scroll">
|
<Games room={room} />
|
||||||
<ScrollToBottomOnChanges changes={messages} content={(
|
</Paper>
|
||||||
<Messages messages={messages} />
|
)}
|
||||||
)} />
|
|
||||||
</Paper>
|
|
||||||
<Paper className="room-view__messages-sayMessage">
|
|
||||||
<SayMessage onSubmit={this.handleRoomSay} />
|
|
||||||
</Paper>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
side={(
|
bottom={(
|
||||||
<Paper className="room-view__side overflow-scroll">
|
<div className="room-view__messages">
|
||||||
<div className="room-view__side-label">
|
<Paper className="room-view__messages-content overflow-scroll">
|
||||||
Users in this room: {users.length}
|
<ScrollToBottomOnChanges changes={messages} content={(
|
||||||
|
<Messages messages={messages} />
|
||||||
|
)} />
|
||||||
|
</Paper>
|
||||||
|
<Paper className="room-view__messages-sayMessage">
|
||||||
|
<SayMessage onSubmit={this.handleRoomSay} />
|
||||||
|
</Paper>
|
||||||
</div>
|
</div>
|
||||||
<VirtualList
|
)}
|
||||||
className="room-view__side-list"
|
|
||||||
itemKey={(index, data) => users[index].name }
|
side={(
|
||||||
items={ users.map(user => (
|
<Paper className="room-view__side overflow-scroll">
|
||||||
<ListItem button className="room-view__side-list__item">
|
<div className="room-view__side-label">
|
||||||
<UserDisplay user={user} />
|
Users in this room: {users.length}
|
||||||
</ListItem>
|
</div>
|
||||||
) ) }
|
<VirtualList
|
||||||
/>
|
className="room-view__side-list"
|
||||||
</Paper>
|
itemKey={(index, data) => users[index].name }
|
||||||
)}
|
items={ users.map(user => (
|
||||||
/>
|
<ListItem button className="room-view__side-list__item">
|
||||||
|
<UserDisplay user={user} />
|
||||||
|
</ListItem>
|
||||||
|
) ) }
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,9 @@ const ServerRooms = ({ rooms, joinedRooms, history, message, users}) => (
|
||||||
)}
|
)}
|
||||||
|
|
||||||
bottom={(
|
bottom={(
|
||||||
<Paper className="serverMessage overflow-scroll" dangerouslySetInnerHTML={{ __html: message }} />
|
<Paper className="serverMessage overflow-scroll">
|
||||||
|
<div className="serverMessage__content" dangerouslySetInnerHTML={{ __html: message }} />
|
||||||
|
</Paper>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
side={(
|
side={(
|
||||||
|
|
|
@ -40,6 +40,11 @@ b {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.overflow-scroll {
|
.overflow-scroll {
|
||||||
overflow-y: scroll; /* has to be scroll, not auto */
|
overflow-y: scroll; /* has to be scroll, not auto */
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
|
@ -54,4 +59,8 @@ b {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled-link {
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
Loading…
Reference in a new issue