Make userlist responsive

This commit is contained in:
Ken-Håvard Lieng 2016-01-11 23:31:06 +01:00
parent 937560e859
commit 67b83fa3d6
15 changed files with 115 additions and 51 deletions

File diff suppressed because one or more lines are too long

View File

@ -252,6 +252,15 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
background: #DDD; background: #DDD;
} }
.button-userlist {
display: none;
border-left: 1px solid #DDD;
}
.chat-server .button-userlist, .chat-private .button-userlist {
display: none;
}
.chat-title { .chat-title {
margin-left: 15px; margin-left: 15px;
font-size: 24px; font-size: 24px;
@ -309,7 +318,7 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
top: 50px; top: 50px;
bottom: 50px; bottom: 50px;
right: 200px; right: 200px;
z-index: 2; z-index: 3;
background: #f0f0f0; background: #f0f0f0;
} }
@ -398,6 +407,9 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
right: 0; right: 0;
width: 200px; width: 200px;
border-left: 1px solid #DDD; border-left: 1px solid #DDD;
background: #f0f0f0;
z-index: 2;
transition: transform .2s;
} }
.userlist > div { .userlist > div {
@ -492,4 +504,32 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.chat-title { .chat-title {
margin-left: 0; margin-left: 0;
} }
.userlist-bar {
display: none;
}
.userlist {
transform: translateX(200px);
}
.userlist.off-canvas {
transform: translateX(0);
}
.chat-channel .chat-title-bar, .chat-channel .messagebox {
right: 0;
}
.button-userlist {
display: inline-block;
}
.chat-topic {
display: none;
}
.search {
right: 0;
}
} }

View File

@ -39,5 +39,6 @@ export const SOCKET_USERS = 'SOCKET_USERS';
export const TAB_HISTORY_POP = 'TAB_HISTORY_POP'; export const TAB_HISTORY_POP = 'TAB_HISTORY_POP';
export const TOGGLE_MENU = 'TOGGLE_MENU'; export const TOGGLE_MENU = 'TOGGLE_MENU';
export const TOGGLE_SEARCH = 'TOGGLE_SEARCH'; export const TOGGLE_SEARCH = 'TOGGLE_SEARCH';
export const TOGGLE_USERLIST = 'TOGGLE_USERLIST';
export const UPLOAD_CERT = 'UPLOAD_CERT'; export const UPLOAD_CERT = 'UPLOAD_CERT';
export const WHOIS = 'WHOIS'; export const WHOIS = 'WHOIS';

View File

@ -46,15 +46,3 @@ export function setSelectedUser(server, user = null) {
user user
}; };
} }
export function hideMenu() {
return {
type: actions.HIDE_MENU
};
}
export function toggleMenu() {
return {
type: actions.TOGGLE_MENU
};
}

View File

@ -0,0 +1,19 @@
import * as actions from '../actions';
export function hideMenu() {
return {
type: actions.HIDE_MENU
};
}
export function toggleMenu() {
return {
type: actions.TOGGLE_MENU
};
}
export function toggleUserList() {
return {
type: actions.TOGGLE_USERLIST
};
}

View File

@ -19,7 +19,7 @@ export default class ChatTitle extends Component {
}; };
render() { render() {
const { title, tab, channel, toggleSearch } = this.props; const { title, tab, channel, toggleSearch, toggleUserList } = this.props;
const topic = Autolinker.link(channel.get('topic') || '', { stripPrefix: false }); const topic = Autolinker.link(channel.get('topic') || '', { stripPrefix: false });
let leaveTitle; let leaveTitle;
@ -45,6 +45,7 @@ export default class ChatTitle extends Component {
title={leaveTitle} title={leaveTitle}
onClick={this.handleLeaveClick} onClick={this.handleLeaveClick}
/> />
<i className="icon-user button-userlist" onClick={toggleUserList} />
</div> </div>
<div className="userlist-bar"> <div className="userlist-bar">
<i className="icon-user" /> <i className="icon-user" />

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import pure from 'pure-render-decorator'; import pure from 'pure-render-decorator';
import { toggleMenu } from '../actions/tab'; import { toggleMenu } from '../actions/ui';
@pure @pure
class Navicon extends Component { class Navicon extends Component {

View File

@ -20,8 +20,8 @@ export default class TabList extends Component {
}; };
render() { render() {
const { channels, servers, privateChats, showMenu, selected } = this.props; const { channels, servers, privateChats, showTabList, selected } = this.props;
const className = showMenu ? 'tablist off-canvas' : 'tablist'; const className = showTabList ? 'tablist off-canvas' : 'tablist';
const tabs = []; const tabs = [];
channels.forEach((server, address) => { channels.forEach((server, address) => {

View File

@ -22,7 +22,8 @@ export default class UserList extends Component {
}; };
render() { render() {
const { tab, openPrivateChat, select } = this.props; const { tab, openPrivateChat, select, showUserList } = this.props;
const className = showUserList ? 'userlist off-canvas' : 'userlist';
const users = []; const users = [];
const style = {}; const style = {};
@ -41,7 +42,7 @@ export default class UserList extends Component {
} }
return ( return (
<div className="userlist" style={style}> <div className={className} style={style}>
<Infinite containerHeight={this.state.height} elementHeight={24}> <Infinite containerHeight={this.state.height} elementHeight={24}>
{users} {users}
</Infinite> </Infinite>

View File

@ -3,13 +3,14 @@ import { connect } from 'react-redux';
import { pushPath } from 'redux-simple-router'; import { pushPath } from 'redux-simple-router';
import pure from 'pure-render-decorator'; import pure from 'pure-render-decorator';
import TabList from '../components/TabList'; import TabList from '../components/TabList';
import * as actions from '../actions/tab'; import { select } from '../actions/tab';
import { hideMenu } from '../actions/ui';
@pure @pure
class App extends Component { class App extends Component {
render() { render() {
const { showMenu, children } = this.props; const { showTabList, children } = this.props;
const mainClass = showMenu ? 'main-container off-canvas' : 'main-container'; const mainClass = showTabList ? 'main-container off-canvas' : 'main-container';
return ( return (
<div> <div>
<TabList {...this.props} /> <TabList {...this.props} />
@ -26,9 +27,9 @@ function mapStateToProps(state) {
servers: state.servers, servers: state.servers,
channels: state.channels, channels: state.channels,
privateChats: state.privateChats, privateChats: state.privateChats,
showMenu: state.showMenu, showTabList: state.ui.showTabList,
selected: state.tab.selected selected: state.tab.selected
}; };
} }
export default connect(mapStateToProps, { pushPath, ...actions })(App); export default connect(mapStateToProps, { pushPath, select, hideMenu })(App);

View File

@ -15,9 +15,10 @@ import { searchMessages, toggleSearch } from '../actions/search';
import { select, setSelectedChannel, setSelectedUser } from '../actions/tab'; import { select, setSelectedChannel, setSelectedUser } from '../actions/tab';
import { runCommand, sendMessage } from '../actions/message'; import { runCommand, sendMessage } from '../actions/message';
import { disconnect } from '../actions/server'; import { disconnect } from '../actions/server';
import * as inputHistoryActions from '../actions/inputHistory';
import { setWrapWidth, setCharWidth } from '../actions/environment'; import { setWrapWidth, setCharWidth } from '../actions/environment';
import { stringWidth, wrapMessages } from '../util'; import { stringWidth, wrapMessages } from '../util';
import { toggleUserList } from '../actions/ui';
import * as inputHistoryActions from '../actions/inputHistory';
function updateSelected({ params, dispatch }) { function updateSelected({ params, dispatch }) {
if (params.channel) { if (params.channel) {
@ -134,6 +135,7 @@ function mapStateToProps(state) {
users: channel.get('users', List()), users: channel.get('users', List()),
history: state.input.index === -1 ? null : state.input.history.get(state.input.index), history: state.input.index === -1 ? null : state.input.history.get(state.input.index),
messages: wrappedMessagesSelector(state), messages: wrappedMessagesSelector(state),
showUserList: state.ui.showUserList,
channel, channel,
tab tab
}; };
@ -145,6 +147,7 @@ function mapDispatchToProps(dispatch) {
...bindActionCreators({ ...bindActionCreators({
select, select,
toggleSearch, toggleSearch,
toggleUserList,
searchMessages, searchMessages,
runCommand, runCommand,
sendMessage, sendMessage,

View File

@ -4,7 +4,7 @@ import DockMonitor from 'redux-devtools-dock-monitor';
import LogMonitor from 'redux-devtools-log-monitor'; import LogMonitor from 'redux-devtools-log-monitor';
export default createDevTools( export default createDevTools(
<DockMonitor toggleVisibilityKey="ctrl-h" changePositionKey="ctrl-q"> <DockMonitor toggleVisibilityKey="ctrl-h" changePositionKey="ctrl-q" defaultIsVisible={false}>
<LogMonitor theme="tomorrow" /> <LogMonitor theme="tomorrow" />
</DockMonitor> </DockMonitor>
); );

View File

@ -8,8 +8,8 @@ import privateChats from './privateChats';
import search from './search'; import search from './search';
import servers from './servers'; import servers from './servers';
import settings from './settings'; import settings from './settings';
import showMenu from './showMenu';
import tab from './tab'; import tab from './tab';
import ui from './ui';
export default combineReducers({ export default combineReducers({
routing: routeReducer, routing: routeReducer,
@ -21,6 +21,6 @@ export default combineReducers({
search, search,
servers, servers,
settings, settings,
showMenu, tab,
tab ui
}); });

View File

@ -1,12 +0,0 @@
import createReducer from '../util/createReducer';
import * as actions from '../actions';
export default createReducer(false, {
[actions.TOGGLE_MENU](state) {
return !state;
},
[actions.HIDE_MENU]() {
return false;
}
});

View File

@ -0,0 +1,22 @@
import { Record } from 'immutable';
import createReducer from '../util/createReducer';
import * as actions from '../actions';
const State = Record({
showTabList: false,
showUserList: false
});
export default createReducer(new State(), {
[actions.TOGGLE_MENU](state) {
return state.update('showTabList', show => !show);
},
[actions.HIDE_MENU](state) {
return state.set('showTabList', false);
},
[actions.TOGGLE_USERLIST](state) {
return state.update('showUserList', show => !show);
}
});