let user = {}; let cursor; let linkColors = {}; let listId = location.pathname.split('/')[3]; let subpage; // Util function updateSubpage() { Array.from(document.getElementsByClassName('list-switch')).forEach(el => el.classList.remove('list-switch-active')); document.getElementById('list-members-container').hidden = true; document.getElementById('list-tweets-container').hidden = true; document.getElementById('list-followers-container').hidden = true; end = false; cursor = undefined; if(location.href.endsWith('/members')) { subpage = 'members'; document.getElementById('list-members-container').hidden = false; document.getElementById('list-members').innerHTML = ''; document.getElementById('ns-members').classList.add('list-switch-active'); } else if(location.href.endsWith('/followers')) { subpage = 'followers'; document.getElementById('list-followers-container').hidden = false; document.getElementById('list-followers').innerHTML = ''; document.getElementById('ns-followers').classList.add('list-switch-active'); } else { subpage = 'tweets'; document.getElementById('list-tweets-container').hidden = false; document.getElementById('list-tweets').innerHTML = ''; document.getElementById('ns-tweets').classList.add('list-switch-active'); } } function updateUserData() { API.account.verifyCredentials().then(u => { user = u; userDataFunction(u); renderUserData(); }).catch(e => { if (e === "Not logged in") { window.location.href = "https://twitter.com/i/flow/login?newtwitter=true"; } console.error(e); }); } // Render function renderUserData() { document.getElementById('wtf-viewall').href = `https://twitter.com/i/connect_people?newtwitter=true&user_id=${user.id_str}`; } function renderListData(data) { if(data.custom_banner_media) { document.getElementById('list-banner').src = data.custom_banner_media.media_info.original_img_url; } else { document.getElementById('list-banner').src = data.default_banner_media.media_info.original_img_url; } document.getElementsByTagName('title')[0].innerText = `${data.name} List - OldTwitter`; document.getElementById('list-name').innerText = data.name; document.getElementById('list-name').classList.toggle('user-protected', data.mode === 'Private'); document.getElementById('list-description').innerText = data.description; document.getElementById('list-members-count').innerText = data.member_count; document.getElementById('list-followers-count').innerText = data.subscriber_count; if(data.user_results && data.user_results.result) { document.getElementById('list-user').href = `https://twitter.com/${data.user_results.result.legacy.screen_name}/lists`; document.getElementById('list-avatar').src = `${(data.user_results.result.legacy.default_profile_image && vars.useOldDefaultProfileImage) ? chrome.runtime.getURL(`images/default_profile_images/default_profile_${Number(data.user_results.result.legacy.id_str) % 7}_normal.png`): data.user_results.result.legacy.profile_image_url_https}`.replace('_normal', '_bigger'); let actions = document.getElementById('list-actions'); actions.innerHTML = ``; if(data.user_results.result.rest_id === user.id_str) { actions.innerHTML = ` `; document.getElementById('list-btn-edit').addEventListener('click', () => { let modal = createModal(`

${LOC.edit_list.message}



${LOC.name.message}:


${LOC.description.message}:


${LOC.is_private.message}:

`, 'list-editor-modal'); document.getElementById('list-btn-save').addEventListener('click', async () => { document.getElementById('list-editor-error').innerText = ''; let name = document.getElementById('list-name-input').value; let description = document.getElementById('list-description-input').value; let isPrivate = document.getElementById('list-private-input').checked; try { await API.list.update(data.id_str, name, description, isPrivate); document.getElementById('list-name').classList.toggle('user-protected', isPrivate); } catch(e) { return document.getElementById('list-editor-error').innerText = e && e.message ? e.message : e; } modal.remove(); renderListData(await API.list.get(data.id_str)); }); let membersCursor; let membersContainer = document.getElementById('list-editor-members-container'); async function getMembers() { let listMembers = await API.list.getMembers(data.id_str, membersCursor); membersCursor = listMembers.cursor; listMembers = listMembers.list; if(!cursor || listMembers.length === 0) document.getElementById('list-editor-members-more').hidden = true; for(let i in listMembers) { let t = listMembers[i]; let followingElement = document.createElement('div'); followingElement.classList.add('following-item'); followingElement.innerHTML = `
${t.screen_name}
${escapeHTML(t.name)}
@${t.screen_name} ${t.followed_by ? `${LOC.follows_you.message}` : ''}
`; let removeButton = followingElement.querySelector('.following-item-btn'); removeButton.addEventListener('click', async () => { await API.list.removeMember(listId, t.id_str); document.getElementById('list-members-count').innerText = parseInt(document.getElementById('list-members-count').innerText) - 1; followingElement.remove(); }); membersContainer.appendChild(followingElement); if(vars.enableTwemoji) twemoji.parse(followingElement); } } document.getElementById('list-btn-members').addEventListener('click', async () => { document.getElementById('list-editor').hidden = true; document.getElementById('list-editor-members').hidden = false; getMembers(); }); document.getElementById('list-editor-members-more').addEventListener('click', getMembers); document.getElementById('list-editor-members-back').addEventListener('click', () => { document.getElementById('list-editor').hidden = false; document.getElementById('list-editor-members').hidden = true; }); }); document.getElementById('list-btn-delete').addEventListener('click', async () => { let modal = createModal(`

${LOC.delete_list.message}


${LOC.delete_list_sure.message}

`, 'list-editor-modal'); document.getElementById('list-btn-delete-confirm').addEventListener('click', async () => { await API.list.delete(data.id_str); modal.remove(); window.location.href = `https://twitter.com/${user.screen_name}/lists`; }); }); } else { actions.innerHTML = ``; document.getElementById('list-btn-subscribe').addEventListener('click', async () => { if(data.following) { await API.list.unsubscribe(data.id_str); document.getElementById('list-followers-count').innerText = +document.getElementById('list-followers-count').innerText - 1; data.following = false; document.getElementById('list-btn-subscribe').innerText = LOC.subscribe.message; } else { await API.list.subscribe(data.id_str); document.getElementById('list-followers-count').innerText = +document.getElementById('list-followers-count').innerText + 1; data.following = true; document.getElementById('list-btn-subscribe').innerText = LOC.unsubscribe.message; } }); } } } async function renderListTweets(c) { let [listInfo, listTweets] = await Promise.allSettled([ API.list.get(listId), API.list.getTweets(listId, c) ]).catch(e => { console.error(e); }); if(listTweets.reason) { console.error(listTweets.reason); document.getElementById('loading-box').hidden = false; document.getElementById('loading-box-error').innerHTML = `${LOC.list_not_found.message}
${LOC.go_homepage.message}`; return false; } listInfo = listInfo.value; listTweets = listTweets.value; cursor = listTweets.cursor; listTweets = listTweets.list; if(!cursor || listTweets.length === 0) end = true; renderListData(listInfo); let container = document.getElementById('list-tweets'); for(let i in listTweets) { let t = listTweets[i]; if(t.retweeted_status) { await appendTweet(t.retweeted_status, container, { top: { text: `${escapeHTML(t.user.name)} ${LOC.retweeted.message}`, icon: "\uf006", color: "#77b255", class: 'retweet-label' }, translate: vars.autotranslateProfiles.includes(t.user.id_str) }); } else { await appendTweet(t, container, { bigFont: typeof t.full_text === 'string' && t.full_text.length < 75, translate: vars.autotranslateProfiles.includes(t.user.id_str) }); } } return true; } async function renderListMembers(c) { let [listInfo, listMembers] = await Promise.allSettled([ API.list.get(listId), API.list.getMembers(listId, c) ]).catch(e => { console.error(e); }); if(listMembers.reason) { console.error(listTweets.reason); document.getElementById('loading-box').hidden = false; document.getElementById('loading-box-error').innerHTML = `${LOC.list_not_found.message}
${LOC.go_homepage.message}`; return false; } listInfo = listInfo.value; listMembers = listMembers.value; cursor = listMembers.cursor; listMembers = listMembers.list; if(!cursor || listMembers.length === 0) end = true; renderListData(listInfo); let container = document.getElementById('list-members'); for(let i in listMembers) { let t = listMembers[i]; appendUser(t, container); } return true; } async function renderListFollowers(c) { let [listInfo, listFollowers] = await Promise.allSettled([ API.list.get(listId), API.list.getFollowers(listId, c) ]).catch(e => { console.error(e); }); if(listFollowers.reason) { console.error(listTweets.reason); document.getElementById('loading-box').hidden = false; document.getElementById('loading-box-error').innerHTML = `${LOC.list_not_found.message}
${LOC.go_homepage.message}`; return false; } listInfo = listInfo.value; listFollowers = listFollowers.value; cursor = listFollowers.cursor; listFollowers = listFollowers.list; if(!cursor || listFollowers.length === 0) end = true; renderListData(listInfo); let container = document.getElementById('list-followers'); for(let i in listFollowers) { let t = listFollowers[i]; let followingElement = document.createElement('div'); followingElement.classList.add('user-item'); followingElement.innerHTML = `
${t.screen_name}
${escapeHTML(t.name)}
@${t.screen_name}
`; let followButton = followingElement.querySelector('.user-item-btn'); followButton.addEventListener('click', async () => { if (followButton.classList.contains('following')) { await API.user.unfollow(t.screen_name); followButton.classList.remove('following'); followButton.classList.add('follow'); followButton.innerText = LOC.follow.message; } else { await API.user.follow(t.screen_name); followButton.classList.remove('follow'); followButton.classList.add('following'); followButton.innerText = LOC.following.message; } }); container.appendChild(followingElement); } return true; } async function renderList() { if(subpage === 'tweets') { if(!await renderListTweets(cursor)) return; } else if(subpage === 'members') { if(!await renderListMembers(cursor)) return; } else if(subpage === 'followers') { if(!await renderListFollowers(cursor)) return; } document.getElementById('loading-box').hidden = true; return true; } let lastTweetDate = 0; let activeTweet; let loadingNewTweets = false; let end = false; setTimeout(async () => { if(!vars) { await loadVars(); } // weird bug if(!document.getElementById('wtf-refresh')) { return setTimeout(() => location.reload(), 500); } try { document.getElementById('wtf-refresh').addEventListener('click', async () => { renderDiscovery(false); }); } catch(e) { setTimeout(() => location.reload(), 500); console.error(e); return; } window.addEventListener("popstate", async () => { cursor = undefined; updateSubpage(); renderList(); }); document.addEventListener('scroll', async () => { // find active tweet by scroll amount if(Date.now() - lastTweetDate > 50) { lastTweetDate = Date.now(); let tweets = Array.from(document.getElementsByClassName('tweet')); let scrollPoint = scrollY + innerHeight/2; let newActiveTweet = tweets.find(t => scrollPoint > t.offsetTop && scrollPoint < t.offsetTop + t.offsetHeight); if(!activeTweet || (newActiveTweet && !activeTweet.className.startsWith(newActiveTweet.className))) { if(activeTweet) { activeTweet.classList.remove('tweet-active'); } if(newActiveTweet) newActiveTweet.classList.add('tweet-active'); if(vars.autoplayVideos && !document.getElementsByClassName('modal')[0]) { if(activeTweet) { let video = activeTweet.querySelector('.tweet-media > video[controls]'); if(video) { video.pause(); } } if(newActiveTweet) { let newVideo = newActiveTweet.querySelector('.tweet-media > video[controls]'); let newVideoOverlay = newActiveTweet.querySelector('.tweet-media > .tweet-media-video-overlay'); if(newVideo && !newVideo.ended) { newVideo.play(); } else if(newVideoOverlay && !newVideoOverlay.style.display) { newVideoOverlay.click(); } } } activeTweet = newActiveTweet; } } // loading new tweets if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 500 && !end) { if (loadingNewTweets) return; loadingNewTweets = true; await renderList(); setTimeout(() => { loadingNewTweets = false; }, 250); } }); document.addEventListener('clearActiveTweet', () => { if(activeTweet) { activeTweet.classList.remove('tweet-active'); } activeTweet = undefined; }); document.addEventListener('findActiveTweet', () => { let tweets = Array.from(document.getElementsByClassName('tweet')); if(activeTweet) { activeTweet.classList.remove('tweet-active'); } let scrollPoint = scrollY + innerHeight/2; activeTweet = tweets.find(t => scrollPoint > t.offsetTop && scrollPoint < t.offsetTop + t.offsetHeight); if(activeTweet) { activeTweet.classList.add('tweet-active'); } }); document.getElementById('list-members-div').addEventListener('click', () => { document.getElementById('ns-members').click(); }); document.getElementById('list-followers-div').addEventListener('click', () => { document.getElementById('ns-followers').click(); }); let listSwitches = Array.from(document.getElementsByClassName('list-switch')); listSwitches.forEach(s => { s.addEventListener('click', async () => { let id = s.id.split('-')[1]; switch(id) { case 'tweets': history.pushState({}, null, `/i/lists/${listId}`); break; case 'members': history.pushState({}, null, `/i/lists/${listId}/members`); break; case 'followers': history.pushState({}, null, `/i/lists/${listId}/followers`); break; } // document.getElementById('loading-box').hidden = false; updateSubpage(); cursor = undefined; renderList(); }); }); // Update dates every minute setInterval(() => { let tweetDates = Array.from(document.getElementsByClassName('tweet-time')); let tweetQuoteDates = Array.from(document.getElementsByClassName('tweet-time-quote')); let all = [...tweetDates, ...tweetQuoteDates]; all.forEach(date => { date.innerText = timeElapsed(+date.dataset.timestamp); }); }, 60000); // Run updateSubpage(); updateUserData(); renderDiscovery(); renderList(); setInterval(updateUserData, 60000 * 3); setInterval(() => renderDiscovery(false), 60000 * 5); }, 50);