PluginProbe
Parse.ly / 3.24.2
Parse.ly v3.24.2
3.24.3 3.24.2 3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 All 107 releases
wp-parsely / src / content-helper / editor-sidebar / smart-linking / hooks.ts

hooks.ts in Parse.ly 3.24.2, at src/content-helper/editor-sidebar/smart-linking/hooks.ts

144 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * WordPress dependencies
3 */
4 import { useRef, useState, useEffect } from '@wordpress/element';
5 import { dispatch, useSelect } from '@wordpress/data';
6 import { store as editorStore } from '@wordpress/editor';
7
8 /**
9 * Internal dependencies
10 */
11 import { GutenbergFunction } from '../../../@types/gutenberg/types';
12 import { SmartLinkingProvider } from './provider';
13 import { SmartLinkingStore as store } from './store';
14 import { validateAndFixSmartLinksInPost } from './utils';
15
16 /**
17 * Handles the smart links validation process, which will validate the smart links before saving the post.
18 *
19 * This hook is used to validate the smart links before saving the post. It will validate the smart links before
20 * saving the post, and then save the post after the smart links have been validated. This is necessary because
21 * the validation process may change the post content, and those changes are not reflected in the post saving process.
22 *
23 * This is a fallback for the validation step in the LinkMonitor component. If for some reason the validation step
24 * is not triggered, this hook will fix the smart links before saving the post.
25 *
26 * @since 3.16.0
27 *
28 * @param {Function} setValidationComplete The function to set the validation completion state.
29 *
30 * @return {boolean} Whether the post is saved.
31 */
32 export const useSmartLinksValidation = ( setValidationComplete: ( value: boolean ) => void ): boolean => {
33 const [ isPostSaved, setIsPostSaved ] = useState( false );
34 const [ didAnyFixes, setDidAnyFixes ] = useState( false );
35 const isPostSavingInProgress = useRef( false );
36 const hasValidatedLinks = useRef( false );
37
38 const { isSavingPost, isAutosavingPost } = useSelect( ( selectFn ) => {
39 const coreEditorSelect = selectFn( 'core/editor' ) as GutenbergFunction;
40 return {
41 isSavingPost: coreEditorSelect.isSavingPost(),
42 isAutosavingPost: coreEditorSelect.isAutosavingPost(),
43 };
44 }, [] );
45
46 /**
47 * Handles the before save action, which will validate the smart links before saving the post.
48 *
49 * @since 3.16.0
50 */
51 useEffect( () => {
52 if ( isSavingPost && ! hasValidatedLinks.current ) {
53 ( async () => {
54 const validationFixed = await validateAndFixSmartLinksInPost();
55 setDidAnyFixes( validationFixed );
56 hasValidatedLinks.current = true;
57 setValidationComplete( true );
58 } )();
59 } else {
60 hasValidatedLinks.current = false;
61 setValidationComplete( false );
62 }
63 }, [ isSavingPost, setValidationComplete ] );
64
65 /**
66 * Handles the post saving state tracking.
67 *
68 * @since 3.16.0
69 */
70 useEffect( () => {
71 if ( ( isSavingPost || isAutosavingPost ) && ! isPostSavingInProgress.current ) {
72 setIsPostSaved( false );
73 isPostSavingInProgress.current = true;
74 } else if ( ! ( isSavingPost || isAutosavingPost ) && isPostSavingInProgress.current ) {
75 setIsPostSaved( true );
76 isPostSavingInProgress.current = false;
77 }
78 }, [ isSavingPost, isAutosavingPost ] );
79
80 /**
81 * Handles the post saving action, which will save the post after the smart links have been validated.
82 * This is necessary because the validation process may change the post content, and those changes are not
83 * reflected in the post saving process.
84 *
85 * @since 3.16.0
86 */
87 useEffect( () => {
88 if ( isPostSaved && hasValidatedLinks.current && didAnyFixes ) {
89 ( async () => {
90 await dispatch( editorStore ).savePost();
91 hasValidatedLinks.current = false;
92 } )();
93 }
94 }, [ didAnyFixes, isPostSaved ] );
95
96 return isPostSaved;
97 };
98
99 /**
100 * Handles the smart links saving process, which will save the smart links after the post has been saved.
101 *
102 * This hook is used to save the smart links after the post has been saved. It will save the smart links to
103 * the database, using the SmartLinkingProvider, after the post has been saved.
104 *
105 * This hook will not save the smart links if the post is being autosaved.
106 *
107 * @since 3.16.0
108 *
109 * @param {boolean} validationCompleted Whether the validation process has been completed.
110 */
111 export const useSaveSmartLinksOnPostSave = (
112 validationCompleted: boolean,
113 ): void => {
114 const { isSavingPost, isAutosavingPost } = useSelect( ( selectFn ) => {
115 const coreEditorSelect = selectFn( 'core/editor' ) as GutenbergFunction;
116 return {
117 isSavingPost: coreEditorSelect.isSavingPost(),
118 isAutosavingPost: coreEditorSelect.isAutosavingPost(),
119 };
120 }, [] );
121
122 const { postId } = useSelect( ( selectFn ) => {
123 const { getCurrentPostId } = selectFn( 'core/editor' ) as GutenbergFunction;
124 return {
125 postId: getCurrentPostId(),
126 };
127 }, [] );
128
129 const { getSmartLinks } = useSelect( ( selectFn ) => {
130 return {
131 getSmartLinks: selectFn( store ).getSmartLinks,
132 };
133 }, [] );
134
135 useEffect( () => {
136 if ( isSavingPost && ! isAutosavingPost && postId && validationCompleted ) {
137 SmartLinkingProvider.getInstance().setSmartLinks( postId, getSmartLinks() ).catch( () => {
138 // eslint-disable-next-line no-console
139 console.error( 'WP Parse.ly: Failed to save Smart Links on post save.' );
140 } );
141 }
142 }, [ getSmartLinks, isAutosavingPost, isSavingPost, postId, validationCompleted ] );
143 };
144