diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 38b9359f..49607d5f 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -644,5 +644,6 @@ "nonexistent_user": { "message": "This account doesn't exist" }, "nonexistent_user_desc": { "message": "Try searching for another." }, "suspended_user": { "message": "Account suspended" }, - "suspended_user_desc": { "message": "The profile you are trying to view has been suspended." } + "suspended_user_desc": { "message": "The profile you are trying to view has been suspended." }, + "show_boring_indicators": { "message": "Show indicator in followers/following page if last tweet of person is a retweet/quote/non-existent" } } diff --git a/layouts/header/style.css b/layouts/header/style.css index 8153a442..3a42b5d7 100644 --- a/layouts/header/style.css +++ b/layouts/header/style.css @@ -2087,6 +2087,29 @@ emoji-picker { font-weight: 100; } +.user-indicator-no-status::after { + content: "\f045"; + color: #dd2b2b; + font-family: var(--icon-font); + margin-left: 5px; + font-weight: 100; +} + +.user-indicator-retweeted::after { + content: "\f152"; + color: #5c913b; + font-family: var(--icon-font); + margin-left: 5px; + font-weight: 100; +} + +.user-indicator-quoted::after { + content: "\f157"; + color: #4a9fc7; + font-family: var(--icon-font); + margin-left: 5px; + font-weight: 100; +} .tweet-media-video-overlay { position: absolute; diff --git a/layouts/profile/script.js b/layouts/profile/script.js index 8abaf551..57fd0a42 100644 --- a/layouts/profile/script.js +++ b/layouts/profile/script.js @@ -729,7 +729,17 @@ async function renderFollowing(clear = true, cursor) { if(vars.showUserFollowerCountsInLists) { label = `${formatLargeNumber(u.followers_count)} ${vars.modernUI ? LOC.followers.message : LOC.followers.message.toLowerCase()}`; } - appendUser(u, userList, label); + let usernameClass = ''; + if(!u.status) { + usernameClass = 'user-indicator-no-status'; + } else if(u.status) { + if(u.status.retweeted_status) { + usernameClass = 'user-indicator-retweeted'; + } else if(u.status.quoted_status_id_str) { + usernameClass = 'user-indicator-quoted'; + } + } + appendUser(u, userList, label, usernameClass); }); document.getElementById('loading-box').hidden = true; loadingFollowing = false; @@ -1003,7 +1013,17 @@ async function renderFollowers(clear = true, cursor) { if(vars.showUserFollowerCountsInLists) { label = `${formatLargeNumber(u.followers_count)} ${vars.modernUI ? LOC.followers.message : LOC.followers.message.toLowerCase()}`; } - appendUser(u, userList, label); + let usernameClass = ''; + if(!u.status) { + usernameClass = 'user-indicator-no-status'; + } else if(u.status) { + if(u.status.retweeted_status) { + usernameClass = 'user-indicator-retweeted'; + } else if(u.status.quoted_status_id_str) { + usernameClass = 'user-indicator-quoted'; + } + } + appendUser(u, userList, label, usernameClass); }); document.getElementById('loading-box').hidden = true; loadingFollowers = false; diff --git a/layouts/settings/index.html b/layouts/settings/index.html index d3062450..97c30017 100644 --- a/layouts/settings/index.html +++ b/layouts/settings/index.html @@ -223,6 +223,9 @@

__MSG_mobile__


__MSG_advanced_options__


+
+ +
diff --git a/layouts/settings/script.js b/layouts/settings/script.js index a26e1c8c..c069d0f5 100644 --- a/layouts/settings/script.js +++ b/layouts/settings/script.js @@ -333,6 +333,7 @@ setTimeout(async () => { let showUserFollowerCountsInLists = document.getElementById('show-user-follower-counts-in-lists'); let hideUnfollowersPage = document.getElementById('hide-unfollowers-page'); let transitionProfileBanner = document.getElementById('transition-profile-banner'); + let showBoringIndicators = document.getElementById('show-boring-indicators'); let root = document.querySelector(":root"); { @@ -733,6 +734,12 @@ setTimeout(async () => { renderTrends(false, false); }); }); + showBoringIndicators.addEventListener('change', () => { + vars.showBoringIndicators = showBoringIndicators.checked; + chrome.storage.sync.set({ + showBoringIndicators: showBoringIndicators.checked + }, () => { }); + }); hideTrends.addEventListener('change', () => { vars.hideTrends = hideTrends.checked; hideStuff(); @@ -1059,6 +1066,7 @@ setTimeout(async () => { showQuoteCount.checked = !!vars.showQuoteCount; hideUnfollowersPage.checked = !!vars.hideUnfollowersPage; transitionProfileBanner.checked = !!vars.transitionProfileBanner; + showBoringIndicators.checked = !!vars.showBoringIndicators; if(vars.customCSS) { writeCSSToDB(vars.customCSS) } diff --git a/sandbox.html b/sandbox.html index a6b42e78..a9cbfc60 100644 --- a/sandbox.html +++ b/sandbox.html @@ -20,7 +20,6 @@ return; } let data = event.data; - console.log('iframe message', data); if (data.action === 'init') { try { let animsDiv = document.getElementById('anims'); diff --git a/scripts/apis.js b/scripts/apis.js index 953d30dc..a4e38358 100644 --- a/scripts/apis.js +++ b/scripts/apis.js @@ -2169,6 +2169,52 @@ const API = { }); }, getFollowing: (id, cursor) => { + return new Promise((resolve, reject) => { + fetch(`https://${location.hostname}/i/api/1.1/friends/list.json?user_id=${id}&count=100${cursor ? `&cursor=${cursor}` : ""}`, { + headers: { + "authorization": OLDTWITTER_CONFIG.oauth_key, + "x-csrf-token": OLDTWITTER_CONFIG.csrf, + "x-twitter-auth-type": "OAuth2Session", + "content-type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + credentials: "include" + }).then(i => i.json()).then(data => { + if (data.errors && data.errors[0]) { + return reject(data.errors[0].message); + } + resolve({ + list: data.users, + cursor: data.next_cursor_str !== "0" ? data.next_cursor_str : null + }); + }).catch(e => { + reject(e); + }); + }); + }, + getFollowers: (id, cursor, count = 100) => { + return new Promise((resolve, reject) => { + fetch(`https://${location.hostname}/i/api/1.1/followers/list.json?user_id=${id}&count=${count}${cursor ? `&cursor=${cursor}` : ""}`, { + headers: { + "authorization": OLDTWITTER_CONFIG.oauth_key, + "x-csrf-token": OLDTWITTER_CONFIG.csrf, + "x-twitter-auth-type": "OAuth2Session", + "content-type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + credentials: "include" + }).then(i => i.json()).then(data => { + if (data.errors && data.errors[0]) { + return reject(data.errors[0].message); + } + resolve({ + list: data.users, + cursor: data.next_cursor_str !== "0" ? data.next_cursor_str : null + }); + }).catch(e => { + reject(e); + }); + }); + }, + getFollowingV2: (id, cursor) => { return new Promise((resolve, reject) => { let obj = { "userId": id, @@ -2185,7 +2231,7 @@ const API = { }, credentials: "include" }).then(i => i.json()).then(data => { - debugLog('user.getFollowing', 'start', {id, cursor, data}); + debugLog('user.getFollowingV2', 'start', {id, cursor, data}); if (data.errors && data.errors[0].code === 32) { return reject("Not logged in"); } @@ -2206,14 +2252,14 @@ const API = { }).filter(e => e), cursor: list.find(e => e.entryId.startsWith('cursor-bottom-')).content.value } - debugLog('user.getFollowing', 'end', out); + debugLog('user.getFollowingV2', 'end', out); resolve(out); }).catch(e => { reject(e); }); }); }, - getFollowers: (id, cursor, count = 100) => { + getFollowersV2: (id, cursor, count = 100) => { return new Promise((resolve, reject) => { let obj = { "userId": id, @@ -2247,7 +2293,7 @@ const API = { }, credentials: "include" }).then(i => i.json()).then(data => { - debugLog('user.getFollowers', 'start', {id, cursor, data}); + debugLog('user.getFollowersV2', 'start', {id, cursor, data}); if (data.errors && data.errors[0].code === 32) { return reject("Not logged in"); } @@ -2267,7 +2313,7 @@ const API = { }), cursor: list.find(e => e.entryId.startsWith('cursor-bottom-')).content.value }; - debugLog('user.getFollowers', 'end', out); + debugLog('user.getFollowersV2', 'end', out); resolve(out); }).catch(e => { reject(e); diff --git a/scripts/config.js b/scripts/config.js index 2b6e83ee..a7a561f5 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -32,7 +32,8 @@ async function loadVars() { 'acknowledgedCustomizationButton', 'modernUI', 'showExactValues', 'hideTimelineTypes', 'autotranslateLanguages', 'autotranslationMode', 'muteVideos', 'dontPauseVideos', 'showUserPreviewsOnMobile', 'systemDarkMode', 'localizeDigit', 'disableRetweetHotkey', 'disableLikeHotkey', 'disableFindHotkey', 'extensionCompatibilityMode', 'disableDataSaver', 'disableAcceptType', - 'showUserFollowerCountsInLists', 'showQuoteCount', 'hideUnfollowersPage', 'transitionProfileBanner', 'customDownloadTemplate' + 'showUserFollowerCountsInLists', 'showQuoteCount', 'hideUnfollowersPage', 'transitionProfileBanner', 'customDownloadTemplate', + 'showBoringIndicators' ], data => { // default variables if(typeof(data.linkColorsInTL) !== 'boolean') { diff --git a/scripts/helpers.js b/scripts/helpers.js index 2e601a66..842de21b 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -1500,7 +1500,7 @@ function renderMedia(t) { return _html; } -async function appendUser(u, container, label) { +async function appendUser(u, container, label, usernameClass = '') { let userElement = document.createElement('div'); userElement.classList.add('user-item'); if(vars.twitterBlueCheckmarks && u.ext && u.ext.isBlueVerified && u.ext.isBlueVerified.r && u.ext.isBlueVerified.r.ok) { @@ -1518,7 +1518,7 @@ async function appendUser(u, container, label) { ${u.screen_name}
- ${escapeHTML(u.name)}
+ ${escapeHTML(u.name)}
@${u.screen_name} ${u.followed_by ? `${LOC.follows_you.message}` : ''} ${label ? `
${escapeHTML(label)}` : ''} diff --git a/scripts/twchallenge.js b/scripts/twchallenge.js index 8c399e93..7a554855 100644 --- a/scripts/twchallenge.js +++ b/scripts/twchallenge.js @@ -33,7 +33,6 @@ function solveChallenge(path, method) { solveQueue.push({ id, path, method }) } else { try { - console.log("sending challenge to solver", solverIframe.contentWindow, path); solverIframe.contentWindow.postMessage({ action: 'solve', id, path, method }, '*'); } catch(e) { console.error(`Error sending challenge to solver:`, e);