Use css to style UI

This commit is contained in:
Yuya Ochiai 2017-05-17 01:38:03 +09:00
parent a6b27238bc
commit 7be7f8dcc2
19 changed files with 234 additions and 218 deletions

View file

@ -45,6 +45,7 @@
"babel-preset-react": "^6.24.1",
"chai": "^3.5.0",
"cross-env": "^4.0.0",
"css-loader": "^0.28.1",
"devtron": "^1.4.0",
"electron": "1.6.6",
"electron-builder": "17.4.0",
@ -56,6 +57,7 @@
"mocha-circleci-reporter": "0.0.2",
"npm-run-all": "^4.0.2",
"spectron": "~3.6.2",
"style-loader": "^0.17.0",
"url-loader": "^0.5.8",
"webpack": "^2.5.1",
"webpack-dev-server": "^2.4.5",

View file

@ -4,48 +4,21 @@ const React = require('react');
const PropTypes = require('prop-types');
const {Grid, Row, Col} = require('react-bootstrap');
const errorPage = {
tableStyle: {
display: 'table',
width: '100%',
height: '100%',
position: 'absolute',
top: '0',
left: '0'
},
cellStyle: {
display: 'table-cell',
verticalAlign: 'top',
paddingTop: '2em'
},
bullets: {
paddingLeft: '15px',
lineHeight: '1.7'
},
techInfo: {
fontSize: '12px',
color: '#aaa'
}
};
function ErrorView(props) {
const classNames = ['container', 'errorView'];
const classNames = ['container', 'ErrorView'];
if (!props.active) {
classNames.push('errorView-hidden');
classNames.push('ErrorView-hidden');
}
if (props.withTab) {
classNames.push('errorView-with-tab');
classNames.push('ErrorView-with-tab');
}
return (
<Grid
id={props.id}
bsClass={classNames.join(' ')}
>
<div style={errorPage.tableStyle}>
<div style={errorPage.cellStyle}>
<div className='ErrorView-table'>
<div className='ErrorView-cell'>
<Row>
<Col
xs={0}
@ -63,7 +36,7 @@ function ErrorView(props) {
<hr/>
<p>{'We\'re having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work please verify that:'}</p>
<br/>
<ul style={errorPage.bullets}>
<ul className='ErrorView-bullets' >
<li>{'Your computer is connected to the internet.'}</li>
<li>{'The Mattermost URL '}
<a href={props.errorInfo.validatedURL}>
@ -75,7 +48,7 @@ function ErrorView(props) {
</a>{' from a browser window.'}</li>
</ul>
<br/>
<div style={errorPage.techInfo}>
<div className='ErrorView-techInfo'>
{props.errorInfo.errorDescription}{' ('}
{props.errorInfo.errorCode }{')'}</div>
</Col>

View file

@ -3,14 +3,13 @@ const PropTypes = require('prop-types');
function HoveringURL(props) {
return (
<div style={props.style}>
<div className='HoveringURL HoveringURL-left'>
{props.targetURL}
</div>
);
}
HoveringURL.propTypes = {
style: PropTypes.object,
targetURL: PropTypes.string
};

View file

@ -14,28 +14,6 @@ const HoveringURL = require('./HoveringURL.jsx');
const NewTeamModal = require('./NewTeamModal.jsx');
// Todo: Need to consider better way to apply styles
const styles = {
hoveringURL: {
color: 'gray',
backgroundColor: 'whitesmoke',
maxWidth: '95%',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
position: 'absolute',
bottom: 0,
paddingLeft: 4,
paddingRight: 16,
paddingTop: 2,
paddingBottom: 2,
borderTopRightRadius: 4,
borderTop: 'solid thin lightgray',
borderRight: 'solid thin lightgray',
pointerEvents: 'none'
}
};
const MainPage = createReactClass({
propTypes: {
onUnreadCountChange: PropTypes.func.isRequired,
@ -313,7 +291,7 @@ const MainPage = createReactClass({
/>
);
return (
<div>
<div className='MainPage'>
<LoginModal
show={this.state.loginQueue.length !== 0}
request={request}
@ -335,7 +313,6 @@ const MainPage = createReactClass({
null :
<HoveringURL
key='hoveringURL'
style={styles.hoveringURL}
targetURL={this.state.targetURL}
/> }
</ReactCSSTransitionGroup>

View file

@ -105,11 +105,6 @@ class NewTeamModal extends React.Component {
}
render() {
const noBottomSpaceing = {
paddingBottom: 0,
marginBottom: 0
};
if (this.wasShown !== this.props.show && this.props.show) {
this.initializeOnShow();
}
@ -117,6 +112,8 @@ class NewTeamModal extends React.Component {
return (
<Modal
bsClass='modal'
className='NewTeamModal'
show={this.props.show}
id='newServerModal'
onHide={this.props.onClose}
@ -156,8 +153,8 @@ class NewTeamModal extends React.Component {
<HelpBlock>{'The name of the server displayed on your desktop app tab bar.'}</HelpBlock>
</FormGroup>
<FormGroup
className='NewTeamModal-noBottomSpace'
validationState={this.getTeamUrlValidationState()}
style={noBottomSpaceing}
>
<ControlLabel>{'Server URL'}</ControlLabel>
<FormControl
@ -168,9 +165,7 @@ class NewTeamModal extends React.Component {
onChange={this.handleTeamUrlChange.bind(this)}
/>
<FormControl.Feedback/>
<HelpBlock
style={noBottomSpaceing}
>{'The URL of your Mattermost server. Must start with http:// or https://.'}</HelpBlock>
<HelpBlock className='NewTeamModal-noBottomSpace'>{'The URL of your Mattermost server. Must start with http:// or https://.'}</HelpBlock>
</FormGroup>
</form>
</Modal.Body>

View file

@ -2,48 +2,55 @@ const React = require('react');
const PropTypes = require('prop-types');
const {Nav, NavItem, Button} = require('react-bootstrap');
class TabBar extends React.Component {
render() {
var self = this;
var tabs = this.props.teams.map((team, index) => {
var unreadCount = 0;
var badgeStyle = {
background: '#FF1744',
float: 'right',
color: 'white',
minWidth: '19px',
fontSize: '12px',
textAlign: 'center',
lineHeight: '20px',
height: '19px',
marginLeft: '5px',
marginTop: '5px',
borderRadius: '50%'
};
function AddServerButton(props) {
return (
<NavItem
className='AddServerButton'
key='addServerButton'
eventKey='addServerButton'
>
<Button
id='tabBarAddNewTeam'
onClick={props.onClick}
className='AddServerButton-button'
title='Add new server'
>
{'+'}
</Button>
</NavItem>
);
}
if (self.props.unreadCounts[index] > 0) {
unreadCount = self.props.unreadCounts[index];
AddServerButton.propTypes = {
onClick: PropTypes.func
};
function TabBar(props) {
const tabs = props.teams.map((team, index) => {
let unreadCount = 0;
if (props.unreadCounts[index] > 0) {
unreadCount = props.unreadCounts[index];
}
if (self.props.unreadAtActive[index]) {
if (props.unreadAtActive[index]) {
unreadCount += 1;
}
var mentionCount = 0;
if (self.props.mentionCounts[index] > 0) {
mentionCount = self.props.mentionCounts[index];
let mentionCount = 0;
if (props.mentionCounts[index] > 0) {
mentionCount = props.mentionCounts[index];
}
if (self.props.mentionAtActiveCounts[index] > 0) {
mentionCount += self.props.mentionAtActiveCounts[index];
if (props.mentionAtActiveCounts[index] > 0) {
mentionCount += props.mentionAtActiveCounts[index];
}
var badgeDiv;
let badgeDiv;
if (mentionCount !== 0) {
badgeDiv = (
<div style={badgeStyle}>
<div className='TabBar-badge'>
{mentionCount}
</div>);
}
var id = 'teamTabItem' + index;
const id = 'teamTabItem' + index;
if (unreadCount === 0) {
return (
<NavItem
@ -71,49 +78,16 @@ class TabBar extends React.Component {
});
return (
<Nav
id={this.props.id}
className='TabBar'
id={props.id}
bsStyle='tabs'
activeKey={this.props.activeKey}
onSelect={this.props.onSelect}
activeKey={props.activeKey}
onSelect={props.onSelect}
>
{ tabs }
{ this.renderAddTeamButton() }
<AddServerButton onClick={props.onAddServer}/>
</Nav>
);
}
renderAddTeamButton() {
var tabButton = {
border: 'none',
fontSize: '20px',
height: '31px',
padding: '2px 0 0 0',
width: '40px',
color: '#999',
fontWeight: 'bold',
margin: '0',
borderRadius: '2px 2px 0 0',
outline: 'none'
};
return (
<NavItem
className='buttonTab'
key='addServerButton'
eventKey='addServerButton'
>
<Button
id='tabBarAddNewTeam'
onClick={this.props.onAddServer}
style={tabButton}
className='btn-tabButton'
title='Add new server'
>
{'+'}
</Button>
</NavItem>
);
}
}
TabBar.propTypes = {
@ -121,6 +95,8 @@ TabBar.propTypes = {
id: PropTypes.string,
onSelect: PropTypes.func,
teams: PropTypes.array,
mentionCounts: PropTypes.array,
mentionAtActiveCounts: PropTypes.array,
onAddServer: PropTypes.func
};

View file

@ -15,17 +15,10 @@ class TeamListItem extends React.Component {
this.props.onTeamEditing();
}
render() {
var style = {
left: {
display: 'inline-block',
width: 'calc(100% - 100px)',
cursor: 'pointer'
}
};
return (
<div className='teamListItem list-group-item'>
<div className='TeamListItem list-group-item'>
<div
style={style.left}
className='TeamListItem-left'
onClick={this.props.onTeamClick}
>
<h4 className='list-group-item-heading'>{ this.props.name }</h4>

View file

@ -1,4 +1,4 @@
.errorView {
.ErrorView {
position: absolute;
top: 0px;
right: 0px;
@ -6,10 +6,35 @@
left: 0px;
}
.errorView-with-tab {
.ErrorView-with-tab {
top: 32px;
}
.errorView-hidden {
.ErrorView-hidden {
visibility: hidden;
}
.ErrorView-tableStyle {
display: table;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.ErrorView-cellStyle {
display: table-cell;
vertical-align: top;
padding-top: 2em;
}
.ErrorView-bullets {
padding-left: 15px;
line-height: 1.7;
}
.ErrorView-techInfo {
font-size: 12px;
color: #aaa;
}

View file

@ -0,0 +1,18 @@
.HoveringURL {
color: gray;
background-color: whitesmoke;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 4px;
padding-right: 16px;
padding-top: 2px;
padding-bottom: 2px;
border-top: solid thin lightgray;
pointer-events: none;
}
.HoveringURL-left {
border-top-right-radius: 4px;
border-right: solid thin lightgray;
}

View file

@ -0,0 +1,9 @@
/*.mainPage,.mainPage > .container-fluid, .mainPage-viewsRow {
height: 100%;
}*/
.MainPage .HoveringURL {
max-width: 95%;
position: absolute;
bottom: 0px;
}

View file

@ -0,0 +1,4 @@
.NewTeamModal-noBottomSpace {
padding-bottom: 0px;
margin-bottom: 0px;
}

View file

@ -0,0 +1,61 @@
.TabBar>li>a {
background: rgba(0, 0, 0, 0.05);
border-radius: 2px 2px 0 0;
border: 1px solid #ddd;
color: #888;
height: 31px;
line-height: 29px;
margin-right: -1px;
margin-top: 0px;
padding: 0 15px;
}
.TabBar .AddServerButton>a {
border: none;
background: transparent;
margin: 0px;
margin-left: 1px; /*Has no border and would be placed above the last item's border due to it's margin-right: -1px */
padding: 0;
margin-bottom: 1px;
}
.TabBar .TabBar-badge {
background: #FF1744;
float: right;
color: white;
min-width: 19px;
font-size: 12px;
text-align: center;
line-height: 20px;
height: 19px;
margin-left: 5px;
margin-top: 5px;
border-radius: 50%;
};
.TabBar .AddServerButton-button {
background-color: #fff;
border-color: #ccc;
color: #333;
margin-top: 3px;
}
.TabBar .AddServerButton-button {
border: none;
font-size: 20px;
height: 31px;
padding: 2px 0 0 0;
width: 40px;
color: #999;
font-weight: bold;
margin: 0;
border-radius: 2px 2px 0 0;
outline: none;
}
.TabBar .AddServerButton-button:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}

View file

@ -0,0 +1,9 @@
.TeamListItem:hover {
background: #eee;
}
.TeamListItem-left {
display: inline-block;
width: calc(100% - 100px);
cursor: pointer;
}

View file

@ -0,0 +1,7 @@
@import url("ErrorView.css");
@import url("HoveringURL.css");
@import url("MainPage.css");
@import url("MattermostView.css");
@import url("NewTeamModal.css");
@import url("TabBar.css");
@import url("TeamListItem.css");

View file

@ -1,5 +1,4 @@
@import url("components/MattermostView.css");
@import url("components/ErrorView.css");
@import url("components/index.css");
.hovering-enter {
opacity: 0.01;
@ -19,40 +18,6 @@
transition: opacity 500ms ease-in-out;
}
.btn-tabButton {
background-color: #fff;
border-color: #ccc;
color: #333;
margin-top: 3px;
}
.btn-tabButton:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.nav-tabs>li>a {
background: rgba(0, 0, 0, 0.05);
border-radius: 2px 2px 0 0;
border: 1px solid #ddd;
color: #888;
height: 31px;
line-height: 29px;
margin-right: -1px;
margin-top: 0px;
padding: 0 15px;
}
.nav-tabs>li.buttonTab>a {
border: none;
background: transparent;
margin: 0px;
margin-left: 1px; /*Has no border and would be placed above the last item's border due to it's margin-right: -1px */
padding: 0;
margin-bottom: 1px;
}
.has-error .control-label,
.has-error .help-block {
color: #333;

View file

@ -1,8 +1,4 @@
.teamListItem:hover {
background: #eee;
}
.IndicatorContainer {
position: absolute;
height: 100%;

View file

@ -4,7 +4,6 @@
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/index.css">
</head>
<body>

View file

@ -1,5 +1,7 @@
'use strict';
require('./css/index.css');
window.eval = global.eval = () => {
throw new Error('Sorry, Mattermost does not support window.eval() for security reasons.');
};

View file

@ -25,6 +25,12 @@ module.exports = merge(base, {
plugins: ['transform-object-rest-spread']
}
}
}, {
test: /\.css$/,
use: [
{loader: 'style-loader'},
{loader: 'css-loader'}
]
}, {
test: /\.mp3$/,
use: {