Add mobile compatibility to management UI

This commit is contained in:
Tulir Asokan 2018-11-10 23:29:31 +02:00
parent 9603f59b96
commit 3a36b862df
11 changed files with 147 additions and 12 deletions

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import React, { Component } from "react"
import { Route, Switch, Link } from "react-router-dom"
import { Route, Switch, Link, withRouter } from "react-router-dom"
import api from "../../api"
import { ReactComponent as Plus } from "../../res/plus.svg"
import Instance from "./Instance"
@ -28,10 +28,17 @@ class Dashboard extends Component {
instances: {},
clients: {},
plugins: {},
sidebarOpen: false,
}
window.maubot = this
}
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.setState({ sidebarOpen: false })
}
}
async componentWillMount() {
const [instanceList, clientList, pluginList] = await Promise.all([
api.getInstances(), api.getClients(), api.getPlugins()])
@ -90,15 +97,15 @@ class Dashboard extends Component {
)
render() {
return <div className="dashboard">
return <div className={`dashboard ${this.state.sidebarOpen ? "sidebar-open" : ""}`}>
<Link to="/" className="title">
<img src="/favicon.png" alt=""/>
Maubot Manager
</Link>
<div className="user">
<span>{localStorage.username}</span>
</div>
<nav className="sidebar">
<div className="instances list">
<div className="title">
@ -122,6 +129,14 @@ class Dashboard extends Component {
{this.renderList("plugins", Plugin.ListEntry)}
</div>
</nav>
<div className="topbar">
<div className={`hamburger ${this.state.sidebarOpen ? "active" : ""}`}
onClick={evt => this.setState({ sidebarOpen: !this.state.sidebarOpen })}>
<span/><span/><span/>
</div>
</div>
<main className="view">
<Switch>
<Route path="/" exact render={() => "Hello, World!"}/>
@ -145,4 +160,4 @@ class Dashboard extends Component {
}
}
export default Dashboard
export default withRouter(Dashboard)

View File

@ -23,6 +23,9 @@
> .entry
display: block
@media screen and (max-width: 55rem)
width: calc(100% - 1rem)
width: calc(50% - 1rem)
margin: .5rem

View File

@ -21,6 +21,9 @@
height: 8rem
border-radius: 50%
@media screen and (max-width: 40rem)
margin: 0 auto 1rem
> img.avatar
position: absolute
display: block

View File

@ -16,7 +16,6 @@
> div.client
display: flex
margin: 2rem 4rem
> div.sidebar
vertical-align: top
@ -36,3 +35,10 @@
> div.instances
+instancelist
@media screen and (max-width: 40rem)
flex-wrap: wrap
> div.sidebar, > div.info
width: 100%
margin-right: 0

View File

@ -5,3 +5,22 @@
[row3-start] "sidebar main" auto [row3-end]
/ 15rem auto;
}
@media screen and (max-width: 35rem) {
.dashboard {
grid-template:
[row1-start] "topbar" 3.5rem [row1-end]
[row2-start] "main" auto [row2-end]
/ auto;
}
.dashboard.sidebar-open {
grid-template:
[row1-start] "title topbar" 3.5rem [row1-end]
[row2-start] "user main" 2.5rem [row2-end]
[row3-start] "sidebar main" auto [row3-end]
/ 15rem 100%;
overflow-x: hidden;
}
}

View File

@ -60,11 +60,19 @@
border-radius: .25rem
@import sidebar
@import topbar
@media screen and (max-width: 35rem)
&:not(.sidebar-open)
> nav.sidebar, > a.title, > div.user
display: none !important
> main.view
grid-area: main
border-left: 1px solid $border-color
overflow-y: scroll
@import client/index
@import instance
@import plugin
@ -74,6 +82,12 @@
margin-top: 5rem
font-size: 1.5rem
> div:not(.not-found)
margin: 2rem 4rem
@media screen and (max-width: 50rem)
margin: 2rem 1rem
div.buttons
+button-group
display: flex

View File

@ -15,8 +15,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
> div.instance
margin: 2rem 4rem
> div.preference-table
.select-client
display: flex

View File

@ -28,6 +28,10 @@
border-radius: .25rem
margin-top: 3rem
@media screen and (max-width: 27rem)
margin: 3rem 1rem 0
width: calc(100% - 2rem)
h1
color: $primary
margin: 3rem 0
@ -35,13 +39,14 @@
input, button
margin: .5rem 2.5rem
height: 3rem
width: 20rem
width: calc(100% - 5rem)
box-sizing: border-box
input
+input
button
+button($width: 20rem, $height: 3rem, $padding: 0)
+button($width: calc(100% - 5rem), $height: 3rem, $padding: 0)
+main-color-button
.spinner

View File

@ -15,8 +15,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
> .plugin
margin: 2rem 4rem
> .upload-box
+upload-box

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
> .sidebar
> nav.sidebar
grid-area: sidebar
background-color: white

View File

@ -0,0 +1,74 @@
// maubot - A plugin-based Matrix bot system.
// Copyright (C) 2018 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
.topbar
background-color: $primary
display: flex
justify-items: center
align-items: center
padding: 0 .75rem
@media screen and (min-width: calc(35rem + 1px))
display: none
// Hamburger menu based on "Pure CSS Hamburger fold-out menu" codepen by Erik Terwan (MIT license)
// https://codepen.io/erikterwan/pen/EVzeRP
.hamburger
display: block
user-select: none
cursor: pointer
> span
display: block
width: 29px
height: 4px
margin-bottom: 5px
position: relative
background: white
border-radius: 3px
z-index: 1
transform-origin: 4px 0
//transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), background 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0), opacity 0.55s ease
&:nth-of-type(1)
transform-origin: 0 0
&:nth-of-type(3)
transform-origin: 0 100%
transform: translateY(2px)
&.active
transform: translateX(1px) translateY(4px)
&.active > span
opacity: 1
&:nth-of-type(1)
transform: rotate(45deg) translate(-2px, -1px)
&:nth-of-type(2)
opacity: 0
transform: rotate(0deg) scale(0.2, 0.2)
&:nth-of-type(3)
transform: rotate(-45deg) translate(0, -1px)