1const hashtag_reg = /\#[^ ]*/gm; 2 3function timeout(ms) { 4 return new Promise(resolve => setTimeout(resolve, ms)); 5} 6 7function timeSince(date) { 8 9 const seconds = Math.floor((new Date() - date) / 1000); 10 11 let interval = seconds / 31536000; 12 13 if (interval > 1) { 14 return Math.floor(interval) + " years"; 15 } 16 interval = seconds / 2592000; 17 if (interval > 1) { 18 return Math.floor(interval) + " months"; 19 } 20 interval = seconds / 86400; 21 if (interval > 1) { 22 return Math.floor(interval) + " days"; 23 } 24 interval = seconds / 3600; 25 if (interval > 1) { 26 return Math.floor(interval) + " hours"; 27 } 28 interval = seconds / 60; 29 if (interval > 1) { 30 return Math.floor(interval) + " minutes"; 31 } 32 return Math.floor(seconds) + " seconds"; 33} 34 35$(document).ready(() => { 36 let twitterArrowClicked = {click:0}; 37 let telegramArrowClicked = {click:0}; 38 let youtubeArrowClicked = {click:0}; 39 $.ajax({ 40 url: '/user_data/last_posts.json?date='+Date.now(), 41 type: 'GET', 42 success: function(data) { 43 data = data.sort((a,b) => b.time.localeCompare(a.time)) 44 const twitterPostsContainer = document.getElementsByClassName('twitter-posts')[0]; 45 const telegramPostsContainer = document.getElementsByClassName('telegram-posts')[0]; 46 const youtubePostsContainer = document.getElementById('youtube-posts'); 47 const youtubePostsContainer2 = document.getElementById('youtube-posts2'); 48 49 let iTwitter = 0; 50 let iTelegram = 0; 51 let iYouTube = [0, 0]; 52 53 let youtubeCnt = 0; 54 let youtubeIndex = 0; 55 56 for (let j = 0; j < data.length; j++) { 57 let postsContainer = null; 58 let i = null; 59 let post = data[j]; 60 let additional_class = 'shown'; 61 let postContent = ``; 62 63 if (!['youtube', 'telegram', 'twitter'].includes(post.social_network)) return; 64 65 if (post.social_network == 'youtube') { 66 if (!youtubePostsContainer) continue; 67 68 69 if (youtubeCnt % 2 == 0) { 70 postsContainer = youtubePostsContainer; 71 youtubeIndex = 0; 72 } 73 else { 74 postsContainer = youtubePostsContainer2; 75 youtubeIndex = 1; 76 } 77 78 if(iYouTube[youtubeIndex] > 2) additional_class = 'right hidden'; 79 80 const code = post.link.split('=')[1].split('&')[0]; 81 postContent = ` 82 <iframe class="video-image lazyload" width="318" height="178" data-src="https://www.youtube.com/embed/${code}" title="YouTube video player" frameborder="0" allowfullscreen></iframe> 83 <p class="video-title"> 84 ${post.text} 85 </p> 86 `; 87 i = iYouTube[youtubeIndex]; 88 iYouTube[youtubeIndex]++; 89 90 youtubeCnt ++; 91 } 92 else if (post.social_network == 'twitter') { 93 if (!twitterPostsContainer) continue; 94 if(iTwitter > 2) additional_class = 'right hidden'; 95 postsContainer = twitterPostsContainer; 96 let tweetText = post.text; 97 if (post.text.length > 250) tweetText = tweetText.substring(0, 250) + ' ...'; 98 tweetText = tweetText.replace(hashtag_reg, '<span class="hashtag">$&</span>'); 99 postContent = ` 100 <p class="main-text">${tweetText}</p> 101 `; 102 i = iTwitter; 103 iTwitter++; 104 } 105 else if (post.social_network == 'telegram') { 106 if (!telegramPostsContainer) continue; 107 if(iTelegram > 2) additional_class = 'right hidden'; 108 postsContainer = telegramPostsContainer; 109 let telegramText = post.text; 110 if (post.text.length > 250) telegramText = telegramText.substring(0, 250) + ' ...'; 111 telegramText = telegramText.replace(hashtag_reg, '<span class="hashtag">$&</span>'); 112 postContent = ` 113 <p class="main-text">${telegramText}</p> 114 `; 115 i = iTelegram; 116 iTelegram++; 117 } 118 const timePass = new Date(post.time).getTime(); 119 const time = timeSince(timePass); 120 post.link = post.link.replace(/\s+/g, ""); 121 postsContainer.innerHTML += ` 122 <div data-number="${i}" class="post ${additional_class}"> 123 <div class="social-media-desc"> 124 <div> 125 <a href="${post.channel_link}"><img class="social-media-icon" src="/images/${post.social_network}-last-posts.png" alt=""></a> 126 </div> 127 <div><a href=${post.link}><p>${post.name}</p></a> 128 <p class="followers">${post.followers} Followers</p> 129 </div> 130 </div> 131 ${postContent} 132 <p class="time-posted">${time} ago</p> 133 </div> 134 `; 135 } 136 } 137 }); 138 139 function sortByNumber(htmlArray, asc) { 140 let arr = Array.from(htmlArray).map(el => { 141 return {el, number: el.dataset.number}; 142 }); 143 if (asc == 1) arr = arr.sort((a,b) => b.number - a.number); 144 else arr = arr.sort((a,b) => a.number - b.number); 145 return arr; 146 } 147 148 async function clickLeft(arrowClicked, arrowLeftId, arrowRightId, postsId) { 149 if (arrowClicked.click) return; 150 arrowClicked.click = 1; 151 document.getElementById(arrowLeftId).classList.remove('clicked'); 152 document.getElementById(arrowRightId).classList.remove('clicked'); 153 const left = document.getElementById(postsId).getElementsByClassName('left'); 154 const leftPosts = sortByNumber(left, 1); 155 if (leftPosts.length == 1) document.getElementById(arrowLeftId).classList.add('clicked'); 156 if (leftPosts.length <= 0) { 157 arrowClicked.click = 0; 158 document.getElementById(arrowLeftId).classList.add('clicked'); 159 return; 160 } 161 const shown = document.getElementById(postsId).getElementsByClassName('shown'); 162 const shownPosts = sortByNumber(shown, 1); 163 shownPosts[0].el.classList.remove('shown'); 164 shownPosts[0].el.classList.add('right'); 165 for (let i = 0; i < 1; i++) { 166 if (leftPosts.length <= i) break; 167 const el = leftPosts[i].el; 168 el.classList.remove('left'); 169 el.classList.add('shown'); 170 el.classList.remove('hidden'); 171 } 172 await timeout(1000); 173 shownPosts[0].el.classList.add('hidden'); 174 arrowClicked.click = 0; 175 } 176 177 async function clickRight(arrowClicked, arrowLeftId, arrowRightId, postsId) { 178 if (arrowClicked.click) return; 179 arrowClicked.click = 1; 180 document.getElementById(arrowLeftId).classList.remove('clicked'); 181 document.getElementById(arrowRightId).classList.remove('clicked'); 182 const right = document.getElementById(postsId).getElementsByClassName('right'); 183 const rightPosts = sortByNumber(right, 0); 184 if (rightPosts.length == 1) document.getElementById(arrowRightId).classList.add('clicked'); 185 if (rightPosts.length <= 0) { 186 arrowClicked.click = 0; 187 document.getElementById(arrowRightId).classList.add('clicked'); 188 return; 189 } 190 const shown = document.getElementById(postsId).getElementsByClassName('shown'); 191 const shownPosts = sortByNumber(shown, 0); 192 shownPosts[0].el.classList.remove('shown'); 193 shownPosts[0].el.classList.add('left'); 194 for (let i = 0; i < 1; i++) { 195 if (rightPosts.length <= i) break; 196 const el = rightPosts[i].el; 197 el.classList.remove('right'); 198 el.classList.add('shown'); 199 el.classList.remove('hidden'); 200 } 201 await timeout(1000); 202 shownPosts[0].el.classList.add('hidden'); 203 arrowClicked.click = 0; 204 } 205 206 if (document.getElementById('telegram-arrow-left')) { 207 $('#telegram-arrow-left').click(async e => { 208 clickLeft(telegramArrowClicked, 'telegram-arrow-left', 'telegram-arrow-right', 'telegram-posts'); 209 }); 210 211 $('#telegram-arrow-right').click(async e => { 212 clickRight(telegramArrowClicked, 'telegram-arrow-left', 'telegram-arrow-right', 'telegram-posts'); 213 }); 214 215 document.getElementById('telegram-arrow-left').classList.add('clicked'); 216 } 217 218 if (document.getElementById('twitter-arrow-left')) { 219 $('#twitter-arrow-right').click(async e => { 220 clickRight(twitterArrowClicked, 'twitter-arrow-left', 'twitter-arrow-right', 'twitter-posts'); 221 }); 222 223 $('#twitter-arrow-left').click(async e => { 224 clickLeft(twitterArrowClicked, 'twitter-arrow-left', 'twitter-arrow-right', 'twitter-posts'); 225 }); 226 document.getElementById('twitter-arrow-left').classList.add('clicked'); 227 } 228 229 if (document.getElementById('youtube-arrow-left')) {
230 $('#youtube-arrow-right').click(async e => { 231 clickRight(youtubeArrowClicked, 'youtube-arrow-left', 'youtube-arrow-right', 'youtube-posts'); 232 }); 233 234 $('#youtube-arrow-left').click(async e => { 235 clickLeft(youtubeArrowClicked, 'youtube-arrow-left', 'youtube-arrow-right', 'youtube-posts'); 236 }); 237 document.getElementById('youtube-arrow-left').classList.add('clicked'); 238 } 239 240 if (document.getElementById('youtube-arrow-left2')) { 241 $('#youtube-arrow-right2').click(async e => { 242 clickRight(youtubeArrowClicked, 'youtube-arrow-left2', 'youtube-arrow-right2', 'youtube-posts2'); 243 }); 244 245 $('#youtube-arrow-left2').click(async e => { 246 clickLeft(youtubeArrowClicked, 'youtube-arrow-left2', 'youtube-arrow-right2', 'youtube-posts2'); 247 }); 248 document.getElementById('youtube-arrow-left2').classList.add('clicked'); 249 } 250});
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.