1jQuery(document).ready(function ($) { 2 $(".dsf_fb_load_more").each(function () { 3 let button = $(this); 4 let blockId = button.data("object"); 5 let feedContainer = $("#" + blockId); 6 7 if (!feedContainer.length) { 8 console.warn(`Feed container with ID '${blockId}' not found.`); 9 return; 10 } 11 12 // Store nextCursor individually for each module 13 feedContainer.data("nextCursor", ""); 14 15 button.on("click", function () { 16 let perPage = button.data("per-page"); 17 let captionLength = button.data("caption-length"); 18 let originalText = button.text(); 19 let nextCursor = feedContainer.data("nextCursor"); // Get stored cursor 20 21 $.ajax({ 22 url: dsf_fb_ajax.ajax_url, 23 type: "POST", 24 data: { 25 action: "dsf_fb_load_more", 26 nonce: dsf_fb_ajax.nonce, 27 block_id: blockId, 28 perpage: perPage, 29 next_cursor: nextCursor, 30 }, 31 beforeSend: function () { 32 console.log(`Loading more posts for ${blockId}...`); 33 button.prop("disabled", true).text("Loading..."); 34 }, 35 success: function (response) { 36 if (response.success && response.data.media.length > 0) { 37 if (!window[blockId]) { 38 window[blockId] = { media: [] }; 39 } 40 window[blockId].media = window[blockId].media.concat(response.data.media); 41 // console.log("Updated media array:", window[blockId].media); 42 43 // Update the next cursor for the specific module 44 feedContainer.data("nextCursor", response.data.next_cursor); 45 46 let existingArticle = feedContainer.find(".dsf_fb_feed_item").first(); 47 48 if (existingArticle.length) { 49 $.each(response.data.media, function (index, post) { 50 51 let newArticle = existingArticle.clone(); 52 newArticle.removeAttr("style").hide(); 53 54 // Set custom attributes 55 newArticle.attr("data-id", post.id); 56 newArticle.attr("data-link", post.permalink_url); 57 newArticle.attr("data-object", blockId); 58 59 // --- Render media preview fresh --- 60 61 let mediaContainer = newArticle.find(".dsf_fb_media_preview"); 62 63 if (mediaContainer.length) { 64 mediaContainer.empty(); 65 mediaContainer.removeClass("dsf_fb_link_preview"); 66 67 let attachmentType = post.attachments?.data?.[0]?.type || post.attachment_type || ""; 68 let mediaType = post.attachments?.data?.[0]?.media_type || ""; 69 let postSource = post.attachments?.data?.[0]?.media?.source || ""; 70 let postAttachment = post.attachments?.data?.[0]?.url || post.attachment_url || ""; 71 let attachmentTitle = post.attachments?.data?.[0]?.title || ""; 72 let displayImage = post.attachments?.data?.[0]?.media?.image?.src || post.attachment_thumb || post.full_picture || ""; 73 74 if (attachmentType === "video_inline" && postSource.endsWith(".mp4")) { 75 mediaContainer.html(`<video controls preload="metadata" src="${postSource}"></video>`); 76 77 } else if (attachmentType === "share" && postSource.includes("youtube.com/embed")) { 78 let videoUrl = postSource + "?autoplay=0&rel=0"; 79 80 mediaContainer.html(` 81 <iframe 82 sandbox="allow-same-origin allow-scripts allow-presentation allow-popups" 83 width="100%" 84 height="auto" 85 style="aspect-ratio: 16/9;" 86 src="${videoUrl}" 87 frameborder="0" 88 allowfullscreen> 89 </iframe> 90 `); 91 92 } else if ( 93 attachmentType === "share" && 94 mediaType === "link" && 95 attachmentTitle 96 ) { 97 // Add class only for link preview 98 mediaContainer.addClass("dsf_fb_link_preview"); 99 100 mediaContainer.html(` 101 <a href="${postAttachment}" target="_blank" rel="noopener noreferrer"> 102 ${displayImage ? `<img src="${displayImage}" alt="${attachmentTitle}">` : ""} 103 <h4 class="dsf_fb_link_title">${attachmentTitle}</h4> 104 </a> 105 `); 106 107 } else if (post.attachment_url && displayImage) { 108 mediaContainer.html(`<img src="${displayImage}" alt="">`); 109 110 } else if (displayImage) { 111 mediaContainer.html(`<img src="${displayImage}" alt="">`); 112 113 } else { 114 mediaContainer.html(""); 115 } 116 } 117 118 // Like count 119 let likeCount = post.reactions?.summary?.total_count || post.reaction_count || 0; 120 let likeCountElement = newArticle.find(".dsf_fb_like_count .like-count"); 121 if (likeCountElement.length) { 122 likeCountElement.text(likeCount); 123 } 124 125 // Comment count 126 let commentCount = post.comments?.summary?.total_count || post.comment_count || 0; 127 let commentCountElement = newArticle.find(".dsf_fb_comment_count .comment-count"); 128 if (commentCountElement.length) { 129 commentCountElement.text(commentCount); 130 } 131 132 // Date Update 133 let postDate = post.created_time || ""; 134 let dateElement = newArticle.find(".dsf_fb_post_date"); 135 if (dateElement.length && postDate) { 136 dateElement.text(postDate); 137 } 138 139 // Update View Post button link 140 let viewPostButton = newArticle.find(".dsf_fb_view_post_button"); 141 if (viewPostButton.length && post.permalink_url) { 142 viewPostButton.attr("href", post.permalink_url); 143 } else if (viewPostButton.length) { 144 viewPostButton.attr("href", "#"); 145 } 146 147 // Caption 148 let captionElement = newArticle.find(".dsf_fb_post_c
148aption"); 149 if (captionElement.length) { 150 let fullCaption = 151 post.message || 152 post.attachments?.data?.[0]?.description || 153 post.attachments?.data?.[0]?.title || 154 post.story || 155 ""; 156 157 let trimmedCaption = 158 fullCaption.length > captionLength 159 ? fullCaption.substring(0, captionLength) + "â¦" 160 : fullCaption; 161 162 // Replace line breaks (\n) with <br> 163 let formattedCaption = trimmedCaption.replace(/\n/g, "<br>"); 164 165 // Insert as HTML so <br> renders 166 captionElement.html(formattedCaption); 167 } 168 169 // Append the item to the container 170 feedContainer.append(newArticle); 171 newArticle.fadeIn(300); 172 173 // Trigger Isotope/Masonry layout update only if it's masonry layout 174 if (feedContainer.hasClass("dsf_fb_grid_masonry")) { 175 feedContainer.imagesLoaded(function () { 176 feedContainer.masonry("appended", newArticle); 177 newArticle.fadeIn(600); 178 }); 179 } 180 181 }); 182 183 } else { 184 console.warn(`No existing article found to clone for ${blockId}.`); 185 } 186 // Hide the button if no more data is available 187 if (!response.data.next_cursor) { 188 console.log(`No more posts for ${blockId}.`); 189 button.hide(); 190 } else { 191 button.text(originalText); 192 } 193 } else { 194 console.warn(`No data received for ${blockId}.`); 195 button.text(originalText); 196 button.hide(); 197 } 198 }, 199 error: function (error) { 200 console.error(`Error loading posts for ${blockId}:`, error); 201 button.text(originalText); 202 }, 203 complete: function () { 204 button.prop("disabled", false); 205 }, 206 }); 207 }); 208 }); 209 210 $(document).on("click", ".dsf_fb_feed_inner article[data-link]", function () { 211 if ($(this).attr("data-popup") === "off") { 212 var url = $(this).attr("data-link"); 213 if (url) { 214 window.open(url, "_blank"); // Open in a new tab 215 } 216 } 217 }); 218});
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.