Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #167 UI adjust & tabs UI fix #179

Merged
merged 4 commits into from
Jan 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/client/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
export const contextMenuHeight = 28
export const contextMenuPaddingTop = 10
export const maxHistory = 50
//export const maxTabs = 20
export const tabWidth = 120
export const tabMargin = 3
export const statusMap = {
default: 'default',
success: 'success',
Expand Down
170 changes: 148 additions & 22 deletions src/client/components/control/tabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,166 @@
* @param {array} props.tabs {id, title}
*/

import {Icon, Tooltip} from 'antd'
import React from 'react'
import _ from 'lodash'
import {Icon, Button, Dropdown, Menu} from 'antd'
import Tab from './tab'
import './tabs.styl'
import {tabWidth, tabMargin} from '../../common/constants'
import createName from '../../common/create-title'

const ButtonGroup = Button.Group
const MenuItem = Menu.Item
const extraWidth = 113
//todo: scroll controll and keyboard controll
//todo: drag and drop

export default function Tabs(props) {

let {tabs = [], onAdd} = props
return (
<div className="tabs">
<div className="tabs-bg" onDoubleClick={onAdd} />
<div className="tabs-inner">

export default class Tabs extends React.Component {

componentDidMount() {
this.dom = document.querySelector('.tabs-inner')
}

componentDidUpdate() {
this.adjustScroll()
}

adjustScroll = () => {
let {width, tabs, currentTabId} = this.props
let index = _.findIndex(tabs, t => t.id === currentTabId)
let w = (index + 1) * (tabMargin + tabWidth) + 5
let scrollLeft = w > width - extraWidth
? w - width + extraWidth
: 0
this.dom.scrollLeft = scrollLeft
}

scrollLeft = () => {
let {scrollLeft} = this.dom
scrollLeft = scrollLeft - tabMargin - tabWidth
if (scrollLeft < 0) {
scrollLeft = 0
}
this.dom.scrollLeft = scrollLeft
}

scrollRight = () => {
let {scrollLeft} = this.dom
scrollLeft = scrollLeft + tabMargin + tabWidth
if (scrollLeft < 0) {
scrollLeft = 0
}
this.dom.scrollLeft = scrollLeft
}

onClickMenu = ({key}) => {
let id = key.split('##')[1]
this.props.onChange(id)
}

renderList = () => {
let {tabs = []} = this.props
return (
<Menu onClick={this.onClickMenu}>
{
tabs.map((tab, i) => {
tabs.map((t, i) => {
return (
<Tab
{...props}
tab={tab}
key={i + 'tab'}
/>
<MenuItem
key={i + '##' + t.id}
>{createName(t)}
</MenuItem>
)
})
}
</Menu>
)
}

renderAddBtn = () => {
return (
<Icon
type="plus-circle-o"
title="open new terminal"
className="pointer tabs-add-btn font16"
onClick={this.props.onAdd}
/>
)
}

renderExtra() {
return (
<div className="tabs-extra pd1x">
{this.renderAddBtn()}
<ButtonGroup className="iblock mg1x">
<Button
icon="left"
onClick={this.scrollLeft}
/>
<Button
icon="right"
onClick={this.scrollRight}
/>
</ButtonGroup>
<Dropdown
className="iblock"
placement="bottomRight"
overlay={this.renderList()}
>
<Icon type="down" />
</Dropdown>
</div>
)
}

render() {
let {tabs = [], onAdd, width} = this.props
let len = tabs.length
let addBtnWidth = 22
let tabsWidthAll = (tabMargin + tabWidth) * len + 10
let overflow = width < (tabsWidthAll + addBtnWidth)
//let extraw = overflow ? extraWidth : 0
return (
<div className="tabs">
<div className="tabs-bg" onDoubleClick={onAdd} />
<div
className="tabs-inner"
style={{
width
}}
>
<div
className="tabs-wrapper"
style={{
width: tabsWidthAll + extraWidth + 10
}}
>
{
tabs.map((tab, i) => {
return (
<Tab
{...this.props}
tab={tab}
key={i + 'tab'}
/>
)
})
}
{
!overflow
? this.renderAddBtn()
: null
}
</div>
</div>
{
overflow
? this.renderExtra()
: null
}
</div>
<Tooltip title="open new terminal" placement="rightTop">
<Icon
type="plus-circle-o"
className="pointer tabs-add-btn font16"
onClick={onAdd}
/>
</Tooltip>
</div>
)
)
}

}
26 changes: 17 additions & 9 deletions src/client/components/control/tabs.styl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.tabs
position relative
background #ccc
min-height 46px
height 46px
overflow hidden
.tabs-bg
position absolute
left 0
Expand All @@ -12,9 +12,11 @@
.tabs-inner
position relative
z-index 2
padding 0 30px 0 10px
padding 0 5px
display inline-block

height 63px
overflow-x scroll
overflow-y hidden
.tab
display inline-block
vertical-align middle
Expand All @@ -24,7 +26,7 @@
line-height 36px
margin 5px 3px 5px 0
border-radius 3px
background #eee
background #ddd
text-align center
color #555
&.active
Expand All @@ -45,8 +47,14 @@
color #08c

.tabs-add-btn
display inline-block
margin 0 3px
.tabs-extra
position absolute
z-index 5
right 10px
top 50%
margin-top -8px
height 46px
top 0
right 0
box-shadow -3px 0px 3px 0px rgba(0,0,0,0.15)
background #fff
line-height 46px
z-index 20
11 changes: 11 additions & 0 deletions src/client/components/main/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export default class Index extends React.Component {
let tabs = initTabs()
this.state = {
tabs,
height: 500,
width: window.innerWidth,
currentTabId: tabs[0].id,
history: ls.get('history') || [],
bookmarks: ls.get('bookmarks') || [],
Expand All @@ -44,6 +46,8 @@ export default class Index extends React.Component {
}

componentDidMount() {
window.addEventListener('resize', this.onResize)
this.onResize()
window._require('electron')
.ipcRenderer.on('checkupdate', this.onCheckUpdate)
.on('open-about', this.openAbout)
Expand All @@ -60,6 +64,13 @@ export default class Index extends React.Component {
}
}

onResize = () => {
this.setState({
height: window.innerHeight,
width: window.innerWidth
})
}

setStateLs = (update) => {
Object.keys(update).forEach(k => {
ls.set(k, update[k])
Expand Down
24 changes: 5 additions & 19 deletions src/client/components/main/window-wrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,29 @@ const {TabPane} = Tabs
export default class WindowWrapper extends React.Component {

state = {
height: 500,
width: window.innerWidth,
pane: 'ssh'
}

componentDidMount() {
window.addEventListener('resize', this.onResize)
this.onResize()
}

onResize = () => {
this.setState({
height: this.computeHeight(),
width: window.innerWidth
})
}

computeHeight = () => {
let hasHost = _.get(this.props, 'tab.host')
return window.innerHeight - 39 - 46 - (hasHost ? 37 : 0)
return window.innerHeight - 39 - 46 - (hasHost ? 36 : 0)
}

onChange = pane => {
this.setState({pane})
}

render() {
let {height, pane, width} = this.state
let {pane} = this.state
let {props} = this
let height = this.computeHeight()
let host = _.get(props, 'tab.host')
let propsAll = {
...props,
height,
width
height
}
return (
<div className="ui-wrapper">
<div className={'ui-wrapper ' + pane}>
{
host
? (
Expand Down
11 changes: 11 additions & 0 deletions src/client/components/main/wrapper.styl
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#container
min-width 600px
.ui-wrapper
.ant-tabs-bar
margin-bottom 0
.ssh
.ant-tabs-bar
.ant-tabs-tab
color #999
.ant-tabs-tab-active
color #fff
.ant-tabs-nav-wrap
background #333

.common-err-desc
&:hover
text-overflow clip
Expand Down