Skip to content

Commit

Permalink
Media: Manage media scale through Redux preferences state
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Oct 12, 2016
1 parent f6127fb commit 3c8b4c2
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 174 deletions.
72 changes: 3 additions & 69 deletions client/my-sites/media-library/content.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import head from 'lodash/head';
import values from 'lodash/values';
import mapValues from 'lodash/mapValues';
import groupBy from 'lodash/groupBy';
import debounce from 'lodash/debounce';
import debugFactory from 'debug';

/**
* Internal dependencies
Expand All @@ -23,93 +21,32 @@ import MediaListData from 'components/data/media-list-data';
import MediaLibrarySelectedData from 'components/data/media-library-selected-data';
import MediaActions from 'lib/media/actions';
import { ValidationErrors as MediaValidationErrors } from 'lib/media/constants';
import PreferencesActions from 'lib/preferences/actions';
import { isMobile } from 'lib/viewport';
import { getSiteSlug } from 'state/sites/selectors';
import MediaLibraryHeader from './header';
import MediaLibraryList from './list';
/**
* Module variables
*/
const debug = debugFactory( 'calypso:media-library:content' );

const MediaLibraryContent = React.createClass( {
propTypes: {
site: React.PropTypes.object,
preferences: React.PropTypes.object,
mediaValidationErrors: React.PropTypes.object,
filter: React.PropTypes.string,
filterRequiresUpgrade: React.PropTypes.bool,
search: React.PropTypes.string,
containerWidth: React.PropTypes.number,
single: React.PropTypes.bool,
scrollable: React.PropTypes.bool,
mediaScaleChoices: React.PropTypes.arrayOf( React.PropTypes.number ),
initialMediaScale: React.PropTypes.number,
onAddMedia: React.PropTypes.func,
onMediaScaleChange: React.PropTypes.func,
onEditItem: React.PropTypes.func
},

getInitialState: function() {
return {};
},

getDefaultProps: function() {
// To ensure some horizontal padding between items in the same row,
// each of these values is slightly less than the corresponding
// number of items per row.
var scaleChoices = [
1 / 12 - 0.006,
1 / 8 - 0.01,
1 / 6 - 0.01,
1 / 4 - 0.01,
1 / 3 - 0.01
].map( function( scale ) {
return Math.round( 1000 * scale ) / 1000;
} );

return {
preferences: Object.freeze( {} ),
mediaValidationErrors: Object.freeze( {} ),
onAddMedia: noop,
onMediaScaleChange: noop,
mediaScaleChoices: scaleChoices,
initialMediaScale: scaleChoices[2]
onAddMedia: noop
};
},

getMediaScale: function() {
var scale = this.props.initialMediaScale;

if ( this.props.preferences && this.props.preferences.mediaScale ) {
scale = this.props.preferences.mediaScale;
}

if ( this.state.mediaScale ) {
scale = this.state.mediaScale;
}

if ( isMobile() && 1 !== scale ) {
scale = MediaLibraryHeader.SCALE_TOUCH_GRID;
}

return scale;
},

setMediaScalePreference: debounce( function( value ) {
PreferencesActions.set( 'mediaScale', value );
}, 1000 ),

onMediaScaleChange: function( scale ) {
debug( 'onMediaScaleChange scale=%f', scale );
this.setMediaScalePreference( scale );
this.setState( {
mediaScale: scale
} );
this.props.onMediaScaleChange( scale );
},

renderErrors: function() {
var errorTypes, notices;

Expand Down Expand Up @@ -225,7 +162,7 @@ const MediaLibraryContent = React.createClass( {

renderMediaList: function() {
if ( ! this.props.site ) {
return <MediaLibraryList key="list-loading" mediaScale={ this.getMediaScale() } />;
return <MediaLibraryList key="list-loading" />;
}

return (
Expand All @@ -238,7 +175,6 @@ const MediaLibraryContent = React.createClass( {
filterRequiresUpgrade={ this.props.filterRequiresUpgrade }
search={ this.props.search }
containerWidth={ this.props.containerWidth }
mediaScale={ this.getMediaScale() }
photon={ ! this.props.site.is_private }
single={ this.props.single }
scrollable={ this.props.scrollable }
Expand All @@ -255,9 +191,7 @@ const MediaLibraryContent = React.createClass( {
<MediaLibraryHeader
site={ this.props.site }
filter={ this.props.filter }
mediaScale={ this.getMediaScale() }
mediaScaleChoices={ this.props.mediaScaleChoices }
onMediaScaleChange={ this.onMediaScaleChange }
onMediaScaleChange={ this.props.onMediaScaleChange }
onAddMedia={ this.props.onAddMedia }
onAddAndEditImage={ this.props.onAddAndEditImage } />
}
Expand Down
103 changes: 4 additions & 99 deletions client/my-sites/media-library/header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
* External dependencies
*/
import React, { PropTypes } from 'react';
import _debug from 'debug';
const debug = _debug( 'calypso:media-library:header' );

/**
* Internal dependencies
*/
import { isMobile } from 'lib/viewport';
import FormRange from 'components/forms/range';
import Gridicon from 'components/gridicon';
import PopoverMenu from 'components/popover/menu';
import PopoverMenuItem from 'components/popover/menu-item';
import SegmentedControl from 'components/segmented-control';
import SegmentedControlItem from 'components/segmented-control/item';
import MediaLibraryScale from './scale';
import UploadButton from './upload-button';
import MediaLibraryUploadUrl from './upload-url';
import { userCan } from 'lib/site/utils';
Expand All @@ -25,18 +20,11 @@ export default React.createClass( {
propTypes: {
site: PropTypes.object,
filter: PropTypes.string,
scale: PropTypes.number,
onMediaScaleChange: PropTypes.func,
mediaScaleChoices: PropTypes.arrayOf( PropTypes.number ).isRequired,
mediaScale: PropTypes.number.isRequired,
sliderPositionCount: PropTypes.number,
onMediaScaleChange: React.PropTypes.func,
onAddMedia: PropTypes.func
},

statics: {
SCALE_TOUCH_GRID: 0.32
},

getInitialState() {
return {
addingViaUrl: false,
Expand All @@ -47,7 +35,6 @@ export default React.createClass( {
getDefaultProps() {
return {
onAddMedia: () => {},
onMediaScaleChange: () => {},
sliderPositionCount: 100
};
},
Expand All @@ -62,50 +49,6 @@ export default React.createClass( {
} );
},

onMediaScaleChange( event ) {
const sliderPosition = parseInt( event.target.value ),
scaleIndex = sliderPosition * this.props.mediaScaleChoices.length / this.props.sliderPositionCount,
scale = this.props.mediaScaleChoices[ Math.floor( scaleIndex ) ];

debug(
'onMediaScaleChange sliderPosition=%d scaleIndex=%d scale=%f',
sliderPosition, scaleIndex, scale
);

this.props.onMediaScaleChange( scale );
this.setState( { sliderPosition } );
},

getMediaScaleSliderPosition() {
// As part of the smooth motion of the slider, the user can move it
// between two snap points, and we want to remember this.

if ( typeof this.state.sliderPosition !== 'undefined' ) {
return this.state.sliderPosition;
}

const scale = this.props.mediaScale,
scaleIndex = this.props.mediaScaleChoices.indexOf( scale );

// Map the media scale index back to a slider position as follows:
// index 0 -> position 0
// index this.props.mediaScaleChoices.length - 1 -> position this.props.sliderPositionCount - 1

if ( scaleIndex < 0 ) {
debug( 'getMediaScaleSliderPosition unrecognized scale %f', scale );
return 0;
}

const { sliderPositionCount, mediaScaleChoices } = this.props,
sliderPosition = Math.floor( scaleIndex * ( sliderPositionCount - 1 ) / ( mediaScaleChoices.length - 1 ) );

debug(
'getMediaScaleSliderPosition scale=%f scaleIndex=%d sliderPosition=%d',
scale, scaleIndex, sliderPosition
);
return sliderPosition;
},

toggleAddViaUrl( state ) {
this.setState( {
addingViaUrl: state,
Expand Down Expand Up @@ -163,45 +106,6 @@ export default React.createClass( {
);
},

renderScaleToggle() {
const { mediaScale, sliderPositionCount, onMediaScaleChange } = this.props;

if ( isMobile() ) {
return (
<SegmentedControl className="media-library__scale-toggle" compact>
<SegmentedControlItem
selected={ 1 !== mediaScale }
onClick={ () => onMediaScaleChange( this.constructor.SCALE_TOUCH_GRID ) }>
<span className="screen-reader-text">
{ this.translate( 'Grid' ) }
</span>
<Gridicon icon="grid" />
</SegmentedControlItem>
<SegmentedControlItem
selected={ 1 === mediaScale }
onClick={ () => onMediaScaleChange( 1 ) }>
<span className="screen-reader-text">
{ this.translate( 'List' ) }
</span>
<Gridicon icon="menu" />
</SegmentedControlItem>
</SegmentedControl>
);
}

return (
<FormRange
step="1"
min="0"
max={ sliderPositionCount - 1 }
minContent={ <Gridicon icon="image" size={ 16 } /> }
maxContent={ <Gridicon icon="image" size={ 24 }/> }
value={ this.getMediaScaleSliderPosition() }
onChange={ this.onMediaScaleChange }
className="media-library__scale-range" />
);
},

render() {
const { site, onAddMedia } = this.props;

Expand All @@ -219,7 +123,8 @@ export default React.createClass( {
<header className="media-library__header">
<h2 className="media-library__heading">{ this.translate( 'Media Library' ) }</h2>
{ this.renderUploadButtons() }
{ this.renderScaleToggle() }
<MediaLibraryScale
onChange={ this.props.onMediaScaleChange } />
</header>
);
}
Expand Down
7 changes: 3 additions & 4 deletions client/my-sites/media-library/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ var Content = require( './content' ),
MediaUtils = require( 'lib/media/utils' ),
filterToMimePrefix = require( './filter-to-mime-prefix' ),
FilterBar = require( './filter-bar' ),
PreferencesData = require( 'components/data/preferences-data' ),
MediaValidationData = require( 'components/data/media-validation-data' ),
urlSearch = require( 'lib/mixins/url-search' );
import QueryPreferences from 'components/data/query-preferences';

module.exports = React.createClass( {
displayName: 'MediaLibrary',
Expand Down Expand Up @@ -145,6 +145,7 @@ module.exports = React.createClass( {

return (
<div className={ classes }>
<QueryPreferences />
{ this.renderDropZone() }
<FilterBar
site={ this.props.site }
Expand All @@ -154,9 +155,7 @@ module.exports = React.createClass( {
search={ this.props.search }
onFilterChange={ this.props.onFilterChange }
onSearch={ this.doSearch } />
<PreferencesData>
{ content }
</PreferencesData>
{ content }
</div>
);
}
Expand Down
9 changes: 8 additions & 1 deletion client/my-sites/media-library/list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ var ReactDom = require( 'react-dom' ),
filter = require( 'lodash/filter' ),
findIndex = require( 'lodash/findIndex' );

import { connect } from 'react-redux';

/**
* Internal dependencies
*/
Expand All @@ -20,8 +22,9 @@ var MediaActions = require( 'lib/media/actions' ),
user = require( 'lib/user' )();

import ListPlanUpgradeNudge from './list-plan-upgrade-nudge';
import { getPreference } from 'state/preferences/selectors';

module.exports = React.createClass( {
export const MediaLibraryList = React.createClass( {
displayName: 'MediaLibraryList',

propTypes: {
Expand Down Expand Up @@ -233,3 +236,7 @@ module.exports = React.createClass( {
);
}
} );

export default connect( ( state ) => ( {
mediaScale: getPreference( state, 'mediaScale' )
} ), null, null, { pure: false } )( MediaLibraryList );
Loading

0 comments on commit 3c8b4c2

Please sign in to comment.