1/** 2 * Dribbble Feed Load More Functionality 3 * 4 * Handles dynamic loading of additional Dribbble posts with: 5 * - AJAX loading of additional posts 6 * - Masonry layout support 7 * - Clone-based template system 8 * - Individual module state management 9 * - Comprehensive error handling 10 * 11 * @since 1.0.0 12 * @package DiviSocialFeed 13 */ 14 15jQuery(document).ready(function ($) { 16 // // Initialize load more functionality for each instance 17 // Initialize load more functionality for each instance 18$(".dsf_drb_load_more").each(function () { 19 let button = $(this); 20 let blockId = button.data("object"); 21 let feedContainer = $("#" + blockId); 22 23 // Validate container existence 24 if (!feedContainer.length) { 25 console.warn(`Feed container with ID '${blockId}' not found.`); 26 return; 27 } 28 29 // Store current page individually for each module 30 feedContainer.data("currentPage", 2); 31 32 // Click handler for load more button 33 button.on("click", function () { 34 // Get configuration parameters 35 let perPage = button.data("per-page"); 36 let originalText = button.text(); 37 let currentPage = feedContainer.data("currentPage"); 38 39 // AJAX request to load more posts 40 $.ajax({
41 url: dsf_drb_ajax.ajax_url, 42 type: "POST", 43 data: { 44 action: "dsf_drb_load_more", // <-- new Dribbble action 45 nonce: dsf_drb_ajax.nonce, 46 block_id: blockId, 47 perpage: perPage, 48 page: currentPage, // send page instead of cursor 49 }, 50 51 beforeSend: function () { 52 console.log(`Loading Dribbble page ${currentPage} for ${blockId}...`); 53 button.prop("disabled", true).text("Loading..."); 54 }, 55 56 success: function (response) { 57 if (response.success && response.data.shots.length > 0) { 58 // Initialize shots array if it doesn't exist 59 if (!window[blockId]) { 60 window[blockId] = { shots: [] }; 61 } 62 63 // Append new shots to existing array 64 window[blockId].shots = window[blockId].shots.concat(response.data.shots); 65 66 // Get the first article as template for cloning 67 let existingArticle = feedContainer.find(".dsf_drb_feed_item").first(); 68 69 if (existingArticle.length) { 70 // Process each new shot 71 $.each(response.data.shots, function (index, post) { 72 let newArticle = existingArticle.clone(); 73 74 // Remove inline styles 75 newArticle.removeAttr("style"); 76 77 // Set attributes 78 newArticle.attr("data-id", post.id); 79 newArticle.attr("data-link", post.html_url); 80 newArticle.attr("data-object", blockId); 81 82 // Update image 83 let img = newArticle.find("img.dribbble-feed__media"); 84 if (img.length) { 85 let mediaUrl = 86 post.images?.two_x || 87 post.images?.one_x || 88 post.images?.teaser || 89 ""; 90 91 img.attr("src", mediaUrl); 92 } 93 94 // Update post date 95 let postDateDisplay = newArticle.find(".dsf_drb_post_date"); 96 if (postDateDisplay.length) { 97 postDateDisplay.text(post.published || ""); 98 } 99 100 // Update post date 101 let postTitleDisplay = newArticle.find(".dsf_drb_post_title"); 102 if (postTitleDisplay.length) { 103 postTitleDisplay.text(post.title || ""); 104 } 105 106 // Append to container 107 feedContainer.append(newArticle); 108 109 // Trigger Isotope/Masonry layout update only if it's masonry layout 110 if (feedContainer.hasClass("dsf_drb_grid_masonry")) { 111 feedContainer.imagesLoaded(function () { 112 feedContainer.masonry("appended", newArticle); 113 }); 114 } 115 }); 116 } else { 117 console.warn(`No existing article found to clone for ${blockId}.`); 118 } 119 120 // Update next page 121 feedContainer.data("currentPage", response.data.next_page); 122 123 button.text(originalText); 124 } else { 125 console.warn(`No more shots for ${blockId}.`); 126 button.text(originalText); 127 button.hide(); 128 } 129 }, 130 131 error: function (error) { 132 console.error(`Error loading Dribbble posts for ${blockId}:`, error); 133 button.text(originalText); 134 }, 135 136 complete: function () { 137 button.prop("disabled", false); 138 }, 139 }); 140 });
141}); 142 143 144 /** 145 * Handle click events on Dribbble posts 146 * 147 * Opens post in new tab when clicked (if popup is disabled) 148 */ 149 $(document).on("click", ".dsf_drb_feed_inner article[data-link]", function () { 150 if ($(this).attr("data-popup") === "off") { 151 var url = $(this).attr("data-link"); 152 if (url) { 153 window.open(url, "_blank"); // Open in a new tab 154 } 155 } 156 }); 157});
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.