From 659c64fc4f8820c2d58f050b2be09ef08e29fc40 Mon Sep 17 00:00:00 2001 From: Nicola Heald Date: Wed, 19 Jul 2017 10:53:13 +0100 Subject: [PATCH] Reducer for user specific data (#1920) --- editor/index.js | 4 +++ editor/selectors.js | 2 +- editor/state.js | 18 ++++++++-- editor/test/state.js | 83 +++++++++++++++++++++++++------------------- 4 files changed, 67 insertions(+), 40 deletions(-) diff --git a/editor/index.js b/editor/index.js index 9d75de3991580..5d90e39f72b2d 100644 --- a/editor/index.js +++ b/editor/index.js @@ -80,6 +80,10 @@ function preparePostState( store, post ) { export function createEditorInstance( id, post ) { const store = createReduxStore(); + store.dispatch( { + type: 'LOAD_USER_DATA', + } ); + preparePostState( store, post ); render( diff --git a/editor/selectors.js b/editor/selectors.js index 3d2116d311c1d..c12942bfa9628 100644 --- a/editor/selectors.js +++ b/editor/selectors.js @@ -676,5 +676,5 @@ export function getNotices( state ) { */ export function getRecentlyUsedBlocks( state ) { // resolves the block names in the state to the block type settings - return state.editor.recentlyUsedBlocks.map( blockType => getBlockType( blockType ) ); + return state.userData.recentlyUsedBlocks.map( blockType => getBlockType( blockType ) ); } diff --git a/editor/state.js b/editor/state.js index 9d77c9f58c9c6..50e29243b61d6 100644 --- a/editor/state.js +++ b/editor/state.js @@ -225,13 +225,24 @@ export const editor = combineUndoableReducers( { return state; }, +}, { resetTypes: [ 'RESET_BLOCKS' ] } ); +/** + * Reducer loading and saving user specific data, such as preferences and + * block usage. + * + * @param {Object} state Current state + * @param {Object} action Dispatched action + * @return {Object} Updated state + */ +export const userData = combineReducers( { recentlyUsedBlocks( state = [], action ) { const maxRecent = 8; switch ( action.type ) { - case 'SETUP_NEW_POST': + case 'LOAD_USER_DATA': // This is where we initially populate the recently used blocks, - // for now this inserts blocks from the common category. + // for now this inserts blocks from the common category, but will + // load this from an API in the future. return getBlockTypes() .filter( ( blockType ) => 'common' === blockType.category ) .slice( 0, maxRecent ) @@ -247,7 +258,7 @@ export const editor = combineUndoableReducers( { } return state; }, -}, { resetTypes: [ 'RESET_BLOCKS' ] } ); +} ); /** * Reducer returning the last-known state of the current post, in the format @@ -528,6 +539,7 @@ export function createReduxStore() { panel, saving, notices, + userData, } ) ); const enhancers = [ applyMiddleware( refx( effects ) ) ]; diff --git a/editor/test/state.js b/editor/test/state.js index 996b6f47157b6..a96548c41ba18 100644 --- a/editor/test/state.js +++ b/editor/test/state.js @@ -25,6 +25,7 @@ import { notices, showInsertionPoint, createReduxStore, + userData, } from '../state'; describe( 'state', () => { @@ -83,42 +84,6 @@ describe( 'state', () => { expect( state.blockOrder ).toEqual( [ 'chicken', 'ribs' ] ); } ); - it( 'should record recently used blocks', () => { - const original = editor( undefined, {} ); - const state = editor( original, { - type: 'INSERT_BLOCKS', - blocks: [ { - uid: 'bacon', - name: 'core-embed/twitter', - } ], - } ); - - expect( state.recentlyUsedBlocks[ 0 ] ).toEqual( 'core-embed/twitter' ); - - const twoRecentBlocks = editor( state, { - type: 'INSERT_BLOCKS', - blocks: [ { - uid: 'eggs', - name: 'core-embed/youtube', - } ], - } ); - - expect( twoRecentBlocks.recentlyUsedBlocks[ 0 ] ).toEqual( 'core-embed/youtube' ); - expect( twoRecentBlocks.recentlyUsedBlocks[ 1 ] ).toEqual( 'core-embed/twitter' ); - } ); - - it( 'should populate recently used blocks with the common category', () => { - const initial = editor( undefined, { - type: 'SETUP_NEW_POST', - edits: { - status: 'draft', - title: 'post title', - }, - } ); - - expect( initial.recentlyUsedBlocks ).toEqual( expect.arrayContaining( [ 'core/test-block', 'core/text' ] ) ); - } ); - it( 'should replace the block', () => { const original = editor( undefined, { type: 'RESET_BLOCKS', @@ -1052,4 +1017,50 @@ describe( 'state', () => { ] ) ); } ); } ); + + describe( 'userData()', () => { + beforeAll( () => { + registerBlockType( 'core/test-block', { + save: noop, + edit: noop, + category: 'common', + } ); + } ); + + afterAll( () => { + unregisterBlockType( 'core/test-block' ); + } ); + + it( 'should record recently used blocks', () => { + const original = userData( undefined, {} ); + const state = userData( original, { + type: 'INSERT_BLOCKS', + blocks: [ { + uid: 'bacon', + name: 'core-embed/twitter', + } ], + } ); + + expect( state.recentlyUsedBlocks[ 0 ] ).toEqual( 'core-embed/twitter' ); + + const twoRecentBlocks = userData( state, { + type: 'INSERT_BLOCKS', + blocks: [ { + uid: 'eggs', + name: 'core-embed/youtube', + } ], + } ); + + expect( twoRecentBlocks.recentlyUsedBlocks[ 0 ] ).toEqual( 'core-embed/youtube' ); + expect( twoRecentBlocks.recentlyUsedBlocks[ 1 ] ).toEqual( 'core-embed/twitter' ); + } ); + + it( 'should populate recently used blocks with the common category', () => { + const initial = userData( undefined, { + type: 'LOAD_USER_DATA', + } ); + + expect( initial.recentlyUsedBlocks ).toEqual( expect.arrayContaining( [ 'core/test-block', 'core/text' ] ) ); + } ); + } ); } );