Skip to content

Commit

Permalink
Merge pull request #92 from Coding/yangzhen/fix-style
Browse files Browse the repository at this point in the history
Fix a few style issues, add context menu to tab
  • Loading branch information
hackape committed Apr 7, 2017
2 parents cef7665 + 24c708c commit 8df301b
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 12 deletions.
4 changes: 3 additions & 1 deletion app/commands/commandBindings/index.js
Expand Up @@ -2,10 +2,12 @@ import git from './git'
import file from './file'
import misc from './misc'
import editor from './editor'
import tab from './tab'

export default {
...git,
...file,
...misc,
...editor
...editor,
...tab
}
40 changes: 40 additions & 0 deletions app/commands/commandBindings/tab.js
@@ -0,0 +1,40 @@
/* @flow weak */
import store, { dispatch as $d } from '../../store'
import * as Tab from '../../components/Tab/actions'
import * as PaneActions from '../../components/Pane/actions'

export default {
'tab:close': c => {
$d(Tab.removeTab(c.context.id))
},

'tab:close_other': c => {
$d(Tab.removeOtherTab(c.context.id))
},

'tab:close_all': c => {
$d(Tab.removeAllTab(c.context.id))
},

'tab:split_v': c => {
const panes = store.getState().PaneState.panes
const pane = Object.values(panes).find((pane) => (
pane.content && pane.content.type === 'tabGroup' && pane.content.id === c.context.tabGroupId
))
$d(PaneActions.splitTo(pane.id, 'bottom'))
.then(newPaneId => {
$d(Tab.moveTabToPane(c.context.id, newPaneId))
})
},

'tab:split_h': c => {
const panes = store.getState().PaneState.panes
const pane = Object.values(panes).find((pane) => (
pane.content && pane.content.type === 'tabGroup' && pane.content.id === c.context.tabGroupId
))
$d(PaneActions.splitTo(pane.id, 'right'))
.then(newPaneId => {
$d(Tab.moveTabToPane(c.context.id, newPaneId))
})
},
}
2 changes: 1 addition & 1 deletion app/components/ContextMenu/index.jsx
Expand Up @@ -3,7 +3,7 @@ import React, { Component } from 'react'
import { connect } from 'react-redux'
import cx from 'classnames'
import Menu from '../Menu'
import {setContext} from '../../commands'
import {setContext} from '../../commands/dispatchCommand'

const ContextMenu = (props) => {
const {items, context, isActive, pos, deactivate} = props
Expand Down
2 changes: 2 additions & 0 deletions app/components/FileTree/actions.js
Expand Up @@ -34,6 +34,7 @@ export function openNode (node, shouldBeFolded = null, deep = false) {
type: 'editor',
title: node.name,
path: node.path,
icon: 'fa fa-file-o',
content: {
body: data.content,
// path: node.path,
Expand All @@ -48,6 +49,7 @@ export function openNode (node, shouldBeFolded = null, deep = false) {
type: 'editor',
title: node.name,
path: node.path,
icon: 'fa fa-file-o',
contentType: node.contentType,
size: node.size
}))
Expand Down
53 changes: 47 additions & 6 deletions app/components/Tab/TabBar.jsx
Expand Up @@ -5,7 +5,33 @@ import { dragStart } from '../DragAndDrop/actions';
import Menu from '../Menu'
import * as TabActions from './actions';
import * as PaneActions from '../Pane/actions';

import ContextMenu from '../ContextMenu'

const dividItem = { name: '-' }
const items = [
{
name: 'Close',
icon: '',
command: 'tab:close'
}, {
name: 'Close Others',
icon: '',
command: 'tab:close_other'
}, {
name: 'Close All',
icon: '',
command: 'tab:close_all'
}, dividItem,
{
name: 'Vertical Split',
icon: '',
command: 'tab:split_v'
}, {
name: 'Horizontal Split',
icon: '',
command: 'tab:split_h'
}
]

class _TabBar extends Component {
constructor (props) {
Expand Down Expand Up @@ -57,7 +83,7 @@ class _TabBar extends Component {
}

render () {
const { tabIds, tabGroupId, isRootPane, addTab, closePane, isDraggedOver } = this.props
const { tabIds, tabGroupId, isRootPane, addTab, closePane, isDraggedOver, contextMenu, closeContextMenu } = this.props
return (
<div className='tab-bar' id={`tab_bar_${tabGroupId}`} data-droppable='TABBAR'>
<ul className='tab-labels'>
Expand All @@ -76,7 +102,13 @@ class _TabBar extends Component {
<i className='fa fa-sort-desc'/>
{this.renderDropdownMenu()}
</div>

<ContextMenu
items={items}
isActive={contextMenu.isActive}
pos={contextMenu.pos}
context={contextMenu.contextNode}
deactivate={closeContextMenu}
/>
</div>
)
}
Expand All @@ -87,16 +119,19 @@ const TabBar = connect((state, { tabIds, tabGroupId, containingPaneId }) => ({
isDraggedOver: state.DragAndDrop.meta
? state.DragAndDrop.meta.tabBarTargetId === `tab_bar_${tabGroupId}`
: false,
isRootPane: state.PaneState.rootPaneId === containingPaneId
isRootPane: state.PaneState.rootPaneId === containingPaneId,
contextMenu: state.TabState.contextMenu
}), (dispatch, { tabGroupId, containingPaneId }) => ({
activateTab: (tabId) => dispatch(TabActions.activateTab(tabId)),
addTab: () => dispatch(TabActions.createTabInGroup(tabGroupId)),
closePane: () => dispatch(PaneActions.closePane(containingPaneId))
closePane: () => dispatch(PaneActions.closePane(containingPaneId)),
openContextMenu: (e, node) => dispatch(TabActions.openContextMenu(e, node)),
closeContextMenu: () => dispatch(TabActions.closeContextMenu())
})
)(_TabBar)


const _TabLabel = ({tab, isActive, isDraggedOver, removeTab, activateTab, dragStart}) => {
const _TabLabel = ({tab, isActive, isDraggedOver, removeTab, activateTab, dragStart, openContextMenu}) => {
const possibleStatus = {
'modified': '*',
'warning': '!',
Expand All @@ -115,8 +150,10 @@ const _TabLabel = ({tab, isActive, isDraggedOver, removeTab, activateTab, dragSt
onClick={e => activateTab(tab.id)}
draggable='true'
onDragStart={e => dragStart({sourceType: 'TAB', sourceId: tab.id})}
onContextMenu={e => openContextMenu(e, tab)}
>
{isDraggedOver ? <div className='tab-label-insert-pos'></div>: null}
{tab.icon ? <div className={tab.icon}></div>: null}
<div className='title'>{tab.title}</div>
<div className='control'>
<i className='close' onClick={e => { e.stopPropagation(); removeTab(tab.id) }}>×</i>
Expand All @@ -132,6 +169,8 @@ _TabLabel.propTypes = {
removeTab: PropTypes.func,
activateTab: PropTypes.func,
dragStart: PropTypes.func,
openContextMenu: PropTypes.func,
closeContextMenu: PropTypes.func
}

const TabLabel = connect((state, { tabId }) => {
Expand All @@ -145,6 +184,8 @@ const TabLabel = connect((state, { tabId }) => {
removeTab: (tabId) => dispatch(TabActions.removeTab(tabId)),
activateTab: (tabId) => dispatch(TabActions.activateTab(tabId)),
dragStart: (dragEventObj) => dispatch(dragStart(dragEventObj)),
openContextMenu: (e, node) => dispatch(TabActions.openContextMenu(e, node)),
closeContextMenu: () => dispatch(TabActions.closeContextMenu())
})
)(_TabLabel)

Expand Down
21 changes: 21 additions & 0 deletions app/components/Tab/actions.js
Expand Up @@ -12,6 +12,12 @@ export const createTabInGroup = createAction(TAB_CREATE_IN_GROUP, (groupId, tab)
export const TAB_REMOVE = 'TAB_REMOVE'
export const removeTab = createAction(TAB_REMOVE, tabId => tabId)

export const TAB_REMOVE_OTHER = 'TAB_REMOVE_OTHER'
export const removeOtherTab = createAction(TAB_REMOVE_OTHER, tabId => tabId)

export const TAB_REMOVE_ALL = 'TAB_REMOVE_ALL'
export const removeAllTab = createAction(TAB_REMOVE_ALL, tabId => tabId)

export const TAB_ACTIVATE = 'TAB_ACTIVATE'
export const activateTab = createAction(TAB_ACTIVATE, tabId => tabId)

Expand Down Expand Up @@ -62,3 +68,18 @@ export const TAB_INSERT_AT = 'TAB_INSERT_AT'
export const insertTabAt = createAction(TAB_INSERT_AT,
(tabId, beforeTabId) => ({tabId, beforeTabId})
)

export const TAB_CONTEXT_MENU_OPEN = 'TAB_CONTEXT_MENU_OPEN'
export const openContextMenu = createAction(TAB_CONTEXT_MENU_OPEN, (e, node) => {
e.stopPropagation()
e.preventDefault()

return {
isActive: true,
pos: { x: e.clientX, y: e.clientY },
contextNode: node,
}
})

export const TAB_CONTEXT_MENU_CLOSE = 'TAB_CONTEXT_MENU_CLOSE'
export const closeContextMenu = createAction(TAB_CONTEXT_MENU_CLOSE)
69 changes: 66 additions & 3 deletions app/components/Tab/reducer.js
Expand Up @@ -14,7 +14,11 @@ import {
TAB_UPDATE_BY_PATH,
TAB_MOVE_TO_GROUP,
TAB_MOVE_TO_PANE,
TAB_INSERT_AT
TAB_INSERT_AT,
TAB_CONTEXT_MENU_OPEN,
TAB_CONTEXT_MENU_CLOSE,
TAB_REMOVE_OTHER,
TAB_REMOVE_ALL
} from './actions'

import {
Expand Down Expand Up @@ -57,7 +61,12 @@ import {
const defaultState = {
tabGroups: {},
tabs: {},
activeTabGroupId: ''
activeTabGroupId: '',
contextMenu: {
isActive: false,
pos: { x: 0, y: 0 },
contextNode: null,
}
}

const Tab = Model({
Expand Down Expand Up @@ -113,6 +122,36 @@ const _removeTab = (state, tab) => {
})
}

const _removeOtherTab = (state, tab) => {
let nextState = state
nextState = _activateTab(state, tab)
const tabGroup = state.tabGroups[tab.tabGroupId]
const tabIdsToBeDeleted = _.without(tabGroup.tabIds, tab.id)
const nextTabs = _.omit(state.tabs, tabIdsToBeDeleted)
return update(nextState, {
tabGroups: {
[tab.tabGroupId]: {
tabIds: { $set: [tab.id] }
}
},
tabs: { $set: nextTabs }
})
}

const _removeAllTab = (state, tab) => {
const tabGroup = state.tabGroups[tab.tabGroupId]
const tabIdsToBeDeleted = tabGroup.tabIds
const nextTabs = _.omit(state.tabs, tabIdsToBeDeleted)
return update(state, {
tabGroups: {
[tab.tabGroupId]: {
tabIds: { $set: [] }
}
},
tabs: { $set: nextTabs }
})
}

const _moveTabToGroup = (state, tab, tabGroup, insertIndex = tabGroup.tabIds.length) => {
// 1. remove it from original group
let nextState = _removeTab(state, tab)
Expand Down Expand Up @@ -193,6 +232,16 @@ const TabReducer = handleActions({
return _removeTab(state, tab)
},

[TAB_REMOVE_OTHER]: (state, action) => {
const tab = state.tabs[action.payload]
return _removeOtherTab(state, tab)
},

[TAB_REMOVE_ALL]: (state, action) => {
const tab = state.tabs[action.payload]
return _removeAllTab(state, tab)
},

[TAB_ACTIVATE]: (state, action) => {
const tab = state.tabs[action.payload]
let nextState = _activateTab(state, tab)
Expand Down Expand Up @@ -261,7 +310,21 @@ const TabReducer = handleActions({
const { targetTabGroupId, sourceTabGroupId } = action.payload
if (!targetTabGroupId) return update(state, {tabGroups: {$delete: sourceTabGroupId}})
return _mergeTabGroups(state, targetTabGroupId, sourceTabGroupId)
}
},

[TAB_CONTEXT_MENU_OPEN]: (state, action) => (
update(state, {
contextMenu: { $merge: action.payload }
})
),

[TAB_CONTEXT_MENU_CLOSE]: (state, action) => (
update(state, {
contextMenu: { $merge: {
isActive: false
} }
})
),
}, defaultState)


Expand Down
1 change: 1 addition & 0 deletions app/styles/core-ui/Bar.styl
Expand Up @@ -3,6 +3,7 @@ $bar-size= 25px
// the rotated label trick, see: https://gist.github.com/aiboy/7406727
.side-bar {
display: flex;
noSelect()

&.left, &.right {
width: $bar-size;
Expand Down
13 changes: 13 additions & 0 deletions app/styles/core-ui/History.styl
Expand Up @@ -25,5 +25,18 @@
padding: 5px 8px;
cursor: pointer;
}
.public_fixedDataTable_header, .public_fixedDataTable_header .public_fixedDataTableCell_main {
background: #FFF;
font-weight: normal;
}
.fixedDataTableLayout_main {
border-width: 0px;
}
.public_fixedDataTableCell_main {
border-color: #ebebeb;
}
.public_fixedDataTable_main, .public_fixedDataTable_header, .public_fixedDataTable_hasBottomBorder {
border-color: #ebebeb;
}
}
}
2 changes: 1 addition & 1 deletion app/styles/core-ui/StatusBar.styl
@@ -1,7 +1,7 @@
$bar-height = 30px;

.status-bar {
border-top: 1px solid transparent;
// border-top: 1px solid transparent;
display: flex;
align-items: center;
min-height: $bar-height;
Expand Down

0 comments on commit 8df301b

Please sign in to comment.