PluginProbe
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more / 3.7.2
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more v3.7.2
3.7.2 3.7.1 3.7.0 3.6.0 3.6.1 3.5.2 trunk 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.6.0 2.6.1 All 73 releases
stockpack / assets / js / stockpack-upscale.js

stockpack-upscale.js in StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more 3.7.2, at assets/js/stockpack-upscale.js

277 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 jQuery( function( $ ) {
2 const config = window.stockpackUpscale || {};
3 const strings = config.strings || {};
4 const POLL_FAST = 2000;
5 const POLL_SLOW = 5000;
6 const FAST_POLLS = 7;
7 const MAX_POLLS = 60;
8
9 const TOAST_COLOURS = {
10 info: '#72aee6',
11 success: '#00a32a',
12 error: '#d63638',
13 };
14
15 let hideTimer = null;
16
17 function notice( message, type, options ) {
18 const kind = type || 'info';
19 const settings = options || {};
20
21 $( '.stockpack-upscale-toast' ).remove();
22 window.clearTimeout( hideTimer );
23
24 const $toast = $( '<div class="stockpack-upscale-toast" role="status" aria-live="polite" />' ).css( {
25 position: 'fixed',
26 right: '24px',
27 bottom: '24px',
28 zIndex: 100000,
29 maxWidth: '380px',
30 padding: '14px 16px',
31 paddingRight: '38px',
32 background: '#fff',
33 borderLeft: '4px solid ' + ( TOAST_COLOURS[ kind ] || TOAST_COLOURS.info ),
34 borderRadius: '4px',
35 boxShadow: '0 4px 16px rgba(0,0,0,.18)',
36 fontSize: '13px',
37 lineHeight: '1.5',
38 color: '#1d2327',
39 wordBreak: 'break-word',
40 } );
41
42 if ( settings.spinner ) {
43 // Core's own spinner, so it matches the admin and needs no keyframes
44 // of ours on a screen that loads none of our css.
45 $( '<span class="spinner is-active" />' ).css( {
46 float: 'none',
47 margin: '0 8px 0 0',
48 verticalAlign: 'text-top',
49 } ).appendTo( $toast );
50 }
51
52 $( '<span />' ).text( message ).appendTo( $toast );
53
54 if ( settings.link ) {
55 $( '<a target="_blank" rel="noopener" />' )
56 .attr( 'href', settings.link )
57 .text( settings.linkText || settings.link )
58 .css( { marginLeft: '6px', fontWeight: 600 } )
59 .appendTo( $toast );
60 }
61
62 $( '<button type="button" aria-label="Dismiss">&times;</button>' )
63 .css( {
64 position: 'absolute',
65 top: '6px',
66 right: '6px',
67 border: 0,
68 background: 'none',
69 cursor: 'pointer',
70 fontSize: '18px',
71 lineHeight: 1,
72 color: '#787c82',
73 } )
74 .on( 'click', function() {
75 $toast.remove();
76 } )
77 .appendTo( $toast );
78
79 $toast.appendTo( document.body );
80
81 // Nothing times itself out. An upscale runs for around half a minute, so
82 // a progress message that faded left the screen looking idle while
83 // credits were being spent. Toasts go when the user dismisses them, when
84 // the next one replaces them, or when the page reloads.
85 if ( settings.hideAfter ) {
86 hideTimer = window.setTimeout( function() {
87 $toast.fadeOut( 200, function() {
88 $toast.remove();
89
90 if ( settings.thenShow ) {
91 notice( settings.thenShow, settings.thenType, {
92 spinner: settings.thenSpinner,
93 } );
94 }
95 } );
96 }, settings.hideAfter );
97 }
98 }
99
100 let running = false;
101
102 // Polling lives in this page. Leaving mid-upscale means Magnific finishes and
103 // bills it while nothing is left to save the result, so the image is paid for
104 // and lost.
105 function guardUnload( event ) {
106 if ( ! running ) {
107 return undefined;
108 }
109
110 event.preventDefault();
111 event.returnValue = strings.leaving || '';
112
113 return event.returnValue;
114 }
115
116 function startRun() {
117 running = true;
118 window.addEventListener( 'beforeunload', guardUnload );
119 }
120
121 function endRun() {
122 running = false;
123 window.removeEventListener( 'beforeunload', guardUnload );
124 }
125
126 function post( data ) {
127 return $.post( window.ajaxurl, data );
128 }
129
130 function requestError( xhr ) {
131 const payload = xhr && xhr.responseJSON;
132
133 if ( payload && payload.data && payload.data.message ) {
134 return payload.data.message;
135 }
136
137 if ( xhr && 0 === xhr.status ) {
138 return strings.timeout;
139 }
140
141 if ( xhr && xhr.status ) {
142 return strings.failed + ' (HTTP ' + xhr.status + ')';
143 }
144
145 return strings.failed;
146 }
147
148 function poll( task, attempt ) {
149 if ( attempt >= MAX_POLLS ) {
150 endRun();
151 notice( strings.timeout, 'error' );
152 return;
153 }
154
155 window.setTimeout( function() {
156 post( {
157 action: 'generate_status-stockpack',
158 security: config.nonceGenerate,
159 task,
160 } ).done( function( response ) {
161 if ( ! response || ! response.success ) {
162 endRun();
163 notice( ( response && response.data && response.data.message ) || strings.failed, 'error' );
164 return;
165 }
166
167 if ( 'pending' === response.data.status ) {
168 poll( task, attempt + 1 );
169 return;
170 }
171
172 download( response.data.id );
173 } ).fail( function( xhr ) {
174 endRun();
175 notice( requestError( xhr ), 'error' );
176 } );
177 }, attempt < FAST_POLLS ? POLL_FAST : POLL_SLOW );
178 }
179
180 function download( task ) {
181 notice( strings.saving, 'info', { spinner: true } );
182
183 post( {
184 action: 'download-stockpack',
185 security: config.nonceDownload,
186 media_id: task,
187 provider: 'Magnific AI',
188 post_id: 0,
189 } ).done( function( response ) {
190 if ( ! response || ! response.success ) {
191 endRun();
192 notice( ( response && response.data && response.data.message ) || strings.failed, 'error' );
193 return;
194 }
195
196 endRun();
197 notice( strings.done, 'success', { spinner: true } );
198
199 const saved = response.data && response.data.id;
200
201 window.setTimeout( function() {
202 if ( saved && config.editUrl ) {
203 window.location.href = config.editUrl + saved;
204 return;
205 }
206
207 window.location.reload();
208 }, 1200 );
209 } ).fail( function( xhr ) {
210 endRun();
211 notice( requestError( xhr ), 'error' );
212 } );
213 }
214
215 $( document ).on( 'click', '.stockpack-upscale', function( event ) {
216 event.preventDefault();
217
218 const $link = $( this );
219 const factor = parseInt( $link.data( 'factor' ), 10 ) || 2;
220
221 if ( running ) {
222 // The only transient one: it must hand the screen back to the
223 // progress message rather than bury it.
224 notice( strings.busy, 'info', {
225 hideAfter: 4000,
226 thenShow: strings.working,
227 thenType: 'info',
228 thenSpinner: true,
229 } );
230
231 return;
232 }
233
234 const quote = ( config.upscale && config.upscale[ factor ] ) || {};
235
236 if ( quote.refuse ) {
237 notice( quote.refuse, 'error', {
238 link: false === quote.link ? null : config.wallet && config.wallet.top_up_url,
239 linkText: strings.topUp,
240 } );
241
242 return;
243 }
244
245 const question = quote.confirm || strings.confirm;
246
247 if ( question && ! window.confirm( question ) ) {
248 return;
249 }
250
251 startRun();
252 notice( strings.working, 'info', { spinner: true } );
253
254 post( {
255 action: 'generate-stockpack',
256 security: config.nonceGenerate,
257 generate_action: 'upscale',
258 image_url: $link.data( 'url' ),
259 scale_factor: factor,
260 } ).done( function( response ) {
261 if ( ! response || ! response.success ) {
262 endRun();
263 notice( ( response && response.data && response.data.message ) || strings.failed, 'error', {
264 link: response && response.data && response.data.link,
265 linkText: response && response.data && response.data.link_text,
266 } );
267 return;
268 }
269
270 poll( response.data.task_id, 0 );
271 } ).fail( function( xhr ) {
272 endRun();
273 notice( requestError( xhr ), 'error' );
274 } );
275 } );
276 } );
277