-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Mobile] - Drag & drop blocks - Fetch and share blocks layout size an…
…d position coordinates (#39089) * Mobile - Block list - Extract block list context into a separate file and add support to store the blocks layouts data and coordinates. * Mobile - Block list - Adds block list item cell to get the onLayout data and use updateBlocksLayouts to store it. It is needed to use CellRendererComponent to be able to get the right position coordinates * Mobile - Block list - Store block layouts data for inner blocks in a deep level * Mobile - BlockList ItemCell - Destructuring props * Mobile - BlockListContext - Rename findByRootId to findBlockLayoutByClientId * Mobile - BlockListContext - Rename deleteByClientId to deleteBlockLayoutByClientId * Mobile - BlockListContext - Store default context and use it for initialization * Mobile - BlockListContext - Add param's docs * Mobile - Block list context - Export findBlockLayoutByClientId * Mobile - Block list context - Update comments * Mobile - Block list context - Unit tests * Mobile - Block list context - update unit tests
- Loading branch information
Gerardo Pacheco
authored
Mar 17, 2022
1 parent
7d39bec
commit a51e773
Showing
5 changed files
with
537 additions
and
8 deletions.
There are no files selected for viewing
131 changes: 131 additions & 0 deletions
131
packages/block-editor/src/components/block-list/block-list-context.native.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { createContext, useContext } from '@wordpress/element'; | ||
|
||
export const DEFAULT_BLOCK_LIST_CONTEXT = { | ||
scrollRef: null, | ||
blocksLayouts: { current: {} }, | ||
findBlockLayoutByClientId, | ||
updateBlocksLayouts, | ||
}; | ||
|
||
const Context = createContext( DEFAULT_BLOCK_LIST_CONTEXT ); | ||
const { Provider, Consumer } = Context; | ||
|
||
/** | ||
* Finds a block's layout data by its client Id. | ||
* | ||
* @param {Object} data Blocks layouts object. | ||
* @param {string} clientId Block's clientId. | ||
* | ||
* @return {Object} Found block layout data. | ||
*/ | ||
function findBlockLayoutByClientId( data, clientId ) { | ||
return Object.entries( data ).reduce( ( acc, entry ) => { | ||
const item = entry[ 1 ]; | ||
if ( acc ) { | ||
return acc; | ||
} | ||
if ( item?.clientId === clientId ) { | ||
return item; | ||
} | ||
if ( item?.innerBlocks && Object.keys( item.innerBlocks ).length > 0 ) { | ||
return findBlockLayoutByClientId( item.innerBlocks, clientId ); | ||
} | ||
return null; | ||
}, null ); | ||
} | ||
|
||
/** | ||
* Deletes the layout data of a block by its client Id. | ||
* | ||
* @param {Object} data Blocks layouts object. | ||
* @param {string} clientId Block's clientsId. | ||
* | ||
* @return {Object} Updated data object. | ||
*/ | ||
export function deleteBlockLayoutByClientId( data, clientId ) { | ||
return Object.keys( data ).reduce( ( acc, key ) => { | ||
if ( key !== clientId ) { | ||
acc[ key ] = data[ key ]; | ||
} | ||
if ( | ||
data[ key ]?.innerBlocks && | ||
Object.keys( data[ key ].innerBlocks ).length > 0 | ||
) { | ||
if ( acc[ key ] ) { | ||
acc[ key ].innerBlocks = deleteBlockLayoutByClientId( | ||
data[ key ].innerBlocks, | ||
clientId | ||
); | ||
} | ||
} | ||
return acc; | ||
}, {} ); | ||
} | ||
|
||
/** | ||
* Updates or deletes a block's layout data in the blocksLayouts object, | ||
* in case of deletion, the layout data is not required. | ||
* | ||
* @param {Object} blocksLayouts Blocks layouts object. | ||
* @param {Object} blockData Block's layout data to add or remove to/from the blockLayouts object. | ||
* @param {string} blockData.clientId Block's clientId. | ||
* @param {?string} blockData.rootClientId Optional. Block's rootClientId. | ||
* @param {?boolean} blockData.shouldRemove Optional. Flag to remove it from the blocksLayout list. | ||
* @param {number} blockData.width Block's width. | ||
* @param {number} blockData.height Block's height. | ||
* @param {number} blockData.x Block's x coordinate (relative to the parent). | ||
* @param {number} blockData.y Block's y coordinate (relative to the parent). | ||
*/ | ||
|
||
function updateBlocksLayouts( blocksLayouts, blockData ) { | ||
const { clientId, rootClientId, shouldRemove, ...layoutProps } = blockData; | ||
|
||
if ( clientId && shouldRemove ) { | ||
blocksLayouts.current = deleteBlockLayoutByClientId( | ||
blocksLayouts.current, | ||
clientId | ||
); | ||
return; | ||
} | ||
|
||
if ( clientId && ! rootClientId ) { | ||
blocksLayouts.current[ clientId ] = { | ||
clientId, | ||
rootClientId, | ||
...layoutProps, | ||
innerBlocks: { | ||
...blocksLayouts.current[ clientId ]?.innerBlocks, | ||
}, | ||
}; | ||
} else if ( clientId && rootClientId ) { | ||
const block = findBlockLayoutByClientId( | ||
blocksLayouts.current, | ||
rootClientId | ||
); | ||
|
||
if ( block ) { | ||
block.innerBlocks[ clientId ] = { | ||
clientId, | ||
rootClientId, | ||
...layoutProps, | ||
innerBlocks: { | ||
...block.innerBlocks[ clientId ]?.innerBlocks, | ||
}, | ||
}; | ||
} | ||
} | ||
} | ||
|
||
export { Provider as BlockListProvider, Consumer as BlockListConsumer }; | ||
|
||
/** | ||
* Hook that returns the block list context. | ||
* | ||
* @return {Object} Block list context | ||
*/ | ||
export const useBlockListContext = () => { | ||
return useContext( Context ); | ||
}; |
42 changes: 42 additions & 0 deletions
42
packages/block-editor/src/components/block-list/block-list-item-cell.native.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { View } from 'react-native'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useEffect, useCallback } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { useBlockListContext } from './block-list-context'; | ||
|
||
function BlockListItemCell( { children, clientId, rootClientId } ) { | ||
const { blocksLayouts, updateBlocksLayouts } = useBlockListContext(); | ||
|
||
useEffect( () => { | ||
return () => { | ||
updateBlocksLayouts( blocksLayouts, { | ||
clientId, | ||
shouldRemove: true, | ||
} ); | ||
}; | ||
}, [] ); | ||
|
||
const onLayout = useCallback( | ||
( { nativeEvent: { layout } } ) => { | ||
updateBlocksLayouts( blocksLayouts, { | ||
clientId, | ||
rootClientId, | ||
...layout, | ||
} ); | ||
}, | ||
[ clientId, rootClientId, updateBlocksLayouts ] | ||
); | ||
|
||
return <View onLayout={ onLayout }>{ children }</View>; | ||
} | ||
|
||
export default BlockListItemCell; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.