PluginProbe
BeyondWords – AI audio for publishers / 7.0.0
BeyondWords – AI audio for publishers v7.0.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 / editor / components / content-id / index.js

index.js in BeyondWords – AI audio for publishers 7.0.0, at src/editor/components/content-id/index.js

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