Skip to content

Commit 2db1024

Browse files
committed
update UI
1 parent 9b463e7 commit 2db1024

File tree

3 files changed

+111
-83
lines changed

3 files changed

+111
-83
lines changed

scripts/content-scripts/ufs_global.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// TODO: split this file into multiple helper files
2+
13
export const UfsGlobal = {
24
Extension: {
35
sendToContentScript,

scripts/tiktok_batchDownload.js

Lines changed: 84 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export default {
7575
<style>
7676
#${id} {
7777
position: fixed;
78-
z-index: 99999999999;
78+
z-index: 16777269;
7979
}
8080
#${floatingBtnId} {
8181
border-radius: 25px;
@@ -114,18 +114,28 @@ export default {
114114
display: flex;
115115
flex-direction: column;
116116
}
117+
.ufs_popup .table_wrap {
118+
overflow: auto;
119+
}
120+
.ufs_popup table {
121+
width: 100%;
122+
}
117123
.ufs_popup table, .ufs_popup th, .ufs_popup td {
118124
border: 1px solid #aaa;
119125
border-collapse: collapse;
120126
}
121127
.ufs_popup table td {
122128
padding: 10px;
123129
}
124-
.ufs_popup table th {
130+
.ufs_popup table thead {
125131
position: sticky;
126-
top: -22px;
132+
top: -2px;
127133
background: #333;
128134
}
135+
.ufs_popup th[data-sort]:hover {
136+
cursor: pointer;
137+
background: #555;
138+
}
129139
.ufs_popup input {
130140
padding: 5px;
131141
}
@@ -170,45 +180,78 @@ export default {
170180
return willShow;
171181
}
172182

183+
const formatter = UfsGlobal.Utils.getNumberFormatter("compactShort");
184+
173185
function renderData() {
174186
container.innerHTML = /*html*/ `
175187
<div class="ufs_popup">
176188
<h1 style="text-align:center">Tiktok - Useful Scripts</h1>
177189
<h2 style="text-align:center">Found ${CACHED.videoById.size} videos</h2>
178190
179-
<div style="align-self: flex-end;">
191+
<div style="align-self: flex-end;padding: 10px;">
180192
<button id="video">🎬 Download video</button>
181193
<button id="audio">🎧 Download audio</button>
182194
<button id="json">📄 Download json</button>
183195
<button id="clear">🗑️ Clear all</button>
184196
<input type="text" id="search" placeholder="🔎 Search..." >
185197
</div>
186198
187-
<table>
188-
<thead>
189-
<tr>
190-
<th data-sort="index">#</th>
191-
<th>🎬 Video</th>
192-
<th data-sort="title">Title</th>
193-
<th data-sort="user">👤 User</th>
194-
<th data-sort="view">👀 View</th>
195-
<th data-sort="length">🕒 Length</th>
196-
<th>Download</th>
197-
</tr>
198-
</thead>
199-
<tbody>
200-
</tbody>
201-
</table>
199+
<div class="table_wrap">
200+
<table>
201+
<thead>
202+
<tr>
203+
<th data-sort="index">#</th>
204+
<th>🎬 Video</th>
205+
<th data-sort="title">Title</th>
206+
<th data-sort="user">👤 User</th>
207+
<th data-sort="view">👀 View</th>
208+
<th data-sort="length">🕒 Length</th>
209+
<th>Download</th>
210+
</tr>
211+
</thead>
212+
<tbody>
213+
</tbody>
214+
</table>
215+
</div>
202216
</div>`;
203217

204218
const tbody = container.querySelector("tbody");
205219

206220
// render initial data
207-
let data = Array.from(CACHED.videoById.values()).map((_, index) => ({
208-
..._,
209-
index,
210-
}));
211-
renderTable(tbody, data);
221+
let allVideoData = Array.from(CACHED.videoById.values()).map(
222+
(_, i) => ({
223+
..._,
224+
index: i + 1,
225+
})
226+
);
227+
renderTable(tbody, allVideoData);
228+
229+
// search
230+
const hiddenVideos = new Set();
231+
const searchInp = container.querySelector("#search");
232+
searchInp.addEventListener("input", (event) => {
233+
const value = event.target.value;
234+
let trs = tbody.querySelectorAll("tr");
235+
for (const tr of trs) {
236+
const tds = tr.querySelectorAll("td");
237+
let found = false;
238+
for (const td of tds) {
239+
if (td.textContent.toLowerCase().includes(value)) {
240+
found = true;
241+
break;
242+
}
243+
}
244+
tr.style.display = found ? "" : "none";
245+
246+
let videoId = tr.getAttribute("data-video-id");
247+
if (found) hiddenVideos.delete(videoId);
248+
else hiddenVideos.add(videoId);
249+
}
250+
});
251+
252+
function getShowingVideos() {
253+
return allVideoData.filter((_) => !hiddenVideos.has(_.video.id));
254+
}
212255

213256
// btn
214257
const clearBtn = container.querySelector("button#clear");
@@ -223,7 +266,7 @@ export default {
223266
downVideoBtn.addEventListener("click", () => {
224267
download(
225268
"video/mp4",
226-
data.map((_, i) => {
269+
getShowingVideos().map((_, i) => {
227270
const urlList =
228271
_.video?.bitrateInfo?.find?.(
229272
(b) => b.Bitrate === _.video.bitrate
@@ -248,7 +291,7 @@ export default {
248291
const downAudioBtn = container.querySelector("button#audio");
249292
downAudioBtn.addEventListener("click", () => {
250293
const uniqueMusic = new Map();
251-
for (const item of data) {
294+
for (const item of getShowingVideos()) {
252295
if (!uniqueMusic.has(item.music.id))
253296
uniqueMusic.set(item.music.id, item);
254297
}
@@ -271,76 +314,57 @@ export default {
271314
const downJsonBtn = container.querySelector("button#json");
272315
downJsonBtn.addEventListener("click", () => {
273316
UfsGlobal.Utils.downloadData(
274-
JSON.stringify(data, null, 4),
317+
JSON.stringify(getShowingVideos(), null, 4),
275318
"tiktok.json"
276319
);
277320
});
278321

279-
// search
280-
const searchInp = container.querySelector("#search");
281-
searchInp.addEventListener("input", (event) => {
282-
const value = event.target.value;
283-
let trs = tbody.querySelectorAll("tr");
284-
for (const tr of trs) {
285-
const tds = tr.querySelectorAll("td");
286-
let found = false;
287-
for (const td of tds) {
288-
if (td.textContent.toLowerCase().includes(value)) {
289-
found = true;
290-
break;
291-
}
292-
}
293-
tr.style.display = found ? "" : "none";
294-
}
295-
});
296-
297322
// sorting
298323
const sorting = {};
299324
const ths = container.querySelectorAll("th");
300325
for (const th of ths) {
301326
const sort = th.getAttribute("data-sort");
302-
// if (!sort) return;
303-
th.style.cursor = "pointer";
327+
if (!sort) continue;
304328
th.title = "Sort";
305329

306330
th.addEventListener("click", () => {
307331
sorting[sort] = sorting[sort] == 1 ? -1 : 1;
308332
switch (sort) {
309333
case "index":
310-
data = data.sort((a, b) =>
334+
allVideoData = allVideoData.sort((a, b) =>
311335
sorting[sort] == -1 ? a.index - b.index : b.index - a.index
312336
);
313337
break;
314338
case "title":
315-
data = data.sort((a, b) =>
339+
allVideoData = allVideoData.sort((a, b) =>
316340
sorting[sort] == -1
317341
? a.desc.localeCompare(b.desc)
318342
: b.desc.localeCompare(a.desc)
319343
);
320344
break;
321345
case "user":
322-
data = data.sort((a, b) =>
346+
allVideoData = allVideoData.sort((a, b) =>
323347
sorting[sort] == -1
324348
? a.author.uniqueId.localeCompare(b.author.uniqueId)
325349
: b.author.uniqueId.localeCompare(a.author.uniqueId)
326350
);
327351
break;
328352
case "view":
329-
data = data.sort((a, b) =>
353+
allVideoData = allVideoData.sort((a, b) =>
330354
sorting[sort] == -1
331355
? a.stats.playCount - b.stats.playCount
332356
: b.stats.playCount - a.stats.playCount
333357
);
334358
break;
335359
case "length":
336-
data = data.sort((a, b) =>
360+
allVideoData = allVideoData.sort((a, b) =>
337361
sorting[sort] == -1
338362
? a.video.duration - b.video.duration
339363
: b.video.duration - a.video.duration
340364
);
341365
break;
342366
}
343-
renderTable(tbody, data);
367+
renderTable(tbody, allVideoData);
344368
});
345369
}
346370
}
@@ -349,23 +373,25 @@ export default {
349373
tbody.innerHTML = data
350374
.map(
351375
(v, i) => /*html*/ `
352-
<tr>
376+
<tr data-video-id="${v.id}">
353377
<td>${v.index}</td>
354378
<td>
355379
<a target="_blank" href="${v.video.playAddr}">
356-
<img src="${v.video.dynamicCover || v.video.cover}" style="width:150px" />
380+
<object data="${v.video.dynamicCover}" type="image/png" style="width:150px">
381+
<img src="${v.video.cover}" style="width:150px" />
382+
</object>
357383
</a>
358384
</td>
359385
<td><p style="max-width:200px">${v.desc}</p></td>
360386
<td>
361387
<a target="_blank" href="https://www.tiktok.com/@${v.author.uniqueId}">
362388
<img src="${v.author.avatarThumb}" style="width:50px;height:50px" />
363389
</a>
364-
${v.author.uniqueId}<br/>
365390
${v.author.nickname}<br/>
366-
${v.id}
391+
${v.author.uniqueId}<br/>
392+
${v.author.id}
367393
</td>
368-
<td>${UfsGlobal.Utils.moneyFormat(v.stats.playCount)}</td>
394+
<td>${formatter.format(v.stats.playCount)}</td>
369395
<td>${v.video.duration}s</td>
370396
<td>
371397
<p style="max-width:200px">

scripts/tiktok_downloadWatchingVideo.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,31 +85,31 @@ export default {
8585
t({ vi: `Đang tải video ${title}...`, en: `Downloading ${title}...` })
8686
);
8787

88-
// UfsGlobal.Extension.download({
89-
// url: link,
90-
// filename: title + ".mp4",
91-
// });
92-
93-
const { formatSize, downloadBlob } = UfsGlobal.Utils;
94-
const blob = await getBlobFromUrlWithProgress(
95-
link,
96-
({ loaded, total, speed }) => {
97-
let desc =
98-
formatSize(loaded, 1) +
99-
" / " +
100-
formatSize(total, 1) +
101-
" (" +
102-
formatSize(speed, 1) +
103-
"/s)";
104-
setLoadingText(
105-
t({
106-
vi: `Đang tải ${desc}...<br/>${title}`,
107-
en: `Downloading ${desc}...<br/>${title}`,
108-
})
109-
);
110-
}
111-
);
112-
downloadBlob(blob, title + ".mp4");
88+
UfsGlobal.Extension.download({
89+
url: link,
90+
filename: title + ".mp4",
91+
});
92+
93+
// const { formatSize, downloadBlob } = UfsGlobal.Utils;
94+
// const blob = await getBlobFromUrlWithProgress(
95+
// link,
96+
// ({ loaded, total, speed }) => {
97+
// let desc =
98+
// formatSize(loaded, 1) +
99+
// " / " +
100+
// formatSize(total, 1) +
101+
// " (" +
102+
// formatSize(speed, 1) +
103+
// "/s)";
104+
// setLoadingText(
105+
// t({
106+
// vi: `Đang tải ${desc}...<br/>${title}`,
107+
// en: `Downloading ${desc}...<br/>${title}`,
108+
// })
109+
// );
110+
// }
111+
// );
112+
// downloadBlob(blob, title + ".mp4");
113113
}
114114

115115
closeLoading();

0 commit comments

Comments
 (0)