slim_mode for JSX elements to hide/show depending on responsive rules

This commit is contained in:
James Barnsley
2017-07-17 07:16:33 +12:00
parent 1889186bed
commit d757792495
12 changed files with 80 additions and 30 deletions

View File

@ -30,11 +30,19 @@ class App extends React.Component{
super(props);
this.handleKeyUp = this.handleKeyUp.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleWindowResize = this.handleWindowResize.bind(this);
}
componentWillMount(){
window.addEventListener("keyup", this.handleKeyUp, false);
window.addEventListener("keydown", this.handleKeyDown, false);
window.addEventListener("resize", this.handleWindowResize, false);
}
componentWillUnmount(){
window.removeEventListener("keyup", this.handleKeyUp, false);
window.removeEventListener("keydown", this.handleKeyDown, false);
window.removeEventListener("resize", this.handleWindowResize, false);
}
componentDidMount(){
@ -56,6 +64,9 @@ class App extends React.Component{
// hide our sidebar
this.props.uiActions.toggleSidebar( false )
});
// Check our slim_mode
this.handleWindowResize(null)
}
componentWillReceiveProps(nextProps){
@ -76,11 +87,6 @@ class App extends React.Component{
}
}
componentWillUnmount(){
window.removeEventListener("keyup", this.handleKeyUp, false);
window.removeEventListener("keydown", this.handleKeyDown, false);
}
shouldTriggerShortcut(e){
var ignoreNodes = ['INPUT', 'TEXTAREA']
var keyCodes = [32,27,191,37,38,39,40,70]
@ -95,6 +101,21 @@ class App extends React.Component{
}
}
handleWindowResize(e){
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
if (width <= 800){
if (!this.props.slim_mode){
this.props.uiActions.setSlimMode(true)
}
} else {
if (this.props.slim_mode){
this.props.uiActions.setSlimMode(false)
}
}
}
handleKeyDown(e){
this.shouldTriggerShortcut(e)
}
@ -197,6 +218,7 @@ class App extends React.Component{
if (this.props.dragger && this.props.dragger.active) className += ' dragging'
if (this.props.sidebar_open) className += ' sidebar-open'
if (this.props.modal) className += ' modal-open'
if (this.props.slim_mode) className += ' slim-mode'
if (helpers.isTouchDevice()){
className += ' touch'
} else {
@ -236,6 +258,7 @@ class App extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
slim_mode: state.ui.slim_mode,
broadcasts: (state.ui.broadcasts ? state.ui.broadcasts : []),
volume: (state.mopidy.volume ? state.mopidy.volume : false),
notifications: (state.ui.notifications ? state.ui.notifications : []),

1
src/js/bootstrap.js vendored
View File

@ -53,6 +53,7 @@ var initialState = {
autocomplete_results: {}
},
ui: {
slim_mode: false,
current_tracklist: [],
current_tltrack: false,
notifications: [],

View File

@ -81,6 +81,9 @@ class DebugInfo extends React.Component{
Enqueue batches: {this.props.mopidy.enqueue_uris_batches ? this.props.mopidy.enqueue_uris_batches.length : '0'}
</div>
<br />
<div className="item">
Slim mode: {this.props.ui.slim_mode ? 'on' : 'off'}
</div>
<div className="item">
_testMode: {window._testMode ? 'on' : 'off'}
</div>

View File

@ -16,26 +16,32 @@ export default class Header extends React.Component{
}
}
handleContextMenuTrigger(e,options){
e.preventDefault()
var data = {
e: e,
context: 'custom',
title: this.props.title,
options: options
handleContextMenuTrigger(e,options){
// We have an override trigger (eg Album, Playlist)
if (this.props.handleContextMenuTrigger){
return this.props.handleContextMenuTrigger(e)
} else {
e.preventDefault()
var data = {
e: e,
context: 'custom',
title: this.props.title,
options: options
}
this.props.uiActions.showContextMenu(data)
}
this.props.uiActions.showContextMenu(data)
}
renderOptions(){
if (!this.props.options) return null
if (!this.props.options && !this.props.handleContextMenuTrigger) return null
return (
<div className='options'>
<ContextMenuTrigger onTrigger={e => this.handleContextMenuTrigger(e,this.props.options)} />
<span className="items">
<span className="liner">
{ this.props.options }
{this.props.options ? this.props.options : null}
</span>
</span>
</div>

View File

@ -30,6 +30,13 @@ export function showContextMenu(data){
}
}
export function setSlimMode(slim_mode){
return {
type: 'SET_SLIM_MODE',
slim_mode: slim_mode
}
}
export function hideContextMenu(){
return {
type: 'HIDE_CONTEXT_MENU'

View File

@ -7,6 +7,9 @@ export default function reducer(ui = {}, action){
case 'LAZY_LOADING':
return Object.assign({}, ui, { lazy_loading: action.start });
case 'SET_SLIM_MODE':
return Object.assign({}, ui, { slim_mode: action.slim_mode });
case 'DEBUG':
return Object.assign({}, ui, { debug_response: action.response })

View File

@ -4,6 +4,7 @@ import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import FontAwesome from 'react-fontawesome'
import Header from '../components/Header'
import TrackList from '../components/TrackList'
import Thumbnail from '../components/Thumbnail'
import Parallax from '../components/Parallax'
@ -12,7 +13,6 @@ import ArtistGrid from '../components/ArtistGrid'
import FollowButton from '../components/FollowButton'
import Dater from '../components/Dater'
import LazyLoadListener from '../components/LazyLoadListener'
import SidebarToggleButton from '../components/SidebarToggleButton'
import ContextMenuTrigger from '../components/ContextMenuTrigger'
import * as helpers from '../helpers'
@ -121,7 +121,7 @@ class Album extends React.Component{
return (
<div className="view album-view content-wrapper">
<SidebarToggleButton />
{this.props.slim_mode ? <Header icon="cd" title="Album" handleContextMenuTrigger={e => this.handleContextMenu(e)} uiActions={this.props.uiActions} /> : null}
<div className="thumbnail-wrapper">
<Thumbnail size="large" canZoom images={ this.props.album.images } />
@ -150,7 +150,7 @@ class Album extends React.Component{
<div className="actions">
<button className="primary" onClick={e => this.play()}>Play</button>
{ helpers.uriSource(this.props.params.uri) == 'spotify' ? <FollowButton className="secondary" uri={this.props.params.uri} addText="Add to library" removeText="Remove from library" is_following={this.inLibrary()} /> : null }
<ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />
{this.props.slim_mode ? null : <ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />}
</div>
<section className="list-wrapper">
@ -172,6 +172,7 @@ class Album extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
slim_mode: state.ui.slim_mode,
load_queue: state.ui.load_queue,
artists: state.ui.artists,
album: (state.ui.albums && typeof(state.ui.albums[ownProps.params.uri]) !== 'undefined' ? state.ui.albums[ownProps.params.uri] : false ),

View File

@ -201,7 +201,7 @@ class Artist extends React.Component{
return (
<div className="view artist-view">
<SidebarToggleButton />
{this.props.slim_mode ? <Header className="overlay" icon="mic" title="Artist" handleContextMenuTrigger={e => this.handleContextMenu(e)} uiActions={this.props.uiActions} /> : null}
<div className="intro">
@ -213,7 +213,7 @@ class Artist extends React.Component{
<div className="actions">
{ can_play_radio ? <button className="primary" onClick={e => this.props.pusherActions.startRadio([this.props.artist.uri])}>Start radio</button> : <button className="primary" onClick={e => this.props.mopidyActions.playURIs(this.props.artist.albums_uris, this.props.artist.uri)}>Play all</button>}
{ can_follow ? <FollowButton className="white" uri={this.props.params.uri} removeText="Remove from library" addText="Add to library" is_following={this.inLibrary()} /> : null}
<ContextMenuTrigger className="white" onTrigger={e => this.handleContextMenu(e)} />
{this.props.slim_mode ? null : <ContextMenuTrigger className="white" onTrigger={e => this.handleContextMenu(e)} />}
</div>
{ this.renderSubViewMenu() }
</div>
@ -260,6 +260,7 @@ class Artist extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
slim_mode: state.ui.slim_mode,
load_queue: state.ui.load_queue,
artist: (state.ui.artists && typeof(state.ui.artists[ownProps.params.uri]) !== 'undefined' ? state.ui.artists[ownProps.params.uri] : false ),
artists: (state.ui.artists ? state.ui.artists : []),

View File

@ -12,7 +12,7 @@ import Dater from '../components/Dater'
import ConfirmationButton from '../components/ConfirmationButton'
import LazyLoadListener from '../components/LazyLoadListener'
import FollowButton from '../components/FollowButton'
import SidebarToggleButton from '../components/SidebarToggleButton'
import Header from '../components/Header'
import ContextMenuTrigger from '../components/ContextMenuTrigger'
import * as helpers from '../helpers'
@ -115,7 +115,7 @@ class Playlist extends React.Component{
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<button className="secondary" onClick={ e => this.props.uiActions.openModal('edit_playlist', { uri: this.props.playlist.uri, name: this.props.playlist.name }) }>Edit</button>
<ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />
{this.props.slim_mode ? null : <ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />}
</div>
)
@ -125,7 +125,7 @@ class Playlist extends React.Component{
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<button className="secondary" onClick={ e => this.props.uiActions.openModal('edit_playlist', { uri: this.props.playlist.uri, name: this.props.playlist.name, is_public: this.props.playlist.public, description: this.props.playlist.description }) }>Edit</button>
<ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />
{this.props.slim_mode ? null : <ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />}
</div>
)
}
@ -133,7 +133,7 @@ class Playlist extends React.Component{
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<FollowButton className="secondary" uri={this.props.playlist.uri} addText="Add to library" removeText="Remove from library" is_following={this.inLibrary()} />
<ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />
{this.props.slim_mode ? null : <ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />}
</div>
)
@ -141,7 +141,7 @@ class Playlist extends React.Component{
return (
<div className="actions">
<button className="primary" onClick={ e => this.play() }>Play</button>
<ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />
{this.props.slim_mode ? null : <ContextMenuTrigger onTrigger={e => this.handleContextMenu(e)} />}
</div>
)
}
@ -166,8 +166,8 @@ class Playlist extends React.Component{
return (
<div className="view playlist-view content-wrapper">
<SidebarToggleButton />
{this.props.slim_mode ? <Header icon="playlist" title="Playlist" handleContextMenuTrigger={e => this.handleContextMenu(e)} uiActions={this.props.uiActions} /> : null}
<div className="thumbnail-wrapper">
<Thumbnail size="large" canZoom images={ this.props.playlist.images } />
@ -216,6 +216,7 @@ const mapStateToProps = (state, ownProps) => {
var uri = ownProps.params.uri
uri = uri.replace(' ','%20')
return {
slim_mode: state.ui.slim_mode,
load_queue: state.ui.load_queue,
playlist: (state.ui.playlists && typeof(state.ui.playlists[uri]) !== 'undefined' ? state.ui.playlists[uri] : false ),
library_playlists: state.ui.library_playlists,

View File

@ -47,7 +47,7 @@ class QueueHistory extends React.Component{
)
return (
<div className="view queue-history-view">
<div className="view queue-history-view">
<Header icon="play" title="Playback history" options={options} uiActions={this.props.uiActions} />
<section className="content-wrapper list-wrapper">

View File

@ -64,6 +64,12 @@ main {
-moz-filter: invert(1);
filter: invert(1);
}
.context-menu-trigger {
.dot {
background: $white;
}
}
}
@include responsive( $bp_medium ){

View File

@ -139,8 +139,6 @@
}
&.about {
padding: 0 20px 20px 20px;
.col.w40,
.col.w60 {
@include clearfix();