Skip to content

Commit 33e14a9

Browse files
committed
various fixes
1 parent 9fb538c commit 33e14a9

File tree

7 files changed

+458
-139
lines changed

7 files changed

+458
-139
lines changed

includes/gutenberg/feedzy-rss-feeds-loop-block.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,17 @@ public function render_callback( $attributes, $content ) {
182182
*/
183183
public function apply_magic_tags( $content, $item ) {
184184
$pattern = '/\{\{feedzy_([^}]+)\}\}/';
185-
$content = str_replace( FEEDZY_ABSURL . 'img/feedzy.svg', '{{feedzy_image}}', $content );
185+
$content = str_replace(
186+
array(
187+
FEEDZY_ABSURL . 'img/feedzy.svg',
188+
'http://{{feedzy_url}}'
189+
),
190+
array(
191+
'{{feedzy_image}}',
192+
'{{feedzy_url}}'
193+
),
194+
$content
195+
);
186196

187197
return preg_replace_callback( $pattern, function( $matches ) use ( $item ) {
188198
return isset( $matches[1] ) ? $this->get_value( $matches[1], $item ) : '';
@@ -210,8 +220,11 @@ public function get_value( $key, $item ) {
210220
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'time_format' ), $item['item_date'] ) : '';
211221
return $item_date;
212222
case 'datetime':
213-
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $item['item_date'] ) : '';
214-
return $item_date;
223+
$item_date = isset( $item['item_date'] ) ? wp_date( get_option( 'date_format' ), $item['item_date'] ) : '';
224+
$item_time = isset( $item['item_date'] ) ? wp_date( get_option( 'time_format' ), $item['item_date'] ) : '';
225+
/* translators: 1: date, 2: time */
226+
$datetime = sprintf( __( '%1$s at %2$s', 'feedzy-rss-feeds' ), $item_date, $item_time );
227+
return $datetime;
215228
case 'author':
216229
if ( isset( $item['item_author'] ) && is_string( $item['item_author'] ) ) {
217230
return $item['item_author'];
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/**
2+
* WordPress dependencies.
3+
*/
4+
import { useState, useEffect, useRef } from '@wordpress/element';
5+
6+
const FeedControl = ({ value, options, onChange }) => {
7+
const [isOpen, setIsOpen] = useState(false);
8+
const [inputValue, setInputValue] = useState('');
9+
const [selectedOption, setSelectedOption] = useState(null);
10+
const dropdownRef = useRef(null);
11+
12+
// Initialize component state based on value prop
13+
useEffect(() => {
14+
if (value?.type === 'group' && value.source) {
15+
const selected = options.find((opt) => opt.value === value.source);
16+
setSelectedOption(selected || null);
17+
setInputValue('');
18+
} else if (value?.type === 'url' && Array.isArray(value.source)) {
19+
setSelectedOption(null);
20+
setInputValue(value.source.join(', '));
21+
}
22+
}, [value, options]);
23+
24+
useEffect(() => {
25+
const handleClickOutside = (event) => {
26+
if (
27+
dropdownRef.current &&
28+
!dropdownRef.current.contains(event.target)
29+
) {
30+
setIsOpen(false);
31+
}
32+
};
33+
34+
document.addEventListener('mousedown', handleClickOutside);
35+
return () =>
36+
document.removeEventListener('mousedown', handleClickOutside);
37+
}, []);
38+
39+
const handleSelectOption = (option) => {
40+
setSelectedOption(option);
41+
setInputValue('');
42+
setIsOpen(false);
43+
onChange({
44+
type: 'group',
45+
source: option.value,
46+
});
47+
};
48+
49+
const handleInputChange = (e) => {
50+
const current = e.target.value;
51+
setInputValue(current);
52+
setSelectedOption(null);
53+
};
54+
55+
const handleInputBlur = () => {
56+
onChange({
57+
type: 'url',
58+
source: inputValue
59+
? inputValue
60+
.split(',')
61+
.map((url) => url.trim())
62+
.filter(Boolean)
63+
: [],
64+
});
65+
};
66+
67+
const handleClear = () => {
68+
setSelectedOption(null);
69+
setInputValue('');
70+
onChange({
71+
type: 'url',
72+
source: [],
73+
});
74+
};
75+
76+
return (
77+
<div className="fz-url-category-input" ref={dropdownRef}>
78+
<input
79+
type="text"
80+
value={selectedOption ? selectedOption.label : inputValue}
81+
onChange={handleInputChange}
82+
onBlur={handleInputBlur}
83+
placeholder="Enter URLs or select a category"
84+
disabled={selectedOption !== null}
85+
className="fz-input-field"
86+
/>
87+
<div className="fz-buttons-container">
88+
{selectedOption && (
89+
<button
90+
onClick={handleClear}
91+
className="fz-clear-button"
92+
title="Clear selection"
93+
>
94+
<svg
95+
width="14"
96+
height="14"
97+
viewBox="0 0 24 24"
98+
fill="none"
99+
xmlns="http://www.w3.org/2000/svg"
100+
>
101+
<path
102+
d="M18 6L6 18M6 6l12 12"
103+
stroke="currentColor"
104+
strokeWidth="2"
105+
strokeLinecap="round"
106+
strokeLinejoin="round"
107+
/>
108+
</svg>
109+
</button>
110+
)}
111+
<button
112+
onClick={() => setIsOpen(!isOpen)}
113+
className="fz-dropdown-button"
114+
>
115+
<svg
116+
width="12"
117+
height="12"
118+
viewBox="0 0 12 12"
119+
fill="none"
120+
xmlns="http://www.w3.org/2000/svg"
121+
style={{
122+
transform: isOpen
123+
? 'rotate(180deg)'
124+
: 'rotate(0deg)',
125+
transition: 'transform 0.2s',
126+
}}
127+
>
128+
<path
129+
d="M2 4L6 8L10 4"
130+
stroke="currentColor"
131+
strokeWidth="2"
132+
strokeLinecap="round"
133+
strokeLinejoin="round"
134+
/>
135+
</svg>
136+
</button>
137+
</div>
138+
139+
{isOpen && (
140+
<div className="fz-dropdown-menu">
141+
{options.map((option) => (
142+
<button
143+
key={option.value}
144+
onClick={() => handleSelectOption(option)}
145+
className={`fz-dropdown-item ${selectedOption?.value === option.value ? 'fz-selected' : ''}`}
146+
>
147+
{option.label}
148+
</button>
149+
))}
150+
</div>
151+
)}
152+
</div>
153+
);
154+
};
155+
156+
export default FeedControl;

js/FeedzyLoop/controls.js

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,37 @@ const Controls = ({
170170
]}
171171
initialOpen={false}
172172
key="filters"
173-
className={
174-
window.feedzyData.isPro
175-
? 'feedzy-item-filter'
176-
: 'feedzy-item-filter fz-locked'
177-
}
173+
className="feedzy-item-filter"
178174
>
175+
{!window.feedzyData.isPro && (
176+
<div className="fz-upsell-notice">
177+
{__(
178+
'Unlock this feature and more advanced options with',
179+
'feedzy-rss-feeds'
180+
)}{' '}
181+
<ExternalLink href="https://themeisle.com/plugins/feedzy-rss-feeds/upgrade/?utm_source=wpadmin&utm_medium=blockeditor&utm_campaign=keywordsfilter&utm_content=feedzy-rss-feeds">
182+
{__('Feedzy Pro', 'feedzy-rss-feeds')}
183+
</ExternalLink>
184+
</div>
185+
)}
186+
179187
<ConditionsControl
180188
conditions={
181-
attributes?.conditions || {
182-
conditions: [],
183-
match: 'all',
184-
}
189+
window.feedzyData.isPro
190+
? attributes?.conditions || {
191+
conditions: [],
192+
match: 'all',
193+
}
194+
: {
195+
match: 'all',
196+
conditions: [
197+
{
198+
field: 'title',
199+
operator: 'contains',
200+
value: 'Sports',
201+
},
202+
],
203+
}
185204
}
186205
setConditions={(conditions) => {
187206
setAttributes({ conditions });

js/FeedzyLoop/edit.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import {
1515
InnerBlocks,
1616
} from '@wordpress/block-editor';
1717

18+
import {
19+
Placeholder as BlockEditorPlaceholder,
20+
Spinner,
21+
} from '@wordpress/components';
22+
1823
import { useDispatch, useSelect } from '@wordpress/data';
1924

2025
import { useState } from '@wordpress/element';
@@ -30,13 +35,20 @@ import Controls from './controls';
3035

3136
const { name } = metadata;
3237

38+
const LoadingResponsePlaceholder = () => (
39+
<BlockEditorPlaceholder>
40+
<Spinner />
41+
</BlockEditorPlaceholder>
42+
);
43+
3344
const Edit = ({ attributes, setAttributes, clientId }) => {
3445
const blockProps = useBlockProps();
3546

3647
const [isEditing, setIsEditing] = useState(!attributes?.feed?.source);
3748
const [isPreviewing, setIsPreviewing] = useState(false);
3849

39-
const { replaceInnerBlocks, selectBlock } = useDispatch(blockEditorStore);
50+
const { clearSelectedBlock, replaceInnerBlocks, selectBlock } =
51+
useDispatch(blockEditorStore);
4052

4153
const isSelected = useSelect(
4254
(select) => {
@@ -130,6 +142,7 @@ const Edit = ({ attributes, setAttributes, clientId }) => {
130142
...attributes,
131143
innerBlocksContent,
132144
}}
145+
LoadingResponsePlaceholder={LoadingResponsePlaceholder}
133146
/>
134147
</div>
135148
</>
@@ -165,8 +178,8 @@ const Edit = ({ attributes, setAttributes, clientId }) => {
165178
),
166179
true
167180
);
181+
clearSelectedBlock();
168182
}
169-
selectBlock(clientId);
170183
}}
171184
/>
172185
)}

0 commit comments

Comments
 (0)