PluginProbe
BeyondWords – AI audio for publishers / 6.3.0
BeyondWords – AI audio for publishers v6.3.0
7.1.0 trunk 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.3.0 4.4.0 4.5.0 4.5.1 4.6.0 4.6.1 4.6.2 4.7.0 All 43 releases
speechkit / src / Component / Post / ContentId / index.js

index.js in BeyondWords – AI audio for publishers 6.3.0, at src/Component/Post/ContentId/index.js

192 lines 4.6 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 { __ } from '@wordpress/i18n';
5 import {
6 Button,
7 Flex,
8 FlexItem,
9 TextControl,
10 Spinner,
11 } from '@wordpress/components';
12 import { useSelect, useDispatch, select } from '@wordpress/data';
13 import { Fragment, useState, useEffect } from '@wordpress/element';
14 import apiFetch from '@wordpress/api-fetch';
15
16 // Internal utilities
17 const updatePostMeta = ( postId, meta ) => {
18 const postType = select( 'core/editor' ).getCurrentPostType();
19 const postTypeInfo = select( 'core' ).getPostType( postType );
20 const restBase = postTypeInfo?.rest_base || postType;
21
22 return apiFetch( {
23 path: `/wp/v2/${ restBase }/${ postId }`,
24 method: 'POST',
25 data: { meta },
26 } );
27 };
28 export function ContentId( { wrapper } ) {
29 const Wrapper = wrapper || Fragment;
30
31 const { editPost } = useDispatch( 'core/editor' );
32
33 const postId = useSelect(
34 () => select( 'core/editor' ).getCurrentPostId(),
35 []
36 );
37
38 const savedContentId = useSelect(
39 () =>
40 select( 'core/editor' ).getEditedPostAttribute( 'meta' )
41 ?.beyondwords_content_id || '',
42 []
43 );
44
45 const settingsProjectId = useSelect( () => {
46 const metaProjectId =
47 select( 'core/editor' ).getEditedPostAttribute(
48 'meta'
49 )?.beyondwords_project_id;
50 const settings = select( 'beyondwords/settings' ).getSettings() || {};
51
52 return metaProjectId || settings.projectId;
53 }, [] );
54
55 const restUrl = useSelect(
56 () => select( 'beyondwords/settings' ).getSettings()?.restUrl,
57 []
58 );
59
60 const [ contentId, setContentId ] = useState( savedContentId );
61 const [ isLoading, setIsLoading ] = useState( false );
62
63 // Keep local state in sync when savedContentId changes externally.
64 useEffect( () => {
65 setContentId( savedContentId );
66 }, [ savedContentId ] );
67
68 const handleFetch = async () => {
69 if ( ! contentId || ! settingsProjectId ) {
70 return;
71 }
72
73 setIsLoading( true );
74
75 try {
76 const response = await fetch(
77 `${ restUrl }beyondwords/v1/projects/${ encodeURIComponent(
78 settingsProjectId
79 ) }/content/${ encodeURIComponent( contentId ) }`,
80 {
81 credentials: 'same-origin',
82 headers: {
83 'X-WP-Nonce': window.wpApiSettings?.nonce,
84 },
85 }
86 );
87
88 if ( ! response.ok ) {
89 /* eslint-disable camelcase */
90 const errorMeta = {
91 beyondwords_content_id: contentId,
92 beyondwords_error_message: __(
93 'Failed to fetch content. Please check the Content ID.',
94 'speechkit'
95 ),
96 };
97 /* eslint-enable camelcase */
98
99 await updatePostMeta( postId, errorMeta );
100 editPost( { meta: errorMeta } );
101 return;
102 }
103
104 const data = await response.json();
105
106 /* eslint-disable camelcase */
107 const {
108 body_voice_id,
109 id,
110 language,
111 preview_token,
112 title_voice_id,
113 summary_voice_id,
114 project_id,
115 } = data;
116
117 const meta = {
118 beyondwords_generate_audio: '0',
119 beyondwords_project_id: String( project_id || '' ),
120 beyondwords_content_id: id || '',
121 beyondwords_preview_token: preview_token || '',
122 beyondwords_language_code: language || '',
123 beyondwords_title_voice_id: String( title_voice_id || '' ),
124 beyondwords_summary_voice_id: String( summary_voice_id || '' ),
125 beyondwords_body_voice_id: String( body_voice_id || '' ),
126 beyondwords_delete_content: '',
127 beyondwords_disabled: '',
128 beyondwords_error_message: '',
129 };
130 /* eslint-enable camelcase */
131
132 await updatePostMeta( postId, meta );
133 editPost( { meta } );
134
135 // Update local state with the returned content ID.
136 setContentId( id || '' );
137 } catch ( err ) {
138 /* eslint-disable camelcase */
139 const errorMeta = {
140 beyondwords_content_id: contentId,
141 beyondwords_error_message: __(
142 'Failed to fetch content. Please check the Content ID.',
143 'speechkit'
144 ),
145 };
146 /* eslint-enable camelcase */
147
148 try {
149 await updatePostMeta( postId, errorMeta );
150 } catch {
151 // Persist failed — still update local editor state below.
152 }
153 editPost( { meta: errorMeta } );
154 } finally {
155 setIsLoading( false );
156 }
157 };
158
159 return (
160 <Wrapper>
161 <Flex align="flex-end" gap={ 2 }>
162 <FlexItem isBlock>
163 <TextControl
164 label={ __( 'Content ID', 'speechkit' ) }
165 value={ contentId }
166 onChange={ setContentId }
167 disabled={ isLoading }
168 __nextHasNoMarginBottom
169 __next40pxDefaultSize
170 />
171 </FlexItem>
172 <FlexItem>
173 <Button
174 variant="secondary"
175 onClick={ handleFetch }
176 disabled={ isLoading || ! contentId }
177 __next40pxDefaultSize
178 >
179 { isLoading ? (
180 <Spinner style={ { margin: 0 } } />
181 ) : (
182 __( 'Fetch', 'speechkit' )
183 ) }
184 </Button>
185 </FlexItem>
186 </Flex>
187 </Wrapper>
188 );
189 }
190
191 export default ContentId;
192