Skip to content

Commit 175e266

Browse files
authored
Merge branch 'dashboard' into fix-language-mode-add-makefile
2 parents 63eb20b + aee0024 commit 175e266

File tree

25 files changed

+338
-31
lines changed

25 files changed

+338
-31
lines changed

app/commons/Tab/TabBar.jsx

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import TabLabel from './TabLabel'
77
import Menu from 'components/Menu'
88
import ContextMenu from 'components/ContextMenu'
99
import i18n from 'utils/createI18n'
10-
10+
import * as SideBar from 'components/Panel/SideBar/actions'
11+
import config from 'config'
12+
import * as Panel from 'components/Panel/actions'
13+
import panelState from 'components/Panel/state'
1114

1215
@defaultProps(props => ({
1316
addTab: () => props.tabGroup.addTab(),
@@ -43,6 +46,7 @@ class TabBar extends Component {
4346
} = this.props
4447

4548
const tabBarId = `tab_bar_${tabGroup.id}`
49+
const size = panelState.panels.get('PANEL_BOTTOM').size
4650

4751
return (
4852
<div id={tabBarId}
@@ -67,12 +71,28 @@ class TabBar extends Component {
6771
</svg>
6872
</div>
6973
<div onDoubleClick={addTab} className='tab-dbclick-area' />
74+
{(!config.isPad || tabGroup.id !== 'terminalGroup')
75+
&& <div className='tab-show-list'
76+
style={{ marginBottom: '-2px' }}
77+
onClick={e => {
78+
e.stopPropagation()
79+
this.setState({ showDropdownMenu: !this.state.showDropdownMenu })
80+
}}
81+
>
82+
<i className='fa fa-ellipsis-h' />
83+
{this.renderDropdownMenu(size)}
84+
</div>}
85+
{tabGroup.id === 'terminalGroup' &&
7086
<div className='tab-show-list'
71-
onClick={(e) => { e.stopPropagation(); this.setState({ showDropdownMenu: true }) }}
87+
style={{ marginBottom: size ? '4px' : '-6px' }}
88+
onClick={e => {
89+
e.stopPropagation()
90+
!size ? Panel.expandPanel('PANEL_BOTTOM')
91+
: Panel.shrinkPanel('PANEL_BOTTOM')
92+
}}
7293
>
73-
<i className='fa fa-sort-desc' />
74-
{this.renderDropdownMenu()}
75-
</div>
94+
<i className={`fa fa-sort-${size ? 'desc' : 'asc'}`} />
95+
</div>}
7696
<ContextMenu
7797
items={contextMenuItems}
7898
isActive={this.state.showContextMenu}
@@ -88,20 +108,26 @@ class TabBar extends Component {
88108
e.stopPropagation()
89109
e.preventDefault()
90110

111+
const rects = e.target.getBoundingClientRect()
112+
const isPad = config.isPad
113+
91114
this.setState({
92115
showContextMenu: true,
93-
contextMenuPos: { x: e.clientX, y: e.clientY },
116+
contextMenuPos: {
117+
x: isPad ? rects.x : e.clientX,
118+
y: isPad ? rects.y : e.clientY
119+
},
94120
contextMenuContext: context,
95121
})
96122
}
97123

98-
renderDropdownMenu () {
124+
renderDropdownMenu (size) {
99125
if (!this.state.showDropdownMenu) return null
100126
const dropdownMenuItems = this.makeDropdownMenuItems()
101127
if (!dropdownMenuItems.length) return null
102-
return (<Menu className='top-down to-left'
128+
return (<Menu className={`${size ? 'top-down' : 'bottom-top'} to-left`}
129+
style={{ bottom: size ? 'initial' : '15px', right: '2px' }}
103130
items={dropdownMenuItems}
104-
style={{ right: '2px' }}
105131
deactivate={e => this.setState({ showDropdownMenu: false })}
106132
/>)
107133
}

app/commons/Tab/TabLabel.jsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as Modal from '../../components/Modal/actions'
99
import config from 'config'
1010
import dispatchCommand from 'commands/dispatchCommand'
1111
import { fileIconProviders } from 'components/FileTree/state'
12+
import { gtouchstart, gtouchend, gtouchmove } from 'utils/touch'
1213

1314
const closeFileTab = async (e, tab, removeTab, activateTab) => {
1415
e.stopPropagation()
@@ -87,7 +88,7 @@ let TabLabel = observer(({ tab, removeTab, activateTab, openContextMenu, dbClick
8788
id={tabLabelId}
8889
data-droppable='TABLABEL'
8990
draggable='true'
90-
onClick={e => activateTab(tab.id)}
91+
onClick={e => { activateTab(tab.id) }}
9192
onMouseUp={e => { e.button === 1 && removeTab(tab.id) }}
9293
onDoubleClick={() => {
9394
if (!tab.isActive) {
@@ -99,7 +100,13 @@ let TabLabel = observer(({ tab, removeTab, activateTab, openContextMenu, dbClick
99100
// Chrome 下直接执行 dragStart 会导致立即又出发了 window.dragend, 添加 timeout 以避免无法拖动的情况
100101
setTimeout(() => dnd.dragStart({ type: 'TAB', id: tab.id }), 0)
101102
}}
102-
onContextMenu={e => openContextMenu(e, tab)}
103+
onContextMenu={e => config.isPad ? '' : openContextMenu(e, tab)}
104+
onTouchStart={e => {
105+
e.persist()
106+
gtouchstart(() => { openContextMenu(e, tab) })
107+
}}
108+
onTouchEnd={gtouchend}
109+
onTouchMove={gtouchmove}
103110
>
104111
{dnd.target.id === tabLabelId ? <div className='tab-label-insert-pos'></div> : null}
105112
{tab.icon && <TabIcon fileName={tab.title} defaultIconStr={tab.icon} />}

app/commons/Tree/TreeNode.jsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { observer } from 'mobx-react'
55
import config from 'config'
66
import cx from 'classnames'
77
import dnd from 'utils/dnd'
8+
import { gtouchstart, gtouchend, gtouchmove } from 'utils/touch'
89
import icons from 'file-icons-js'
910
import { fileIconProviders } from 'components/FileTree/state'
1011

@@ -135,9 +136,20 @@ class TreeNode extends Component {
135136
})}
136137
data-droppable='FILE_TREE_NODE'
137138
onContextMenu={(e) => {
139+
if (config.isPad) return
138140
selectNode(node)
139141
openContextMenu(e, node)
140142
}}
143+
onTouchMove={gtouchmove}
144+
onTouchEnd={gtouchend}
145+
onTouchStart={e => {
146+
e.persist()
147+
gtouchstart(() => {
148+
selectNode(node)
149+
openContextMenu(e, node)
150+
})
151+
e.stopPropagation()
152+
}}
141153
draggable='true'
142154
onDragStart={(e) => {
143155
e.dataTransfer.effectAllowed = 'move'
@@ -151,17 +163,19 @@ class TreeNode extends Component {
151163
<div
152164
className={cx('filetree-node', { focus: node.isFocused })}
153165
ref={r => (this.nodeDOM = r)}
154-
onClick={e => selectNode(node)}
166+
onClick={e => {
167+
selectNode(node)
168+
config.isPad ? openNode(node) : ''
169+
}}
155170
onDoubleClick={e => openNode(node)}
156-
onTouchStart={e => openNode(node)}
157171
style={{ paddingLeft: `${1 + node.depth}em` }}
158172
>
159173
{node.isLoading && <i className='fa fa-spinner fa-pulse fa-fw' />}
160174
{!node.isLoading && (
161175
<span
162176
className='filetree-node-arrow'
163177
onDoubleClick={e => e.stopPropagation()}
164-
onClick={e => openNode(node, null, e.altKey)}
178+
onClick={e => config.isPad ? '' : openNode(node, null, e.altKey)}
165179
>
166180
{node.isDir && (
167181
<i

app/components/ContextMenu/store.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import state from './state'
22
import isFunction from 'lodash/isFunction'
33
import isArray from 'lodash/isArray'
44
import { createAction, handleAction, registerAction } from 'utils/actions'
5+
import config from 'config'
56

67
const OPEN_CONTEXT_MENU = 'menu:open_context_menu'
78
handleAction(OPEN_CONTEXT_MENU, ({ isActive, pos, contextNode, items, className }) => {
@@ -23,7 +24,14 @@ function openContextMenuFactory (items, margin, className) {
2324
const openContextMenu = createAction(OPEN_CONTEXT_MENU, (e, context, items = [], margin = { x: 0, y: 0, relative: false }, className = '') => {
2425
e.stopPropagation()
2526
e.preventDefault()
26-
let pos = { x: e.clientX + margin.x, y: e.clientY + margin.y }
27+
28+
const rects = e.target.getBoundingClientRect()
29+
const isPad = config.isPad
30+
31+
let pos = {
32+
x: (isPad ? rects.x + rects.width / 2 : e.clientX) + margin.x,
33+
y: (isPad ? rects.y + rects.height : e.clientY) + + margin.y
34+
}
2735
if (margin.relative) {
2836
const rect = e.target.getBoundingClientRect()
2937
pos = { x: rect.x + rect.width + margin.x, y: rect.y + rect.height + margin.y }

app/components/Git/GitBranchWidget.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { connect } from 'react-redux'
77
import * as GitActions from './actions'
88
import Menu from '../Menu'
99
import i18n from 'utils/createI18n'
10-
10+
import config from 'config'
1111

1212
// add withRef to deliver ref to the wrapperedcomponent
1313
@connect(state => state.GitState.branches,
@@ -28,7 +28,7 @@ export default class GitBranchWidget extends Component {
2828
const { current: currentBranch, local: localBranches, remote: remoteBranches } = this.props
2929
return (
3030
<div className='status-bar-menu-item'
31-
onClick={e => { this.toggleActive(true, true) }}
31+
onClick={e => { this.toggleActive(true, true); config.menuBars.push(this) }}
3232
>
3333
<span>
3434
<span className='fa fa-code-fork' style={{ fontWeight: 800, marginRight: '5px' }} />

app/components/MenuBar/MenuBar.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ class MenuBarItem extends Component {
114114
onClick={(e) => {
115115
e.stopPropagation()
116116
toggleActive(index, true)
117+
if (config.isPad) {
118+
config.menuBars.push(this.props)
119+
}
117120
}}
118121
onMouseEnter={(e) => { if (shouldHoverToggleActive) toggleActive(index) }}
119122
>

app/components/MonacoEditor/MonacoReact/BaseEditor.jsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ class MonacoEditor extends React.PureComponent {
194194
this.containerElement = component
195195
}
196196

197+
removeMenus = () => {
198+
// Hack tricks to remove active menu
199+
const menuBars = config.menuBars
200+
menuBars.map(menubar => menubar.toggleActive())
201+
}
202+
197203
render () {
198204
const { width, height } = this.props
199205
const fixedWidth = width.toString().indexOf('%') !== -1 ? width : `${width}px`
@@ -207,6 +213,7 @@ class MonacoEditor extends React.PureComponent {
207213
style={{ width: '100%', height: '100%' }}
208214
onWidthChange={this.handleResize}
209215
onHeightChange={this.handleResize}
216+
onTouchStart={this.removeMenus}
210217
>
211218
<div className='react-monaco-editor-container' ref={this.assignRef} style={style} />
212219
</Div>)

app/components/MonacoEditor/state.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
import codeEditorService from './codeEditorService'
2222
import ConditionWidget from './ConditionWidget'
2323
import initialOptions from './monacoDefaultOptions'
24+
import config from 'config'
25+
import { state as virtualKeyState } from '../VirtualKey'
2426

2527
reaction(
2628
() => initialOptions.theme,
@@ -105,6 +107,7 @@ class EditorInfo {
105107
state.editors.set(this.uri, monacoEditor)
106108

107109
monacoEditor.onDidFocusEditorText(() => {
110+
virtualKeyState.show = true
108111
state.activeMonacoEditor = monacoEditor
109112
if (state.activeEditorListeners && state.activeEditorListeners.length > 0) {
110113
for (const activeEditorListener of state.activeEditorListeners) {

app/components/Notification/actions.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import state from './state'
44
export const NOTIFY_TYPE = {
55
ERROR: 'error',
66
INFO: 'info',
7+
SUCCESS: 'success',
8+
WARNING: 'warning'
79
}
810

911
export const NOTIFICATION_REMOVE = 'NOTIFICATION_REMOVE'
@@ -13,12 +15,14 @@ export const removeNotification = registerAction.normal(NOTIFICATION_REMOVE, (no
1315
})
1416

1517
const NOTIFICATION_ADD = 'NOTIFICATION_ADD'
16-
export const addNotification = registerAction.normal(NOTIFICATION_ADD,
18+
export const addNotification = registerAction.normal(
19+
NOTIFICATION_ADD,
1720
(notification) => {
1821
const notifKey = Date.now()
1922
let defaultNotification = {
2023
message: '',
21-
action: 'Dismiss',
24+
action: '',
25+
notifyType: NOTIFY_TYPE.SUCCESS, // 默认弹出success弹窗
2226
key: notifKey,
2327
dismissAfter: 6000,
2428
onClick: () => removeNotification(notifKey)
@@ -28,7 +32,7 @@ export const addNotification = registerAction.normal(NOTIFICATION_ADD,
2832
defaultNotification = {
2933
...defaultNotification,
3034
barStyle: { backgroundColor: 'red' },
31-
actionStyle: { color: 'white' },
35+
actionStyle: { color: 'white' }
3236
}
3337
}
3438

app/components/Notification/index.jsx

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,87 @@ import { NotificationStack } from 'react-notification'
44
import * as actions from './actions'
55
import state from './state'
66

7-
const barStyleFactory = (index, style) => {
8-
return Object.assign({}, style, {
7+
const actionStyleFactory = (index, style) =>
8+
Object.assign({}, style, {
9+
color: '#ccc',
10+
right: '-100%',
11+
bottom: 'initial',
12+
top: `${2 + index * 4}rem`,
13+
zIndex: 20,
14+
fontSize: '12px',
15+
padding: '8px'
16+
})
17+
const barStyleFactory = (index, style) =>
18+
Object.assign({}, style, {
919
left: 'initial',
1020
right: '-100%',
1121
bottom: 'initial',
1222
top: `${2 + index * 4}rem`,
1323
zIndex: 20,
1424
fontSize: '12px',
15-
padding: '8px',
25+
padding: '8px'
1626
})
17-
}
1827

19-
const activeBarStyleFactory = (index, style) => {
20-
return Object.assign({}, style, {
28+
const activeBarStyleFactory = (index, style) =>
29+
Object.assign({}, style, {
2130
left: 'initial',
2231
right: '1rem',
2332
bottom: 'initial',
2433
top: `${2 + index * 4}rem`,
2534
fontSize: '12px',
26-
padding: '8px',
35+
padding: '8px'
2736
})
37+
38+
function notificationMessageFactory (notifyType, message) {
39+
let ClassName
40+
let Color
41+
switch (notifyType) {
42+
case 'error':
43+
ClassName = 'fa fa-times-circle'
44+
Color = 'red'
45+
break
46+
case 'success':
47+
ClassName = 'fa fa-check-circle'
48+
Color = 'green'
49+
break
50+
case 'warning':
51+
ClassName = 'fa fa-exclamation-triangle'
52+
Color = 'orange'
53+
break
54+
case 'info':
55+
ClassName = 'fa fa-info-circle'
56+
Color = 'blue'
57+
break
58+
default:
59+
}
60+
return (
61+
<span style={{ fontSize: 12 }}>
62+
<span style={{ color: Color }}>
63+
<i className={ClassName} aria-hidden='true' />
64+
</span>
65+
&nbsp;&nbsp;{message}
66+
</span>
67+
)
2868
}
2969

3070
class Notification extends Component {
3171
constructor (props) {
3272
super()
3373
}
74+
3475
render () {
35-
const { notifications } = this.props
76+
const notifications = this.props.notifications.map((v) => {
77+
v.action = <i className='fa fa-close' aria-hidden='true' />
78+
v.dismissAfter = false
79+
v.message = notificationMessageFactory(v.notifyType, v.message)
80+
return v
81+
})
3682
return (
3783
<NotificationStack
3884
notifications={notifications}
3985
onDismiss={notification => actions.removeNotification(notification.key)}
4086
barStyleFactory={barStyleFactory}
87+
actionStyleFactory={actionStyleFactory}
4188
activeBarStyleFactory={activeBarStyleFactory}
4289
/>
4390
)

0 commit comments

Comments
 (0)