Skip to content

Commit

Permalink
Add a brand new UI for Linux and Windows 💅
Browse files Browse the repository at this point in the history
  • Loading branch information
matheuss committed Oct 30, 2016
1 parent 2b75c04 commit 9dbff52
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 39 deletions.
12 changes: 12 additions & 0 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ app.on('ready', () => installDevExtensions(isDev).then(() => {
rpc.emit('move');
});

rpc.on('open hamburger menu', ({x, y}) => {
Menu.getApplicationMenu().popup(x, y);
});

rpc.on('minimize', () => {
win.minimize();
});

rpc.on('close', () => {
win.close();
});

const deleteSessions = () => {
sessions.forEach((session, key) => {
session.removeAllListeners();
Expand Down
22 changes: 20 additions & 2 deletions assets/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 34 additions & 1 deletion lib/actions/header.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {CLOSE_TAB, CHANGE_TAB} from '../constants/tabs';
import {UI_WINDOW_MAXIMIZE, UI_WINDOW_UNMAXIMIZE} from '../constants/ui';
import {UI_WINDOW_MAXIMIZE, UI_WINDOW_UNMAXIMIZE, UI_OPEN_HAMBURGER_MENU, UI_WINDOW_MINIMIZE, UI_WINDOW_CLOSE} from '../constants/ui';
import rpc from '../rpc';
import {userExitTermGroup, setActiveGroup} from './term-groups';

Expand Down Expand Up @@ -48,3 +48,36 @@ export function unmaximize() {
});
};
}

export function openHamburgerMenu(coordinates) {
return dispatch => {
dispatch({
type: UI_OPEN_HAMBURGER_MENU,
effect() {
rpc.emit('open hamburger menu', coordinates);
}
});
};
}

export function minimize() {
return dispatch => {
dispatch({
type: UI_WINDOW_MINIMIZE,
effect() {
rpc.emit('minimize');
}
});
};
}

export function close() {
return dispatch => {
dispatch({
type: UI_WINDOW_CLOSE,
effect() {
rpc.emit('close');
}
});
};
}
118 changes: 118 additions & 0 deletions lib/components/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export default class Header extends Component {
this.onChangeIntent = this.onChangeIntent.bind(this);
this.handleHeaderClick = this.handleHeaderClick.bind(this);
this.handleHeaderMouseDown = this.handleHeaderMouseDown.bind(this);
this.handleHamburgerMenuClick = this.handleHamburgerMenuClick.bind(this);
this.handleMaximizeClick = this.handleMaximizeClick.bind(this);
this.handleMinimizeClick = this.handleMinimizeClick.bind(this);
this.handleCloseClick = this.handleCloseClick.bind(this);
}

onChangeIntent(active) {
Expand Down Expand Up @@ -68,6 +72,27 @@ export default class Header extends Component {
}
}

handleHamburgerMenuClick(event) {
const {right: x, bottom: y} = event.currentTarget.getBoundingClientRect();
this.props.openHamburgerMenu({x, y});
}

handleMaximizeClick() {
if (this.props.maximized) {
this.props.unmaximize();
} else {
this.props.maximize();
}
}

handleMinimizeClick() {
this.props.minimize();
}

handleCloseClick() {
this.props.close();
}

componentWillUnmount() {
delete this.clicks;
clearTimeout(this.clickTimer);
Expand All @@ -81,11 +106,49 @@ export default class Header extends Component {
onClose: this.props.onCloseTab,
onChange: this.onChangeIntent
});
const {borderColor} = props;
let title = 'Hyper';
if (props.tabs.length === 1 && props.tabs[0].title) {
// if there's only one tab we use its title as the window title
title = props.tabs[0].title;
}
return (<header
className={css('header', isMac && 'headerRounded')}
onClick={this.handleHeaderClick}
onMouseDown={this.handleHeaderMouseDown}
>
{
!isMac && <div
className={css('windowHeader', props.tabs.length > 1 && 'windowHeaderWithBorder')}
style={{borderColor}}
>
<svg
className={css('shape', 'hamburgerMenu')}
onClick={this.handleHamburgerMenuClick}
>
<use xlinkHref="./dist/assets/icons.svg#hamburger-menu"/>
</svg>
<span className={css('appTitle')}>{title}</span>
<svg
className={css('shape', 'minimizeWindow')}
onClick={this.handleMinimizeClick}
>
<use xlinkHref="./dist/assets/icons.svg#minimize-window"/>
</svg>
<svg
className={css('shape', 'maximizeWindow')}
onClick={this.handleMaximizeClick}
>
<use xlinkHref="./dist/assets/icons.svg#maximize-window"/>
</svg>
<svg
className={css('shape', 'closeWindow')}
onClick={this.handleCloseClick}
>
<use xlinkHref="./dist/assets/icons.svg#close-window"/>
</svg>
</div>
}
{ this.props.customChildrenBefore }
<Tabs {...props}/>
{ this.props.customChildren }
Expand All @@ -105,6 +168,61 @@ export default class Header extends Component {
headerRounded: {
borderTopLeftRadius: '4px',
borderTopRightRadius: '4px'
},

windowHeader: {
height: '34px',
width: '100%',
position: 'fixed',
top: '1px',
left: '1px',
right: '1px',
WebkitAppRegion: 'drag',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
},

windowHeaderWithBorder: {
borderColor: '#ccc',
borderBottomStyle: 'solid',
borderBottomWidth: '1px'
},

appTitle: {
fontSize: '12px',
fontFamily: `-apple-system, BlinkMacSystemFont,
"Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", sans-serif`
},

shape: {
width: '10px',
height: '10px',
position: 'fixed',
WebkitAppRegion: 'no-drag',
fill: 'currentColor'
},

hamburgerMenu: {
height: '9px', // TODO fix the SVG
top: '10px',
left: '10px'
},

closeWindow: {
right: '10px',
stroke: 'currentColor'
},

maximizeWindow: {
right: '35px',
stroke: 'currentColor'
},

minimizeWindow: {
right: '60px'
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion lib/components/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default class Tab extends Component {
onClick={this.props.onClose}
>
<svg className={css('shape')}>
<use xlinkHref="./dist/assets/icons.svg#close"/>
<use xlinkHref="./dist/assets/icons.svg#close-tab"/>
</svg>
</i>
{ this.props.customChildren }
Expand Down
67 changes: 35 additions & 32 deletions lib/components/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,40 @@ export default class Tabs extends Component {
return (<nav className={css('nav')}>
{ this.props.customChildrenBefore }
{
tabs.length ?
tabs.length === 1 ?
<div className={css('title')}>{tabs[0].title}</div> :
[
<ul
key="list"
className={css('list')}
>
{
tabs.map((tab, i) => {
const {uid, title, isActive, hasActivity} = tab;
const props = getTabProps(tab, this.props, {
text: title === '' ? 'Shell' : title,
isFirst: i === 0,
isLast: tabs.length - 1 === i,
borderColor,
isActive,
hasActivity,
onSelect: onChange.bind(null, uid),
onClose: onClose.bind(null, uid)
});
return <Tab key={`tab-${uid}`} {...props}/>;
})
}
</ul>,
isMac && <div
key="shim"
style={{borderColor}}
className={css('borderShim')}
/>
] :
tabs.length === 1 && isMac ?
<div className={css('title')}>{tabs[0].title}</div> :
null
}
{
tabs.length > 1 ?
[
<ul
key="list"
className={css('list')}
>
{
tabs.map((tab, i) => {
const {uid, title, isActive, hasActivity} = tab;
const props = getTabProps(tab, this.props, {
text: title === '' ? 'Shell' : title,
isFirst: i === 0,
isLast: tabs.length - 1 === i,
borderColor,
isActive,
hasActivity,
onSelect: onChange.bind(null, uid),
onClose: onClose.bind(null, uid)
});
return <Tab key={`tab-${uid}`} {...props}/>;
})
}
</ul>,
isMac && <div
key="shim"
style={{borderColor}}
className={css('borderShim')}
/>
] :
null
}
{ this.props.customChildren }
Expand All @@ -73,7 +76,7 @@ export default class Tabs extends Component {
cursor: 'default',
position: 'relative',
WebkitUserSelect: 'none',
WebkitAppRegion: 'drag'
top: isMac ? '' : '34px'
},

title: {
Expand Down
11 changes: 9 additions & 2 deletions lib/components/terms.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {decorate, getTermGroupProps} from '../utils/plugins';
import TermGroup_ from './term-group';

const TermGroup = decorate(TermGroup_, 'TermGroup');
const isMac = /Mac/.test(navigator.userAgent);

export default class Terms extends Component {

Expand Down Expand Up @@ -71,8 +72,9 @@ export default class Terms extends Component {
}

template(css) {
const shift = !isMac && this.props.termGroups.length > 1;
return (<div
className={css('terms')}
className={css('terms', shift && 'termsShifted')}
>
{ this.props.customChildrenBefore }
{
Expand Down Expand Up @@ -132,7 +134,12 @@ export default class Terms extends Component {
right: 0,
left: 0,
bottom: 0,
color: '#fff'
color: '#fff',
transition: isMac ? '' : 'margin-top 0.3s ease'
},

termsShifted: {
marginTop: '68px'
},

termGroup: {
Expand Down
3 changes: 3 additions & 0 deletions lib/constants/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ export const UI_WINDOW_MOVE = 'UI_WINDOW_MOVE';
export const UI_WINDOW_MAXIMIZE = 'UI_WINDOW_MAXIMIZE';
export const UI_WINDOW_UNMAXIMIZE = 'UI_WINDOW_UNMAXIMIZE';
export const UI_OPEN_FILE = 'UI_OPEN_FILE';
export const UI_OPEN_HAMBURGER_MENU = 'UI_OPEN_HAMBURGER_MENU';
export const UI_WINDOW_MINIMIZE = 'UI_WINDOW_MINIMIZE';
export const UI_WINDOW_CLOSE = 'UI_WINDOW_CLOSE';
Loading

0 comments on commit 9dbff52

Please sign in to comment.