Skip to content

Commit d3e6837

Browse files
committed
tiktok batch download new - WIP
1 parent 124b1dc commit d3e6837

File tree

1 file changed

+164
-6
lines changed

1 file changed

+164
-6
lines changed

scripts/tiktok_batchDownload.js

Lines changed: 164 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,169 @@ export default {
5959
// reference to Cached
6060
window.ufs_tiktok_batchDownload = CACHED;
6161

62+
const id = "ufs_tiktok_batchDownload";
63+
const floatingBtnId = `${id}_floating_btn`;
64+
const containerId = `${id}_container`;
65+
66+
const ui = document.createElement("div");
67+
ui.id = id;
68+
(document.body || document.documentElement).appendChild(ui);
69+
70+
ui.innerHTML = /*html*/ `
71+
<style>
72+
#${id} {
73+
position: fixed;
74+
z-index: 99999999999;
75+
}
76+
#${floatingBtnId} {
77+
border-radius: 25px;
78+
background: #444;
79+
color: white;
80+
padding: 15px;
81+
position: fixed;
82+
bottom: 25px;
83+
right: 25px;
84+
border: 1px solid #777;
85+
cursor: pointer;
86+
}
87+
#${floatingBtnId}:hover {
88+
background: #666;
89+
}
90+
#${containerId} {
91+
display: none;
92+
position: fixed;
93+
top: 0;
94+
left: 0;
95+
width: 100vw;
96+
height: 100vh;
97+
background: rgba(0, 0, 0, 0.5);
98+
align-items: center;
99+
justify-content: center;
100+
}
101+
.ufs_popup {
102+
background: #444;
103+
color: #eee;
104+
padding: 20px;
105+
border-radius: 10px;
106+
max-width: 90vw;
107+
max-height: 90vh;
108+
overflow-y: auto;
109+
overflow-x: hidden;
110+
}
111+
.ufs_popup table, .ufs_popup th, .ufs_popup td {
112+
border: 1px solid #aaa;
113+
border-collapse: collapse;
114+
}
115+
.ufs_popup table td {
116+
padding: 10px;
117+
}
118+
.ufs_popup table th {
119+
position: sticky;
120+
top: -22px;
121+
background: #333;
122+
}
123+
</style>
124+
125+
<div id="${floatingBtnId}">📥</div>
126+
127+
<div id="${containerId}">
128+
129+
</div>
130+
`;
131+
const floatingBtn = ui.querySelector("#" + floatingBtnId);
132+
const container = ui.querySelector("#" + containerId);
133+
134+
function toggle(willShow) {
135+
if (!(typeof willShow === "boolean")) {
136+
let isShowing = container.style.display == "flex";
137+
willShow = !isShowing;
138+
}
139+
container.style.display = willShow ? "flex" : "none";
140+
return willShow;
141+
}
142+
143+
function renderData() {
144+
container.innerHTML = /*html*/ `
145+
<div class="ufs_popup">
146+
<h1 style="text-align:center">Tiktok - Useful Scripts</h1>
147+
<h2 style="text-align:center">Found ${CACHED.videoById.size} videos</h2>
148+
149+
<table>
150+
<thead>
151+
<tr>
152+
<th data-sort="index">#</th>
153+
<th>Video</th>
154+
<th data-sort="title">Title</th>
155+
<th data-sort="user">User</th>
156+
<th data-sort="view">View</th>
157+
<th data-sort="length">Length</th>
158+
<th>Download</th>
159+
</tr>
160+
</thead>
161+
<tbody>
162+
</tbody>
163+
</table>
164+
</div>`;
165+
166+
const tbody = container.querySelector("tbody");
167+
renderTable(tbody);
168+
}
169+
170+
function renderTable(
171+
tbody,
172+
data = Array.from(CACHED.videoById.values())
173+
) {
174+
tbody.innerHTML = data
175+
.map(
176+
(v, i) => /*html*/ `
177+
<tr>
178+
<td>${i + 1}</td>
179+
<td>
180+
<a target="_blank" href="${v.video.playAddr}">
181+
<img src="${v.video.originCover}" style="width:150px" />
182+
</a>
183+
</td>
184+
<td><p style="max-width:200px">${v.desc}</p></td>
185+
<td>
186+
<a target="_blank" href="https://www.tiktok.com/@${v.author.uniqueId}">
187+
<img src="${v.author.avatarThumb}" style="width:50px;height:50px" />
188+
</a>
189+
${v.author.uniqueId}<br/>
190+
${v.author.nickname}<br/>
191+
${v.id}
192+
</td>
193+
<td>${UfsGlobal.Utils.moneyFormat(v.stats.playCount)}</td>
194+
<td>${v.video.duration}s</td>
195+
<td>
196+
<p style="max-width:200px">
197+
<a href="${v.video.playAddr}" download target="_blank">Video</a><br/>
198+
<a href="${v.author.avatarLarger}" download target="_blank">
199+
Avatar
200+
</a><br/>
201+
<a href="${v.music.playUrl}" download target="_blank">
202+
Music: ${v.music.title}
203+
</a>
204+
</p>
205+
</td>
206+
</tr>`
207+
)
208+
.join("");
209+
}
210+
211+
container.onclick = (e) => {
212+
if (e.target === container) {
213+
toggle(false);
214+
}
215+
};
216+
217+
floatingBtn.onclick = () => {
218+
let isShow = toggle();
219+
if (isShow) renderData();
220+
};
221+
62222
hookFetch({
63223
onAfter: async (url, options, response) => {
64-
if (url.includes("api/post/item_list")) {
224+
if (url.includes("item_list/")) {
65225
// clone to new response
66226
const res = response.clone();
67227
const json = await res.json();
@@ -70,17 +230,15 @@ export default {
70230
if (json?.itemList) {
71231
CACHED.list.push(...json.itemList);
72232
json.itemList.forEach((_) => {
73-
CACHED.videoById.set(_.video.id, {
74-
url: _.video.playAddr,
75-
name: _.desc,
76-
});
233+
if (_.video.playAddr) CACHED.videoById.set(_.video.id, _);
77234
});
235+
floatingBtn.innerHTML = `📥 (${CACHED.videoById.size})`;
78236
}
79237
}
80238
},
81239
});
82240
},
83-
onDocumentIdle: async () => {
241+
_onDocumentIdle: async () => {
84242
let checkboxes = [];
85243

86244
// Setup DOM

0 commit comments

Comments
 (0)