PluginProbe
Extendify / trunk
Extendify vtrunk
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.4 → trunk 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;