1jQuery(function ($) { 2 // === UPLOAD HANDLER === 3 const form = $('#beo-album-form'); 4 const progressWrap = $('.beo-progress-wrap'); 5 const progressBar = $('.beo-progress-bar'); 6 const progressText = $('.beo-progress-text'); 7 8 form.on('submit', function (e) { 9 e.preventDefault(); 10 const files = $('input[type=file]', this)[0].files; 11 if (!files.length) return alert('Please select at least one image.'); 12 13 const data = new FormData(); 14 $.each(files, (i, f) => data.append('beo_images[]', f)); 15 data.append('action', 'beo_album_upload'); 16 data.append('security', BeoAlbum.nonce); 17 18 progressBar.width('0%'); 19 progressText.text('Uploadingâ¦'); 20 progressWrap.fadeIn(200); 21 22 $.ajax({ 23 url: BeoAlbum.ajax_url, 24 type: 'POST', 25 data: data, 26 processData: false, 27 contentType: false, 28 xhr: function () { 29 const xhr = new window.XMLHttpRequest(); 30 xhr.upload.addEventListener('progress', e => { 31 if (e.lengthComputable) { 32 const pct = Math.round((e.loaded / e.total) * 100); 33 progressBar.css('width', pct + '%'); 34 } 35 }); 36 return xhr; 37 }, 38 success: function (res) { 39 if (res.success) { 40 progressText.text('Upload complete â '); 41 setTimeout(() => location.reload(), 800); 42 } else { 43 progressText.text('Upload failed â'); 44 } 45 }, 46 error: () => progressText.text('Error during upload â'), 47 complete: () => setTimeout(() => progressWrap.fadeOut(400), 1500) 48 }); 49 }); 50 51 // === DELETE HANDLER === 52 $(document).on('click', '.beo-del-btn', function (e) { 53 e.preventDefault(); 54 const $btn = $(this); 55 const $card = $btn.closest('.beo-card'); 56 const attachmentId = $btn.closest('.beo-del-form').data('aid'); 57 if (!attachmentId) return alert('Error: missing attachment ID.'); 58 if (!confirm('Remove this image?')) return; 59 60 $.ajax({ 61 url: BeoAlbum.ajax_url, 62 type: 'POST', 63 dataType: 'json', 64 data: { action: 'beo_album_delete', security: BeoAlbum.nonce, attachment_id: attachmentId }, 65 beforeSend: () => $btn.prop('disabled', true).text('Removing...'), 66 success: res => { 67 if (res.success) $card.fadeOut(300, () => $card.remove()); 68 else { 69 alert('Error: ' + (res.data || 'Could not remove image.')); 70 $btn.prop('disabled', false).text('Remove'); 71 } 72 }, 73 error: () => { 74 alert('Error connecting to server.'); 75 $btn.prop('disabled', false).text('Remove'); 76 } 77 }); 78 }); 79 80 // === DYNAMIC ALBUM HANDLER WITH CACHE + LIGHTBOX === 81 const albumCache = {}; 82 83 $('#album-gallery-container').on('click', '.album-user-card', function () { 84 const userId = $(this).data('user-id'); 85 const $container = $('#album-gallery-container'); 86 let $spinner = $('#album-loading-spinner'); 87 88 if (!$spinner.length) {
89 $spinner = $('<div id="album-loading-spinner"><div class="spinner"></div></div>'); 90 $container.append($spinner); 91 } 92 $spinner.css('display', 'flex'); // show instantly 93 94 const showAlbum = html => { 95 $('#album-user-grid').fadeOut(150, function () { 96 $('#album-user-gallery').html(html).fadeIn(250, function () { 97 if (typeof GLightbox !== 'undefined') { 98 GLightbox({ 99 selector: '.glightbox', 100 skin: 'clean', // enables close/toolbar 101 openEffect: 'zoom', 102 closeEffect: 'fade', 103 touchNavigation: true, 104 loop: true, 105 zoomable: true, 106 moreText: '', 107 svg: { 108 close: 109 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">' + 110 '<line x1="18" y1="6" x2="6" y2="18" stroke="currentColor" stroke-width="2"/>' + 111 '<line x1="6" y1="6" x2="18" y2="18" stroke="currentColor" stroke-width="2"/>' + 112 '</svg>' 113 } 114 }); 115 } 116 }); 117 }); 118 $spinner.hide(); 119 }; 120 121 if (albumCache[userId]) { 122 showAlbum(albumCache[userId]); 123 return; 124 } 125 126 $.post(BeoAlbum.ajax_url, { 127 action: 'beo_album_load_user', 128 security: BeoAlbum.nonce, 129 user_id: userId 130 }) 131 .done(res => { 132 if (res.success) { 133 albumCache[userId] = res.data; 134 showAlbum(res.data); 135 } else { 136 alert(res.data || 'Failed to load album.'); 137 $spinner.hide(); 138 } 139 }) 140 .fail(() => { 141 alert('Connection error'); 142 $spinner.hide(); 143 }); 144 }); 145 146 // === BACK BUTTON === 147 $('#album-gallery-container').on('click', '#album-back-btn', function () { 148 $('#album-user-gallery').fadeOut(200, function () { 149 $('#album-user-grid').fadeIn(250); 150 }); 151 }); 152});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.