PluginProbe
Extendify / 3.2.1
Extendify v3.2.1
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
← All changes | src/Shared/api/wp.js +57 -5 3.0.43.2.1 View file →
@@ -1,6 +1,8 @@
1 1 import { AI_HOST } from '@constants';
2 +import { renderAiLabelPill, stampAiLabel } from '@shared/lib/ai-label';
2 3 import apiFetch from '@wordpress/api-fetch';
4 +import { sprintf } from '@wordpress/i18n';
3 5 import { addQueryArgs } from '@wordpress/url';
4 6
5 7 export const getPlugin = async (slug) => {
6 8 const response = await apiFetch({
@@ -25,10 +27,23 @@
25 27
26 28 return response;
27 29 };
28 30
31 +export const enableAutoUpdate = async (plugin) => {
32 + if (!plugin) return;
33 + try {
34 + await apiFetch({
35 + path: '/extendify/v1/shared/enable-auto-update',
36 + method: 'POST',
37 + data: { plugin },
38 + });
39 + } catch (_e) {
40 + // Best-effort: the install already succeeded.
41 + }
42 +};
43 +
29 44 export const installPlugin = async (slug) => {
30 - return await apiFetch({
45 + const plugin = await apiFetch({
31 46 path: '/wp/v2/plugins',
32 47 method: 'POST',
33 48 data: {
34 49 slug,
@@ -33,8 +48,12 @@
33 48 data: {
34 49 slug,
35 50 },
36 51 });
52 +
53 + await enableAutoUpdate(plugin?.plugin);
54 +
55 + return plugin;
37 56 };
38 57
39 58 export const activatePlugin = async (slug) => {
40 59 const plugin = await getPlugin(slug);
@@ -54,8 +73,17 @@
54 73 img.onerror = (e) => reject(e);
55 74 });
56 75 };
57 76
77 +const shouldDisclose = (metadata) =>
78 + Boolean(metadata.aiGenerated) && Boolean(metadata.disclose);
79 +
80 +const altText = (metadata) => {
81 + if (!shouldDisclose(metadata)) return metadata.alt ?? '';
82 + const pattern = window.extSharedData?.aiImageAltPattern ?? 'AI Generated: %s';
83 + return sprintf(pattern, metadata.alt ?? '').trim();
84 +};
85 +
58 86 export const importImage = async (imageUrl, metadata = {}) => {
59 87 const image = new Image();
60 88 image.src = imageUrl;
61 89 image.crossOrigin = 'anonymous';
@@ -67,8 +95,11 @@
67 95
68 96 const ctx = canvas.getContext('2d');
69 97 if (!ctx) return;
70 98 ctx.drawImage(image, 0, 0);
99 + if (shouldDisclose(metadata)) {
100 + stampAiLabel(ctx, canvas.width, canvas.height);
101 + }
71 102
72 103 const blob = await new Promise((resolve) => {
73 104 canvas.toBlob((blob) => {
74 105 blob && resolve(blob);
@@ -76,11 +107,14 @@
76 107 });
77 108
78 109 const formData = new FormData();
79 110 formData.append('file', new File([blob], metadata.filename));
80 - formData.append('alt_text', metadata.alt ?? '');
111 + formData.append('alt_text', altText(metadata));
81 112 formData.append('caption', metadata.caption ?? '');
82 113 formData.append('status', 'publish');
114 + if (metadata.aiGenerated) {
115 + formData.append('meta[extendify_ai_generated]', '1');
116 + }
83 117
84 118 return await apiFetch({
85 119 path: 'wp/v2/media',
86 120 method: 'POST',
@@ -91,10 +125,22 @@
91 125 export const importImageServer = async (src, metadata = {}) => {
92 126 const formData = new FormData();
93 127 formData.append('source', src);
94 128 // Fallback doesn't support custom file_name
95 - formData.append('alt_text', metadata.alt ?? '');
129 + formData.append('alt_text', altText(metadata));
96 130 formData.append('caption', metadata.caption ?? '');
131 + if (metadata.aiGenerated) {
132 + formData.append('ai_generated', '1');
133 + if (shouldDisclose(metadata)) {
134 + const pill = await renderAiLabelPill();
135 + if (pill) {
136 + formData.append(
137 + 'disclosure_label',
138 + new File([pill], 'disclosure-label.png', { type: 'image/png' }),
139 + );
140 + }
141 + }
142 + }
97 143
98 144 return await apiFetch({
99 145 path: '/extendify/v1/draft/upload-image',
100 146 method: 'POST',
@@ -109,22 +155,28 @@
109 155 unsplashId,
110 156 metadata = { alt: '', caption: '' },
111 157 ) => {
112 158 let image;
159 + const aiGenerated = source === 'ai-generated';
113 160 if (unsplashId) {
114 161 await downloadPing(id, source, { unsplashId });
162 + } else if (aiGenerated && id) {
163 + await downloadPing(id, source, { disclose: metadata.disclose });
115 164 }
116 165 try {
117 166 image = await importImage(src, {
118 167 alt: metadata.alt,
119 - filename: 'image.jpg',
168 + filename: metadata.filename ?? 'image.jpg',
120 169 caption: metadata.caption,
170 + aiGenerated,
171 + disclose: metadata.disclose,
121 172 });
122 173 } catch (_e) {
123 174 image = await importImageServer(src, {
124 175 alt: metadata.alt,
125 - filename: 'image.jpg',
126 176 caption: metadata.caption,
177 + aiGenerated,
178 + disclose: metadata.disclose,
127 179 });
128 180 }
129 181
130 182 return image;