Thread viewer for Bluesky

refactoring

Changed files
+41 -36
+21 -36
like_stats_page.js
··· 56 56 let fetchGivenLikes = this.fetchGivenLikes(requestedDays); 57 57 58 58 let receivedLikes = await this.fetchReceivedLikes(requestedDays); 59 + let received = countElementsBy(receivedLikes, (x) => x.actor.handle); 59 60 60 - let received = {}; 61 + await this.renderResults(received, this.receivedTable); 61 62 62 - for (let like of receivedLikes) { 63 - received[like.actor.handle] = received[like.actor.handle] || 0; 64 - received[like.actor.handle] += 1; 65 - } 63 + let givenLikes = await fetchGivenLikes; 64 + let given = countElementsBy(givenLikes, (x) => atURI(x.value.subject.uri).repo); 66 65 67 - Object.entries(received).sort(this.sortResults).slice(0, 20).forEach(([h, i]) => { 68 - let tr = $tag('tr'); 69 - tr.append( 70 - $tag('td', { html: `<a href="https://bsky.app/profile/${h}" target="_blank">${h}</a>` }), 71 - $tag('td', { text: i }) 72 - ); 73 - this.receivedTable.append(tr); 74 - }); 66 + await this.renderResults(given, this.givenTable); 75 67 76 68 this.receivedTable.style.display = 'table'; 77 - 78 - let givenLikes = await fetchGivenLikes; 79 - 80 - let given = {}; 81 - 82 - for (let like of givenLikes) { 83 - let did = like.value.subject.uri.split('/')[2]; 84 - given[did] = given[did] || 0; 85 - given[did] += 1; 86 - } 87 - 88 - let entries = Object.entries(given).sort(this.sortResults).slice(0, 20); 89 - 90 - for (let [d, i] of entries) { 91 - let h = await accountAPI.fetchHandleForDid(d); 92 - let tr = $tag('tr'); 93 - tr.append( 94 - $tag('td', { html: `<a href="https://bsky.app/profile/${h}" target="_blank">${h}</a>` }), 95 - $tag('td', { text: i }) 96 - ); 97 - this.givenTable.append(tr); 98 - }; 99 - 100 69 this.givenTable.style.display = 'table'; 101 70 } 102 71 ··· 123 92 124 93 let results = await Promise.all(fetchPostLikes); 125 94 return results.flat(); 95 + } 96 + 97 + async renderResults(counts, table) { 98 + let entries = Object.entries(counts).sort(this.sortResults).slice(0, 20); 99 + 100 + for (let [user, count] of entries) { 101 + let handle = user.startsWith('did:') ? await accountAPI.fetchHandleForDid(user) : user; 102 + 103 + let tr = $tag('tr'); 104 + tr.append( 105 + $tag('td', { html: `<a href="https://bsky.app/profile/${handle}" target="_blank">${handle}</a>` }), 106 + $tag('td', { text: count }) 107 + ); 108 + 109 + table.append(tr); 110 + }; 126 111 } 127 112 128 113 sortResults(a, b) {
+20
utils.js
··· 150 150 url.searchParams.set('post', postId); 151 151 return url.toString(); 152 152 } 153 + 154 + /** 155 + * @template T 156 + * @param {T[]} list 157 + * @param {(T) => string} prop 158 + * @returns {Record<string, number>} 159 + */ 160 + 161 + function countElementsBy(list, prop) { 162 + /** @type {Record<string, number>} */ 163 + let counts = {}; 164 + 165 + for (let obj of list) { 166 + let value = prop(obj); 167 + counts[value] = counts[value] || 0; 168 + counts[value] += 1; 169 + } 170 + 171 + return counts; 172 + }