+41
-68
posting_stats_page.js
+41
-68
posting_stats_page.js
···
18
18
this.submitButton = $(this.pageElement.querySelector('input[type="submit"]'), HTMLInputElement);
19
19
this.progressBar = $(this.pageElement.querySelector('input[type=submit] + progress'), HTMLProgressElement);
20
20
this.table = $(this.pageElement.querySelector('table.scan-result'));
21
+
this.tableHead = $(this.table.querySelector('thead'));
22
+
this.tableBody = $(this.table.querySelector('tbody'));
23
+
this.listSelect = $(this.pageElement.querySelector('.list-choice select'), HTMLSelectElement);
24
+
this.scanInfo = $(this.pageElement.querySelector('.scan-info'));
25
+
this.scanType = this.form.elements['scan_type'];
21
26
22
27
this.setupEvents();
23
28
···
26
31
}
27
32
28
33
setupEvents() {
29
-
$(this.pageElement.querySelector('form')).addEventListener('submit', (e) => {
34
+
this.form.addEventListener('submit', (e) => {
30
35
e.preventDefault();
31
36
32
37
if (!this.scanStartTime) {
···
38
43
39
44
this.rangeInput.addEventListener('input', (e) => {
40
45
let days = parseInt(this.rangeInput.value, 10);
41
-
this.configurePostingStats({ days });
46
+
let label = $(this.pageElement.querySelector('input[type=range] + label'));
47
+
label.innerText = (days == 1) ? '1 day' : `${days} days`;
42
48
});
43
49
44
-
this.pageElement.querySelectorAll('input[type="radio"]').forEach(r => {
50
+
this.scanType.forEach(r => {
45
51
r.addEventListener('click', (e) => {
46
52
let value = $(r, HTMLInputElement).value;
47
53
···
67
73
/** @returns {Promise<void>} */
68
74
69
75
async fetchLists() {
70
-
let select = $(this.pageElement.querySelector('.list-choice select'));
71
76
let lists = await accountAPI.loadUserLists();
72
77
73
78
let sorted = lists.sort((a, b) => {
···
78
83
});
79
84
80
85
for (let list of lists) {
81
-
let opt = $tag('option', { value: list.uri, text: list.name + ' ' });
82
-
select.append(opt);
83
-
}
84
-
}
85
-
86
-
/** @param {{ days: number }} args */
87
-
88
-
configurePostingStats(args) {
89
-
if (args.days) {
90
-
let label = $(this.pageElement.querySelector('input[type=range] + label'));
91
-
label.innerText = (args.days == 1) ? '1 day' : `${args.days} days`;
86
+
this.listSelect.append(
87
+
$tag('option', { value: list.uri, text: list.name + ' ' })
88
+
);
92
89
}
93
90
}
94
91
95
92
/** @returns {Promise<void>} */
96
93
97
94
async scanPostingStats() {
98
-
this.submitButton.value = 'Cancel';
99
-
95
+
let startTime = new Date().getTime();
100
96
let requestedDays = this.selectedDaysRange();
101
-
102
-
this.progressBar.max = requestedDays;
103
-
this.progressBar.value = 0;
104
-
this.progressBar.style.display = 'inline';
105
-
106
-
this.table.style.display = 'none';
97
+
let scanType = this.scanType.value;
107
98
108
-
let tbody = $(this.table.querySelector('tbody'));
109
-
tbody.innerHTML = '';
110
-
111
-
let thead = $(this.table.querySelector('thead'));
112
-
thead.innerHTML = '';
113
-
114
-
let startTime = new Date().getTime();
115
-
this.scanStartTime = startTime;
116
-
117
-
let scanInfo = $(this.pageElement.querySelector('.scan-info'));
118
-
scanInfo.style.display = 'none';
99
+
this.startScan(startTime, requestedDays);
119
100
120
101
/** @type {FetchAllOnPageLoad} */
121
102
let onPageLoad = (data) => {
···
126
107
this.updateProgress(data, startTime);
127
108
};
128
109
129
-
let scanType = this.form.elements['scan_type'].value;
130
-
131
110
if (scanType == 'home') {
132
111
let items = await accountAPI.loadHomeTimeline(requestedDays, {
133
112
onPageLoad: onPageLoad,
134
113
keepLastPage: true
135
114
});
136
-
137
-
if (this.scanStartTime != startTime) {
138
-
return;
139
-
}
140
115
141
116
this.updateResultsTable(items, startTime, requestedDays);
142
117
} else if (scanType == 'list') {
143
-
let select = $(this.pageElement.querySelector('.list-choice select'), HTMLSelectElement);
144
-
let list = select.value;
118
+
let list = this.listSelect.value;
145
119
let items = await accountAPI.loadListTimeline(list, requestedDays, {
146
120
onPageLoad: onPageLoad,
147
121
keepLastPage: true
148
122
});
149
-
150
-
if (this.scanStartTime != startTime) {
151
-
return;
152
-
}
153
123
154
124
this.updateResultsTable(items, startTime, requestedDays, { showReposts: false });
155
125
} else if (scanType == 'users') {
···
172
142
}));
173
143
174
144
let datasets = await Promise.all(requests);
175
-
176
-
if (this.scanStartTime != startTime) {
177
-
return;
178
-
}
179
-
180
145
let items = datasets.flat();
181
146
182
147
this.updateResultsTable(items, startTime, requestedDays, {
···
189
154
keepLastPage: true
190
155
});
191
156
192
-
if (this.scanStartTime != startTime) {
193
-
return;
194
-
}
195
-
196
157
this.updateResultsTable(items, startTime, requestedDays, { showTotal: false, showPercentages: false });
197
158
}
198
159
}
···
209
170
210
171
this.progressBar.value = daysBack;
211
172
}
212
-
213
173
214
174
/** @param {string[]} dids */
215
175
···
265
225
*/
266
226
267
227
updateResultsTable(items, startTime, requestedDays, options = {}) {
228
+
if (this.scanStartTime != startTime) {
229
+
return;
230
+
}
231
+
268
232
let users = {};
269
233
let total = 0;
270
234
let allReposts = 0;
···
284
248
let fetchedDays = (startTime - lastDate) / 86400 / 1000;
285
249
286
250
if (Math.ceil(fetchedDays) < requestedDays) {
287
-
let scanInfo = $(this.pageElement.querySelector('.scan-info'));
288
-
scanInfo.innerText = `🕓 Showing data from ${Math.round(fetchedDays)} days (the timeline only goes that far):`;
289
-
scanInfo.style.display = 'block';
251
+
this.scanInfo.innerText = `🕓 Showing data from ${Math.round(fetchedDays)} days (the timeline only goes that far):`;
252
+
this.scanInfo.style.display = 'block';
290
253
}
291
254
292
255
daysBack = Math.min(requestedDays, fetchedDays);
···
314
277
}
315
278
}
316
279
317
-
let thead = $(this.table.querySelector('thead'));
318
280
let headRow = $tag('tr');
319
281
320
282
if (options.showReposts !== false) {
···
337
299
headRow.append($tag('th', { text: '% of all' }));
338
300
}
339
301
340
-
thead.append(headRow);
341
-
342
-
let tbody = $(this.table.querySelector('tbody'));
302
+
this.tableHead.append(headRow);
343
303
344
304
if (options.showTotal !== false) {
345
305
let tr = $tag('tr.total');
···
361
321
tr.append($tag('td.percent', { text: '' }));
362
322
}
363
323
364
-
tbody.append(tr);
324
+
this.tableBody.append(tr);
365
325
}
366
326
367
327
let sorted = Object.values(users).sort(this.sortUserRows);
···
390
350
tr.append($tag('td.percent', { text: ((user.own + user.reposts) * 100 / total).toFixed(1) + '%' }));
391
351
}
392
352
393
-
tbody.append(tr);
353
+
this.tableBody.append(tr);
394
354
}
395
355
396
356
this.table.style.display = 'table';
397
-
this.submitButton.value = 'Start scan';
398
-
this.progressBar.style.display = 'none';
399
-
this.scanStartTime = undefined;
357
+
this.stopScan();
358
+
}
359
+
360
+
startScan(startTime, requestedDays) {
361
+
this.submitButton.value = 'Cancel';
362
+
363
+
this.progressBar.max = requestedDays;
364
+
this.progressBar.value = 0;
365
+
this.progressBar.style.display = 'inline';
366
+
367
+
this.table.style.display = 'none';
368
+
this.tableHead.innerHTML = '';
369
+
this.tableBody.innerHTML = '';
370
+
371
+
this.scanStartTime = startTime;
372
+
this.scanInfo.style.display = 'none';
400
373
}
401
374
402
375
stopScan() {