3
3
* WordPress dependencies.
4
4
*/
5
5
import { __ } from '@wordpress/i18n' ;
6
-
6
+ import { useState } from '@wordpress/element' ;
7
7
import {
8
8
BaseControl ,
9
9
Button ,
10
10
Placeholder ,
11
11
Spinner ,
12
+ Notice ,
12
13
} from '@wordpress/components' ;
13
-
14
14
import { useSelect } from '@wordpress/data' ;
15
-
16
15
import { store as coreStore } from '@wordpress/core-data' ;
17
16
18
17
/**
@@ -21,6 +20,9 @@ import { store as coreStore } from '@wordpress/core-data';
21
20
import FeedControl from './components/FeedControl' ;
22
21
23
22
const BlockPlaceholder = ( { attributes, setAttributes, onSaveFeed } ) => {
23
+ const [ isValidating , setIsValidating ] = useState ( false ) ;
24
+ const [ validationResults , setValidationResults ] = useState ( [ ] ) ;
25
+
24
26
const { categories, isLoading } = useSelect ( ( select ) => {
25
27
const { getEntityRecords, isResolving } = select ( coreStore ) ;
26
28
@@ -33,20 +35,132 @@ const BlockPlaceholder = ({ attributes, setAttributes, onSaveFeed }) => {
33
35
} ;
34
36
} , [ ] ) ;
35
37
38
+ const handleLoadFeed = async ( ) => {
39
+ if ( ! attributes ?. feed ?. source ) {
40
+ return ;
41
+ }
42
+
43
+ setIsValidating ( true ) ;
44
+ setValidationResults ( [ ] ) ;
45
+
46
+ const isCategory = categories . some (
47
+ ( cat ) => cat . id === attributes . feed . source
48
+ ) ;
49
+
50
+ if ( isCategory && 'group' === attributes . feed . type ) {
51
+ onSaveFeed ( ) ;
52
+ setIsValidating ( false ) ;
53
+ return ;
54
+ }
55
+
56
+ try {
57
+ const formData = new FormData ( ) ;
58
+ formData . append ( 'action' , 'feedzy_validate_feed' ) ;
59
+ formData . append ( 'feed_url' , attributes . feed . source ) ;
60
+ formData . append ( 'nonce' , window . feedzyData ?. nonce ) ;
61
+
62
+ const response = await fetch ( window . feedzyData ?. url , {
63
+ method : 'POST' ,
64
+ body : formData ,
65
+ } ) ;
66
+
67
+ const data = await response . json ( ) ;
68
+
69
+ if ( data . success && data . data ?. results ) {
70
+ const results = data . data . results ;
71
+ setValidationResults ( results ) ;
72
+
73
+ const hasErrors = results . some (
74
+ ( result ) => result . status === 'error'
75
+ ) ;
76
+
77
+ if ( ! hasErrors ) {
78
+ onSaveFeed ( ) ;
79
+ }
80
+ } else if ( ! data . success ) {
81
+ setValidationResults ( [
82
+ {
83
+ status : 'error' ,
84
+ message :
85
+ data . data ?. message ||
86
+ __ ( 'Validation failed' , 'feedzy-rss-feeds' ) ,
87
+ } ,
88
+ ] ) ;
89
+ }
90
+ } catch ( error ) {
91
+ setValidationResults ( [
92
+ {
93
+ status : 'error' ,
94
+ message : __ (
95
+ 'Failed to validate feed. Please check your connection and try again.' ,
96
+ 'feedzy-rss-feeds'
97
+ ) ,
98
+ } ,
99
+ ] ) ;
100
+ } finally {
101
+ setIsValidating ( false ) ;
102
+ }
103
+ } ;
104
+
105
+ const handleFeedChange = ( value ) => {
106
+ setAttributes ( { feed : value } ) ;
107
+ setValidationResults ( [ ] ) ;
108
+ } ;
109
+
110
+ const renderValidationResults = ( ) => {
111
+ if ( ! validationResults || validationResults . length === 0 ) {
112
+ return null ;
113
+ }
114
+
115
+ return (
116
+ < div
117
+ className = "feedzy-validation-results"
118
+ style = { {
119
+ display : 'flex' ,
120
+ flexDirection : 'column' ,
121
+ gap : '10px' ,
122
+ marginTop : '15px' ,
123
+ } }
124
+ >
125
+ { validationResults . map ( ( result , index ) => (
126
+ < Notice
127
+ key = { `result-${ index } ` }
128
+ status = { result . status }
129
+ isDismissible = { false }
130
+ >
131
+ { result . url && (
132
+ < >
133
+ < strong > { result . url } </ strong >
134
+ < br />
135
+ </ >
136
+ ) }
137
+ { result . message }
138
+ </ Notice >
139
+ ) ) }
140
+ </ div >
141
+ ) ;
142
+ } ;
143
+
36
144
return (
37
145
< Placeholder
38
146
key = "placeholder"
39
147
icon = "rss"
40
148
label = { __ ( 'Feedzy RSS Feeds' , 'feedzy-rss-feeds' ) }
41
149
>
42
- { isLoading && (
150
+ { ( isLoading || isValidating ) && (
43
151
< div key = "loading" className = "wp-block-embed is-loading" >
44
152
< Spinner />
45
- < p > { __ ( 'Fetching…' , 'feedzy-rss-feeds' ) } </ p >
153
+ < p >
154
+ { isValidating
155
+ ? __ (
156
+ 'Validating and fetching feed…' ,
157
+ 'feedzy-rss-feeds' )
158
+ : __ ( 'Loading…' , 'feedzy-rss-feeds' ) }
159
+ </ p >
46
160
</ div >
47
161
) }
48
162
49
- { ! isLoading && (
163
+ { ! isLoading && ! isValidating && (
50
164
< >
51
165
< BaseControl
52
166
label = { __ ( 'Feed Source' , 'feedzy-rss-feeds' ) }
@@ -60,9 +174,11 @@ const BlockPlaceholder = ({ attributes, setAttributes, onSaveFeed }) => {
60
174
value : category . id ,
61
175
} ) ) ,
62
176
] }
63
- onChange = { ( value ) => setAttributes ( { feed : value } ) }
177
+ onChange = { handleFeedChange }
64
178
/>
65
179
180
+ { renderValidationResults ( ) }
181
+
66
182
< p >
67
183
{ __ (
68
184
'Enter the full URL of the feed source you wish to display here, or select a Feed Group. Also you can add multiple URLs separated with a comma. You can manage your feed groups from' ,
@@ -81,22 +197,11 @@ const BlockPlaceholder = ({ attributes, setAttributes, onSaveFeed }) => {
81
197
< div >
82
198
< Button
83
199
variant = "primary"
84
- onClick = { ( ) => {
85
- if ( attributes ?. feed ?. source ) {
86
- onSaveFeed ( ) ;
87
- }
88
- } }
200
+ onClick = { handleLoadFeed }
201
+ disabled = { ! attributes ?. feed ?. source }
89
202
>
90
203
{ __ ( 'Load Feed' , 'feedzy-rss-feeds' ) }
91
204
</ Button >
92
-
93
- < Button
94
- variant = "link"
95
- href = "https://validator.w3.org/feed/"
96
- target = "_blank"
97
- >
98
- { __ ( 'Validate' , 'feedzy-rss-feeds' ) }
99
- </ Button >
100
205
</ div >
101
206
</ >
102
207
) }
0 commit comments