Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: Persist the selected editor mode across reloads #2568

Merged
merged 6 commits into from
Aug 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions editor/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ import { getBlockTypes } from '@wordpress/blocks';
*/
import { combineUndoableReducers } from './utils/undoable-reducer';

const isMobile = window.innerWidth < 782;
/**
* Module constants
*/
const DEFAULT_PREFERENCES = {
mode: 'visual',
isSidebarOpened: window.innerWidth >= 782,
panels: { 'post-status': true },
};

/**
* Returns a post attribute value, flattening nested rendered content using its
Expand Down Expand Up @@ -426,22 +433,16 @@ export function showInsertionPoint( state = false, action ) {
}

/**
* Reducer returning current editor mode, either "visual" or "text".
* Reducer returning the user preferences:
*
* @param {string} state Current state
* @param {Object} action Dispatched action
* @return {string} Updated state
* @param {Object} state Current state
* @param {string} state.mode Current editor mode, either "visual" or "text".
* @param {Boolean} state.isSidebarOpened Whether the sidebar is opened or closed
* @param {Object} state.panels The state of the different sidebar panels
* @param {Object} action Dispatched action
* @return {string} Updated state
*/
export function mode( state = 'visual', action ) {
switch ( action.type ) {
case 'SWITCH_MODE':
return action.mode;
}

return state;
}

export function preferences( state = { isSidebarOpened: ! isMobile, panels: { 'post-status': true } }, action ) {
export function preferences( state = DEFAULT_PREFERENCES, action ) {
switch ( action.type ) {
case 'TOGGLE_SIDEBAR':
return {
Expand All @@ -456,6 +457,11 @@ export function preferences( state = { isSidebarOpened: ! isMobile, panels: { 'p
[ action.panel ]: ! get( state, [ 'panels', action.panel ], false ),
},
};
case 'SWITCH_MODE':
return {
...state,
mode: action.mode,
};
}

return state;
Expand Down Expand Up @@ -530,7 +536,6 @@ export default optimist( combineReducers( {
blockSelection,
hoveredBlock,
showInsertionPoint,
mode,
preferences,
panel,
saving,
Expand Down
8 changes: 5 additions & 3 deletions editor/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { addQueryArgs } from '@wordpress/url';
* @return {String} Editing mode
*/
export function getEditorMode( state ) {
return state.mode;
return getPreference( state, 'mode', 'visual' );
}

/**
Expand All @@ -46,11 +46,13 @@ export function getPreferences( state ) {
*
* @param {Object} state Global application state
* @param {String} preferenceKey Preference Key
* @param {Mixed} defaultValue Default Value
* @return {Mixed} Preference Value
*/
export function getPreference( state, preferenceKey ) {
export function getPreference( state, preferenceKey, defaultValue ) {
const preferences = getPreferences( state );
return preferences[ preferenceKey ];
const value = preferences[ preferenceKey ];
return value === undefined ? defaultValue : value;
}

/**
Expand Down
10 changes: 7 additions & 3 deletions editor/sidebar/discussion-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ import { editPost, toggleSidebarPanel } from '../../actions';
*/
const PANEL_NAME = 'discussion-panel';

function DiscussionPanel( { pingStatus = 'open', commentStatus = 'open', instanceId, isOpened, ...props } ) {
function DiscussionPanel( { pingStatus = 'open', commentStatus = 'open', instanceId, isOpened, onTogglePanel, ...props } ) {
const onTogglePingback = () => props.editPost( { ping_status: pingStatus === 'open' ? 'closed' : 'open' } );
const onToggleComments = () => props.editPost( { comment_status: commentStatus === 'open' ? 'closed' : 'open' } );
const onTogglePanel = () => props.toggleSidebarPanel( PANEL_NAME );

const commentsToggleId = 'allow-comments-toggle-' + instanceId;
const pingbacksToggleId = 'allow-pingbacks-toggle-' + instanceId;
Expand Down Expand Up @@ -60,6 +59,11 @@ export default connect(
isOpened: isEditorSidebarPanelOpened( state, PANEL_NAME ),
};
},
{ editPost, toggleSidebarPanel }
{
editPost,
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
)( withInstanceId( DiscussionPanel ) );

10 changes: 5 additions & 5 deletions editor/sidebar/featured-image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ import { editPost, toggleSidebarPanel } from '../../actions';
*/
const PANEL_NAME = 'featured-image';

function FeaturedImage( { featuredImageId, onUpdateImage, onRemoveImage, media, isOpened, ...props } ) {
const onToggle = () => props.toggleSidebarPanel( PANEL_NAME );

function FeaturedImage( { featuredImageId, onUpdateImage, onRemoveImage, media, isOpened, onTogglePanel } ) {
return (
<PanelBody title={ __( 'Featured image' ) } opened={ isOpened } onToggle={ onToggle }>
<PanelBody title={ __( 'Featured image' ) } opened={ isOpened } onToggle={ onTogglePanel }>
<div className="editor-featured-image__content">
{ !! featuredImageId &&
<MediaUploadButton
Expand Down Expand Up @@ -84,7 +82,9 @@ const applyConnect = connect(
onRemoveImage() {
return editPost( { featured_media: null } );
},
toggleSidebarPanel,
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
);

Expand Down
13 changes: 5 additions & 8 deletions editor/sidebar/page-attributes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export class PageAttributes extends Component {
super( ...arguments );

this.setUpdatedOrder = this.setUpdatedOrder.bind( this );
this.onToggle = this.onToggle.bind( this );

this.state = {
supportsPageAttributes: false,
Expand All @@ -41,12 +40,8 @@ export class PageAttributes extends Component {
}
}

onToggle() {
this.props.toggleSidebarPanel( PANEL_NAME );
}

render() {
const { instanceId, order, postType, isOpened } = this.props;
const { instanceId, order, postType, isOpened, onTogglePanel } = this.props;
const supportsPageAttributes = get( postType.data, [
'supports',
'page-attributes',
Expand All @@ -64,7 +59,7 @@ export class PageAttributes extends Component {
<PanelBody
title={ __( 'Page Attributes' ) }
opened={ isOpened }
onToggle={ this.onToggle }
onToggle={ onTogglePanel }
>
<PanelRow>
<label htmlFor={ inputId }>
Expand Down Expand Up @@ -96,7 +91,9 @@ const applyConnect = connect(
menu_order: order,
} );
},
toggleSidebarPanel,
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
);

Expand Down
7 changes: 4 additions & 3 deletions editor/sidebar/post-excerpt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ import { editPost, toggleSidebarPanel } from '../../actions';
*/
const PANEL_NAME = 'post-excerpt';

function PostExcerpt( { excerpt, onUpdateExcerpt, isOpened, ...props } ) {
function PostExcerpt( { excerpt, onUpdateExcerpt, isOpened, onTogglePanel } ) {
const onChange = ( event ) => onUpdateExcerpt( event.target.value );
const onTogglePanel = () => props.toggleSidebarPanel( PANEL_NAME );

return (
<PanelBody title={ __( 'Excerpt' ) } opened={ isOpened } onToggle={ onTogglePanel }>
Expand Down Expand Up @@ -52,7 +51,9 @@ export default connect(
onUpdateExcerpt( excerpt ) {
return editPost( { excerpt } );
},
toggleSidebarPanel,
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
)( PostExcerpt );

13 changes: 5 additions & 8 deletions editor/sidebar/post-status/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class PostStatus extends Component {
constructor() {
super( ...arguments );
this.togglePendingStatus = this.togglePendingStatus.bind( this );
this.togglePanel = this.togglePanel.bind( this );
}

togglePendingStatus() {
Expand All @@ -44,16 +43,12 @@ class PostStatus extends Component {
onUpdateStatus( updatedStatus );
}

togglePanel() {
this.props.toggleSidebarPanel( PANEL_NAME );
}

render() {
const { status, isPublished, isOpened, instanceId } = this.props;
const { status, isPublished, isOpened, instanceId, onTogglePanel } = this.props;
const pendingId = 'pending-toggle-' + instanceId;

return (
<PanelBody title={ __( 'Status & Visibility' ) } opened={ isOpened } onToggle={ this.togglePanel }>
<PanelBody title={ __( 'Status & Visibility' ) } opened={ isOpened } onToggle={ onTogglePanel }>
{ ! isPublished &&
<PanelRow>
<label htmlFor={ pendingId }>{ __( 'Pending review' ) }</label>
Expand Down Expand Up @@ -86,7 +81,9 @@ export default connect(
onUpdateStatus( status ) {
return editPost( { status } );
},
toggleSidebarPanel,
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
)( withInstanceId( PostStatus ) );

18 changes: 10 additions & 8 deletions editor/sidebar/post-taxonomies/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class PostTaxonomies extends Component {
constructor() {
super( ...arguments );

this.onToggle = this.onToggle.bind( this );

this.state = {
taxonomies: [],
};
Expand All @@ -47,10 +45,6 @@ class PostTaxonomies extends Component {
this.fetchTaxonomies.abort();
}

onToggle() {
this.props.toggleSidebarPanel( PANEL_NAME );
}

render() {
const availableTaxonomies = this.state.taxonomies
.filter( ( taxonomy ) => taxonomy.types.indexOf( this.props.postType ) !== -1 );
Expand All @@ -60,7 +54,11 @@ class PostTaxonomies extends Component {
}

return (
<PanelBody title={ __( 'Categories & Tags' ) } opened={ this.props.isOpened } onToggle={ this.onToggle }>
<PanelBody
title={ __( 'Categories & Tags' ) }
opened={ this.props.isOpened }
onToggle={ this.props.onTogglePanel }
>
{ availableTaxonomies.map( ( taxonomy ) => {
const TaxonomyComponent = taxonomy.hierarchical ? HierarchicalTermSelector : FlatTermSelector;
return (
Expand All @@ -84,6 +82,10 @@ export default connect(
isOpened: isEditorSidebarPanelOpened( state, PANEL_NAME ),
};
},
{ toggleSidebarPanel }
{
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
)( PostTaxonomies );

7 changes: 4 additions & 3 deletions editor/sidebar/table-of-contents/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ const getHeadingLevel = heading => {

const isEmptyHeading = heading => ! heading.attributes.content || heading.attributes.content.length === 0;

const TableOfContents = ( { blocks, onSelect, isOpened, ...props } ) => {
const TableOfContents = ( { blocks, onSelect, isOpened, onTogglePanel } ) => {
const headings = filter( blocks, ( block ) => block.name === 'core/heading' );
const onTogglePanel = () => props.toggleSidebarPanel( PANEL_NAME );

if ( headings.length <= 1 ) {
return null;
Expand Down Expand Up @@ -117,6 +116,8 @@ export default connect(
onSelect( uid ) {
return selectBlock( uid );
},
toggleSidebarPanel,
onTogglePanel() {
return toggleSidebarPanel( PANEL_NAME );
},
}
)( TableOfContents );
29 changes: 10 additions & 19 deletions editor/test/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
hoveredBlock,
isTyping,
blockSelection,
mode,
preferences,
saving,
notices,
Expand Down Expand Up @@ -784,28 +783,11 @@ describe( 'state', () => {
} );
} );

describe( 'mode()', () => {
it( 'should return "visual" by default', () => {
const state = mode( undefined, {} );

expect( state ).toBe( 'visual' );
} );

it( 'should return switched mode', () => {
const state = mode( null, {
type: 'SWITCH_MODE',
mode: 'text',
} );

expect( state ).toBe( 'text' );
} );
} );

describe( 'preferences()', () => {
it( 'should be opened by default and show the post-status panel', () => {
const state = preferences( undefined, {} );

expect( state ).toEqual( { isSidebarOpened: true, panels: { 'post-status': true } } );
expect( state ).toEqual( { mode: 'visual', isSidebarOpened: true, panels: { 'post-status': true } } );
} );

it( 'should toggle the sidebar open flag', () => {
Expand Down Expand Up @@ -833,6 +815,15 @@ describe( 'state', () => {

expect( state ).toEqual( { isSidebarOpened: false, panels: { 'post-taxonomies': false } } );
} );

it( 'should return switched mode', () => {
const state = preferences( deepFreeze( { isSidebarOpened: false } ), {
type: 'SWITCH_MODE',
mode: 'text',
} );

expect( state ).toEqual( { isSidebarOpened: false, mode: 'text' } );
} );
} );

describe( 'saving()', () => {
Expand Down
Loading