+1
-1
index.html
+1
-1
index.html
+67
-2
like_stats_page.js
+67
-2
like_stats_page.js
···
8
8
9
9
this.rangeInput = $(this.pageElement.querySelector('input[type="range"]'), HTMLInputElement);
10
10
this.submitButton = $(this.pageElement.querySelector('input[type="submit"]'), HTMLInputElement);
11
+
this.progressBar = $(this.pageElement.querySelector('input[type=submit] + progress'), HTMLProgressElement);
11
12
12
13
this.receivedTable = $(this.pageElement.querySelector('.received-likes'));
13
14
this.givenTable = $(this.pageElement.querySelector('.given-likes'));
···
50
51
51
52
let requestedDays = this.selectedDaysRange();
52
53
54
+
this.resetProgress();
55
+
this.progressBar.style.display = 'inline';
56
+
53
57
let startTime = new Date().getTime();
54
58
this.scanStartTime = startTime;
59
+
60
+
this.receivedTable.style.display = 'none';
61
+
this.givenTable.style.display = 'none';
55
62
56
63
let fetchGivenLikes = this.fetchGivenLikes(requestedDays);
57
64
···
67
74
68
75
this.receivedTable.style.display = 'table';
69
76
this.givenTable.style.display = 'table';
77
+
78
+
this.submitButton.value = 'Start scan';
79
+
this.progressBar.style.display = 'none';
80
+
this.scanStartTime = undefined;
70
81
}
71
82
72
83
async fetchGivenLikes(requestedDays) {
···
78
89
limit: 100
79
90
}, {
80
91
field: 'records',
81
-
breakWhen: (x) => Date.parse(x['value']['createdAt']) < now - 86400 * requestedDays * 1000
92
+
breakWhen: (x) => Date.parse(x['value']['createdAt']) < now - 86400 * requestedDays * 1000,
93
+
onPageLoad: (data) => {
94
+
if (data.length == 0) { return }
95
+
96
+
let last = data[data.length - 1];
97
+
let lastDate = Date.parse(last.value.createdAt);
98
+
99
+
let daysBack = (this.scanStartTime - lastDate) / 86400 / 1000;
100
+
this.updateProgress({ likeRecords: Math.min(1.0, daysBack / requestedDays) });
101
+
}
82
102
});
83
103
}
84
104
85
105
async fetchReceivedLikes(requestedDays) {
86
-
let myPosts = await this.appView.loadUserTimeline(accountAPI.user.did, requestedDays);
106
+
let myPosts = await this.appView.loadUserTimeline(accountAPI.user.did, requestedDays, {
107
+
onPageLoad: (data) => {
108
+
if (data.length == 0) { return }
109
+
110
+
let last = data[data.length - 1];
111
+
let lastTimestamp = last.reason ? last.reason.indexedAt : last.post.record.createdAt;
112
+
let lastDate = Date.parse(lastTimestamp);
113
+
114
+
let daysBack = (this.scanStartTime - lastDate) / 86400 / 1000;
115
+
this.updateProgress({ posts: Math.min(1.0, daysBack / requestedDays) });
116
+
}
117
+
});
118
+
87
119
let likedPosts = myPosts.filter(x => !x['reason'] && x['post']['likeCount'] > 0);
88
120
89
121
let results = [];
90
122
91
123
for (let i = 0; i < likedPosts.length; i += 10) {
92
124
let batch = likedPosts.slice(i, i + 10);
125
+
this.updateProgress({ postLikes: i / likedPosts.length });
93
126
94
127
let fetchBatch = batch.map(x => {
95
128
return this.appView.fetchAll('app.bsky.feed.getLikes', { uri: x['post']['uri'], limit: 100 }, {
···
100
133
let batchResults = await Promise.all(fetchBatch);
101
134
results = results.concat(batchResults);
102
135
}
136
+
137
+
this.updateProgress({ postLikes: 1.0 });
103
138
104
139
return results.flat();
105
140
}
···
120
155
};
121
156
}
122
157
158
+
resetProgress() {
159
+
this.progressBar.value = 0;
160
+
this.progressPosts = 0;
161
+
this.progressLikeRecords = 0;
162
+
this.progressPostLikes = 0;
163
+
}
164
+
165
+
updateProgress(data) {
166
+
if (data.posts) {
167
+
this.progressPosts = data.posts;
168
+
}
169
+
170
+
if (data.likeRecords) {
171
+
this.progressLikeRecords = data.likeRecords;
172
+
}
173
+
174
+
if (data.postLikes) {
175
+
this.progressPostLikes = data.postLikes;
176
+
}
177
+
178
+
let totalProgress = (
179
+
0.1 * this.progressPosts +
180
+
0.65 * this.progressLikeRecords +
181
+
0.25 * this.progressPostLikes
182
+
);
183
+
184
+
this.progressBar.value = totalProgress;
185
+
}
186
+
123
187
sortResults(a, b) {
124
188
if (a[1] < b[1]) {
125
189
return 1;
···
132
196
133
197
stopScan() {
134
198
this.submitButton.value = 'Start scan';
199
+
this.progressBar.style.display = 'none';
135
200
this.scanStartTime = undefined;
136
201
}
137
202
}
+35
-28
style.css
+35
-28
style.css
···
732
732
margin-top: 25px;
733
733
}
734
734
735
-
#like_stats_page {
736
-
display: none;
737
-
}
738
-
739
-
#like_stats_page input[type="range"] {
740
-
width: 250px;
741
-
vertical-align: middle;
742
-
}
743
-
744
-
#like_stats_page .scan-result {
745
-
border: 1px solid #333;
746
-
border-collapse: collapse;
747
-
display: none;
748
-
float: left;
749
-
margin-right: 100px;
750
-
}
751
-
752
-
#like_stats_page .scan-result td, #like_stats_page .scan-result th {
753
-
border: 1px solid #333;
754
-
padding: 5px 8px;
755
-
}
756
-
757
-
#like_stats_page .scan-result th {
758
-
text-align: center;
759
-
background-color: hsl(207, 100%, 86%);
760
-
padding: 7px 10px;
761
-
}
762
-
763
735
#posting_stats_page {
764
736
display: none;
765
737
}
···
857
829
858
830
#posting_stats_page .scan-result td.percent {
859
831
min-width: 70px;
832
+
}
833
+
834
+
#like_stats_page {
835
+
display: none;
836
+
}
837
+
838
+
#like_stats_page input[type="range"] {
839
+
width: 250px;
840
+
vertical-align: middle;
841
+
}
842
+
843
+
#like_stats_page progress {
844
+
width: 300px;
845
+
margin-left: 10px;
846
+
vertical-align: middle;
847
+
display: none;
848
+
}
849
+
850
+
#like_stats_page .scan-result {
851
+
border: 1px solid #333;
852
+
border-collapse: collapse;
853
+
display: none;
854
+
float: left;
855
+
margin-right: 100px;
856
+
}
857
+
858
+
#like_stats_page .scan-result td, #like_stats_page .scan-result th {
859
+
border: 1px solid #333;
860
+
padding: 5px 8px;
861
+
}
862
+
863
+
#like_stats_page .scan-result th {
864
+
text-align: center;
865
+
background-color: hsl(207, 100%, 86%);
866
+
padding: 7px 10px;
860
867
}
861
868
862
869
@media (prefers-color-scheme: dark) {