/
use-post-history.js
81 lines (73 loc) · 2.19 KB
/
use-post-history.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* WordPress dependencies
*/
import { useCallback, useReducer, useMemo } from '@wordpress/element';
import { addQueryArgs, getQueryArgs, removeQueryArgs } from '@wordpress/url';
/**
* A hook that records the 'entity' history in the post editor as a user
* navigates between editing a post and editing the post template or patterns.
*
* Implemented as a stack, so a little similar to the browser history API.
*
* Used to control displaying UI elements like the back button.
*
* @param {number} initialPostId The post id of the post when the editor loaded.
* @param {string} initialPostType The post type of the post when the editor loaded.
*
* @return {Object} An object containing the `currentPost` variable and
* `getPostLinkProps` and `goBack` functions.
*/
export default function usePostHistory( initialPostId, initialPostType ) {
const [ postHistory, dispatch ] = useReducer(
( historyState, { type, post } ) => {
if ( type === 'push' ) {
return [ ...historyState, post ];
}
if ( type === 'pop' ) {
// Try to leave one item in the history.
if ( historyState.length > 1 ) {
return historyState.slice( 0, -1 );
}
}
return historyState;
},
[ { postId: initialPostId, postType: initialPostType } ]
);
const initialPost = useMemo( () => {
return {
type: initialPostType,
id: initialPostId,
};
}, [ initialPostType, initialPostId ] );
const getPostLinkProps = useCallback( ( params ) => {
const currentArgs = getQueryArgs( window.location.href );
const currentUrlWithoutArgs = removeQueryArgs(
window.location.href,
...Object.keys( currentArgs )
);
const newUrl = addQueryArgs( currentUrlWithoutArgs, {
post: params.postId,
action: 'edit',
} );
return {
href: newUrl,
onClick: ( event ) => {
event?.preventDefault();
dispatch( {
type: 'push',
post: { postId: params.postId, postType: params.postType },
} );
},
};
}, [] );
const goBack = useCallback( () => {
dispatch( { type: 'pop' } );
}, [] );
const currentPost = postHistory[ postHistory.length - 1 ];
return {
currentPost,
getPostLinkProps,
initialPost,
goBack: postHistory.length > 1 ? goBack : undefined,
};
}