PluginProbe
Extendify / 3.2.0
Extendify v3.2.0
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Agent / workflows / abilities / components / run / imagify / OptimizeMedia.jsx

OptimizeMedia.jsx in Extendify 3.2.0, at src/Agent/workflows/abilities/components/run/imagify/OptimizeMedia.jsx

133 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import executeAbility from '@agent/workflows/abilities/tools/execute-ability';
2 import { useEffect, useState } from '@wordpress/element';
3 import { __, _n, sprintf } from '@wordpress/i18n';
4
5 const ABILITY = 'imagify/optimize-media';
6
7 // Imagify translates its own guard messages only where it has language packs.
8 const blockedMessage = (status) => {
9 if (status === 'invalid_api_key')
10 return __(
11 'Your Imagify API key is missing or invalid. Add a valid key in the Imagify settings.',
12 'extendify-local',
13 );
14 if (status === 'insufficient_quota')
15 return __(
16 'Your Imagify quota is used up. Wait for the next reset or upgrade your plan.',
17 'extendify-local',
18 );
19 return null;
20 };
21
22 const usePreview = (inputs, enabled) => {
23 const [preview, setPreview] = useState(null);
24
25 useEffect(() => {
26 if (!enabled) return;
27 let live = true;
28 // Imagify runs nothing without confirm: true, so this only reports the cost.
29 executeAbility({ ability: ABILITY, input: { ...inputs, confirm: false } })
30 .then((result) => {
31 if (live) setPreview(result ?? {});
32 })
33 // Imagify still gates the run, so a failed cost check need not block it.
34 .catch(() => {
35 if (live) setPreview({});
36 });
37 return () => {
38 live = false;
39 };
40 }, [inputs, enabled]);
41
42 return preview;
43 };
44
45 const Line = ({ children }) => (
46 <p className="m-0 p-0 text-sm text-gray-900">{children}</p>
47 );
48
49 const Cost = ({ preview }) => {
50 const count = preview?.impact?.count ?? 1;
51 const quota = preview?.quota_remaining;
52
53 return (
54 <>
55 <Line>
56 {sprintf(
57 // translators: %d is how many Imagify credits optimizing this image will use.
58 _n(
59 'Optimizing this image uses %d Imagify credit.',
60 'Optimizing this image uses %d Imagify credits.',
61 count,
62 'extendify-local',
63 ),
64 count,
65 )}
66 </Line>
67 {quota == null ? null : (
68 <p className="m-0 mt-1 p-0 text-sm text-gray-700">
69 {sprintf(
70 // translators: %s is the percentage of the user's Imagify quota that is still unused, e.g. "88%".
71 __('%s of your quota remains.', 'extendify-local'),
72 `${Math.round(quota)}%`,
73 )}
74 </p>
75 )}
76 </>
77 );
78 };
79
80 const Body = ({ gate, preview, blocked, result }) => {
81 if (result) {
82 const failed = result.error || result[ABILITY]?.status === 'error';
83 return (
84 <Line>
85 {failed
86 ? __("The image couldn't be optimized.", 'extendify-local')
87 : __('Image optimized.', 'extendify-local')}
88 </Line>
89 );
90 }
91 if (!gate) return <Line>{__('Optimizing image...', 'extendify-local')}</Line>;
92 if (!preview)
93 return (
94 <Line>{__('Checking your Imagify quota...', 'extendify-local')}</Line>
95 );
96 if (blocked) return <Line>{blocked}</Line>;
97 return <Cost preview={preview} />;
98 };
99
100 export const OptimizeMedia = ({ inputs, result, onConfirm, onCancel }) => {
101 const gate = !!onConfirm && !result;
102 const preview = usePreview(inputs, gate);
103 const blocked = blockedMessage(preview?.status);
104
105 return (
106 <div className="mb-4 ms-12 me-2 flex flex-col rounded-lg border border-gray-300 bg-gray-50">
107 <div className="rounded-lg border-b border-gray-300 bg-white p-3">
108 <Body gate={gate} preview={preview} blocked={blocked} result={result} />
109 </div>
110 {gate && preview ? (
111 <div className="flex justify-start gap-2 p-3">
112 <button
113 type="button"
114 className="w-full rounded-sm border border-gray-500 bg-white p-2 text-sm text-gray-900"
115 onClick={onCancel}
116 >
117 {__('Cancel', 'extendify-local')}
118 </button>
119 {blocked ? null : (
120 <button
121 type="button"
122 className="w-full rounded-sm border border-design-main bg-design-main p-2 text-sm text-white"
123 onClick={() => onConfirm({ data: { ...inputs, confirm: true } })}
124 >
125 {__('Optimize image', 'extendify-local')}
126 </button>
127 )}
128 </div>
129 ) : null}
130 </div>
131 );
132 };
133