Extension to return old Twitter layout from 2015.
1let user = {};
2let bookmarkCursor = null;
3let end = false;
4let linkColors = {};
5let activeTweet;
6
7function updateUserData() {
8 API.account.verifyCredentials().then(async u => {
9 user = u;
10 userDataFunction(u);
11 renderUserData();
12 }).catch(e => {
13 if (e === "Not logged in") {
14 window.location.href = "https://twitter.com/i/flow/login?newtwitter=true";
15 }
16 console.error(e);
17 });
18}
19// Render
20function renderUserData() {
21 document.getElementById('user-name').innerText = user.name;
22 document.getElementById('user-name').classList.toggle('user-verified', user.verified);
23 document.getElementById('user-name').classList.toggle('user-protected', user.protected);
24
25 document.getElementById('user-handle').innerText = `@${user.screen_name}`;
26 document.getElementById('user-tweets').innerText = Number(user.statuses_count).toLocaleString().replace(/\s/g, ',');
27 if(user.statuses_count >= 100000) {
28 let style = document.createElement('style');
29 style.innerText = `
30 .user-stat-div > h1 { font-size: 18px !important }
31 .user-stat-div > h2 { font-size: 13px !important }
32 `;
33 document.head.appendChild(style);
34 }
35 document.getElementById('user-following').innerText = Number(user.friends_count).toLocaleString().replace(/\s/g, ',');
36 document.getElementById('user-followers').innerText = Number(user.followers_count).toLocaleString().replace(/\s/g, ',');
37 document.getElementById('user-banner').src = user.profile_banner_url;
38 document.getElementById('user-avatar').src = `${(user.default_profile_image && vars.useOldDefaultProfileImage) ? chrome.runtime.getURL(`images/default_profile_images/default_profile_${Number(user.id_str) % 7}_normal.png`): user.profile_image_url_https}`.replace('_normal.', '_400x400.');
39 document.getElementById('wtf-viewall').href = `https://twitter.com/i/connect_people?newtwitter=true&user_id=${user.id_str}`;
40 document.getElementById('user-avatar-link').href = `https://twitter.com/${user.screen_name}`;
41 document.getElementById('user-info').href = `https://twitter.com/${user.screen_name}`;
42
43 if(vars.enableTwemoji) twemoji.parse(document.getElementById('user-name'));
44
45 if(document.getElementById('user-stats').clientWidth > 300) {
46 let style = document.createElement('style');
47 style.innerHTML = `.user-stat-div > h2 { font-size: 10px !important }`;
48 document.head.appendChild(style);
49 }
50}
51
52async function renderBookmarks(cursor) {
53 let bookmarks;
54 let bookmarksContainer = document.getElementById('timeline');
55 try {
56 bookmarks = await API.bookmarks.get(cursor);
57 } catch(e) {
58 console.error(e);
59 bookmarksContainer.innerHTML = `<div style="color:var(--light-gray)">${e}</div>`;
60 document.getElementById('loading-box').hidden = true;
61 return;
62 }
63
64 if (bookmarks.cursor) {
65 bookmarkCursor = bookmarks.cursor;
66 } else {
67 end = true;
68 }
69 bookmarks = bookmarks.list;
70 if(bookmarks.length === 0 && !cursor) {
71 bookmarksContainer.innerHTML = `<div style="color:var(--light-gray)">${LOC.empty.message}</div>`;
72 document.getElementById('delete-all').hidden = true;
73 return;
74 }
75 if(bookmarks.length === 0 && cursor) {
76 end = true;
77 return;
78 }
79 for (let i = 0; i < bookmarks.length; i++) {
80 let b = bookmarks[i];
81 await appendTweet(b, bookmarksContainer, {
82 bigFont: b.full_text && b.full_text.length < 75
83 });
84 }
85 document.getElementById('loading-box').hidden = true;
86
87}
88let lastScroll = Date.now();
89let loadingNewTweets = false;
90let lastTweetDate = 0;
91
92setTimeout(async () => {
93 if(!vars) {
94 await loadVars();
95 }
96
97 // weird bug
98 try {
99 document.getElementById('wtf-refresh').addEventListener('click', async () => {
100 renderDiscovery(false);
101 });
102 } catch(e) {
103 setTimeout(() => location.reload(), 500);
104 console.error(e);
105 return;
106 }
107 document.addEventListener('scroll', async () => {
108 lastScroll = Date.now();
109 // find active tweet by scroll amount
110 if(Date.now() - lastTweetDate > 50) {
111 lastTweetDate = Date.now();
112 let tweets = Array.from(document.getElementsByClassName('tweet'));
113
114 let scrollPoint = scrollY + innerHeight/2;
115 let newActiveTweet = tweets.find(t => scrollPoint > t.offsetTop && scrollPoint < t.offsetTop + t.offsetHeight);
116 if(!activeTweet || (newActiveTweet && !activeTweet.className.startsWith(newActiveTweet.className))) {
117 if(activeTweet) {
118 activeTweet.classList.remove('tweet-active');
119 }
120 if(newActiveTweet) newActiveTweet.classList.add('tweet-active');
121 if(vars.autoplayVideos && !document.getElementsByClassName('modal')[0]) {
122 if(activeTweet) {
123 let video = activeTweet.querySelector('.tweet-media > video[controls]');
124 if(video) {
125 video.pause();
126 }
127 }
128 if(newActiveTweet) {
129 let newVideo = newActiveTweet.querySelector('.tweet-media > video[controls]');
130 let newVideoOverlay = newActiveTweet.querySelector('.tweet-media > .tweet-media-video-overlay');
131 if(newVideo && !newVideo.ended) {
132 newVideo.play();
133 } else if(newVideoOverlay && !newVideoOverlay.style.display) {
134 newVideoOverlay.click();
135 }
136 }
137 }
138 activeTweet = newActiveTweet;
139 }
140 }
141
142 // loading new tweets
143 if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 500 && !end) {
144 if (loadingNewTweets) return;
145 loadingNewTweets = true;
146 await renderBookmarks(bookmarkCursor);
147 setTimeout(() => {
148 loadingNewTweets = false;
149 }, 250);
150 }
151 }, { passive: true });
152 document.getElementById('delete-all').addEventListener('click', async () => {
153 let modal = createModal(`
154 <p style="color:var(--almost-black);margin-top:0">${LOC.delete_bookmarks.message}</p>
155 <button class="nice-button" id="delete-all-confirm">${LOC.delete_all.message}</button>
156 `);
157 modal.getElementsByClassName('nice-button')[0].addEventListener('click', () => {
158 API.bookmarks.deleteAll().then(() => {
159 document.getElementById('timeline').innerHTML = `<div style="color:var(--light-gray)">${LOC.empty.message}</div>`;
160 document.getElementById('delete-all').hidden = true;
161 modal.remove();
162 });
163 });
164 });
165
166
167 // Run
168 updateUserData();
169 renderDiscovery();
170 renderTrends();
171 renderBookmarks();
172 setInterval(updateUserData, 60000 * 3);
173 setInterval(() => renderDiscovery(false), 60000 * 15);
174 setInterval(renderTrends, 60000 * 5);
175}, 50);