2022-07-13 21:32:00 +01:00
|
|
|
let isIOS = navigator.userAgent.toLowerCase().match("iphone os");
|
2022-08-22 15:10:54 +01:00
|
|
|
let version = 5;
|
2022-08-12 14:36:19 +01:00
|
|
|
|
2022-07-13 21:32:00 +01:00
|
|
|
let switchers = {
|
|
|
|
"theme": ["auto", "light", "dark"],
|
2022-08-12 14:36:19 +01:00
|
|
|
"ytFormat": ["webm", "mp4"],
|
|
|
|
"quality": ["max", "hig", "mid", "low"],
|
2022-08-13 12:14:09 +01:00
|
|
|
"audioFormat": ["best", "mp3", "ogg", "wav", "opus"]
|
2022-07-13 21:32:00 +01:00
|
|
|
}
|
2022-08-23 15:43:56 +01:00
|
|
|
let checkboxes = ["disableTikTokWatermark", "fullTikTokAudio"]
|
2022-08-22 15:10:54 +01:00
|
|
|
let exceptions = { // used solely for ios devices, because they're less capable than everything else.
|
2022-08-12 14:36:19 +01:00
|
|
|
"ytFormat": "mp4",
|
|
|
|
"audioFormat": "mp3"
|
2022-08-06 16:21:48 +01:00
|
|
|
}
|
2022-07-13 21:32:00 +01:00
|
|
|
|
2022-07-08 19:17:56 +01:00
|
|
|
function eid(id) {
|
|
|
|
return document.getElementById(id)
|
|
|
|
}
|
2022-08-16 11:31:41 +01:00
|
|
|
function sGet(id) {
|
|
|
|
return localStorage.getItem(id)
|
|
|
|
}
|
|
|
|
function sSet(id, value) {
|
|
|
|
localStorage.setItem(id, value)
|
|
|
|
}
|
2022-07-08 19:17:56 +01:00
|
|
|
function enable(id) {
|
|
|
|
eid(id).dataset.enabled = "true";
|
|
|
|
}
|
|
|
|
function disable(id) {
|
|
|
|
eid(id).dataset.enabled = "false";
|
|
|
|
}
|
|
|
|
function vis(state) {
|
|
|
|
return (state === 1) ? "visible" : "hidden";
|
|
|
|
}
|
2022-08-12 14:36:19 +01:00
|
|
|
function opposite(state) {
|
|
|
|
return state == "true" ? "false" : "true";
|
|
|
|
}
|
2022-07-08 19:17:56 +01:00
|
|
|
function changeDownloadButton(action, text) {
|
|
|
|
switch (action) {
|
|
|
|
case 0:
|
|
|
|
eid("download-button").disabled = true
|
2022-08-16 11:31:41 +01:00
|
|
|
if (sGet("alwaysVisibleButton") == "true") {
|
2022-07-08 19:17:56 +01:00
|
|
|
eid("download-button").value = text
|
|
|
|
eid("download-button").style.padding = '0 1rem'
|
|
|
|
} else {
|
|
|
|
eid("download-button").value = ''
|
|
|
|
eid("download-button").style.padding = '0'
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
eid("download-button").disabled = false
|
|
|
|
eid("download-button").value = text
|
|
|
|
eid("download-button").style.padding = '0 1rem'
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
eid("download-button").disabled = true
|
|
|
|
eid("download-button").value = text
|
|
|
|
eid("download-button").style.padding = '0 1rem'
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-08-16 08:14:19 +01:00
|
|
|
document.addEventListener("keydown", (event) => {
|
2022-07-08 19:17:56 +01:00
|
|
|
if (event.key == "Tab") {
|
|
|
|
eid("download-button").value = '>>'
|
|
|
|
eid("download-button").style.padding = '0 1rem'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
function button() {
|
|
|
|
let regex = /https:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/.test(eid("url-input-area").value);
|
|
|
|
regex ? changeDownloadButton(1, '>>') : changeDownloadButton(0, '>>');
|
|
|
|
}
|
2022-07-13 21:32:00 +01:00
|
|
|
function copy(id, data) {
|
2022-07-08 19:17:56 +01:00
|
|
|
let e = document.getElementById(id);
|
|
|
|
e.classList.add("text-backdrop");
|
2022-07-13 21:32:00 +01:00
|
|
|
data ? navigator.clipboard.writeText(data) : navigator.clipboard.writeText(e.innerText);
|
2022-07-08 19:17:56 +01:00
|
|
|
setTimeout(() => { e.classList.remove("text-backdrop") }, 600);
|
|
|
|
}
|
|
|
|
function detectColorScheme() {
|
|
|
|
let theme = "auto";
|
2022-08-16 11:31:41 +01:00
|
|
|
let localTheme = sGet("theme");
|
2022-07-08 19:17:56 +01:00
|
|
|
if (localTheme) {
|
|
|
|
theme = localTheme;
|
|
|
|
} else if (!window.matchMedia) {
|
|
|
|
theme = "dark"
|
|
|
|
}
|
|
|
|
document.documentElement.setAttribute("data-theme", theme);
|
|
|
|
}
|
2022-08-12 14:36:19 +01:00
|
|
|
function changeTab(evnt, tabId, tabClass) {
|
|
|
|
let tabcontent = document.getElementsByClassName(`tab-content-${tabClass}`);
|
|
|
|
let tablinks = document.getElementsByClassName(`tab-${tabClass}`);
|
|
|
|
for (let i = 0; i < tabcontent.length; i++) {
|
|
|
|
tabcontent[i].style.display = "none";
|
|
|
|
}
|
|
|
|
for (let i = 0; i < tablinks.length; i++) {
|
|
|
|
tablinks[i].dataset.enabled = "false";
|
|
|
|
}
|
|
|
|
eid(tabId).style.display = "block";
|
|
|
|
evnt.currentTarget.dataset.enabled = "true";
|
|
|
|
}
|
|
|
|
function hideAllPopups() {
|
|
|
|
let filter = document.getElementsByClassName('popup');
|
|
|
|
for (let i = 0; i < filter.length; i++) {
|
|
|
|
filter[i].style.visibility = "hidden";
|
|
|
|
}
|
|
|
|
eid("popup-backdrop").style.visibility = "hidden";
|
|
|
|
}
|
2022-07-08 19:17:56 +01:00
|
|
|
function popup(type, action, text) {
|
|
|
|
eid("popup-backdrop").style.visibility = vis(action);
|
|
|
|
switch (type) {
|
|
|
|
case "about":
|
2022-08-12 14:36:19 +01:00
|
|
|
let tabId = text ? text : "changelog";
|
|
|
|
if (tabId == "changelog") {
|
2022-08-16 11:31:41 +01:00
|
|
|
sSet("changelogStatus", version)
|
2022-08-12 14:36:19 +01:00
|
|
|
}
|
|
|
|
eid(`tab-button-${type}-${tabId}`).click();
|
2022-07-08 19:17:56 +01:00
|
|
|
eid("popup-about").style.visibility = vis(action);
|
2022-08-16 11:31:41 +01:00
|
|
|
if (!sGet("seenAbout")) sSet("seenAbout", "true");
|
2022-07-08 19:17:56 +01:00
|
|
|
break;
|
2022-08-12 14:36:19 +01:00
|
|
|
case "settings":
|
|
|
|
eid(`tab-button-${type}-video`).click();
|
|
|
|
eid("popup-settings").style.visibility = vis(action);
|
|
|
|
break;
|
2022-07-08 19:17:56 +01:00
|
|
|
case "error":
|
|
|
|
eid("desc-error").innerHTML = text;
|
|
|
|
eid("popup-error").style.visibility = vis(action);
|
|
|
|
break;
|
2022-07-13 21:32:00 +01:00
|
|
|
case "download":
|
|
|
|
if (action == 1) {
|
|
|
|
eid("pd-download").href = text;
|
2022-08-04 12:22:40 +01:00
|
|
|
eid("pd-copy").setAttribute("onClick", `copy('pd-copy', '${text}')`);
|
2022-07-13 21:32:00 +01:00
|
|
|
}
|
|
|
|
eid("popup-download").style.visibility = vis(action);
|
2022-07-08 19:17:56 +01:00
|
|
|
break;
|
2022-07-13 21:32:00 +01:00
|
|
|
default:
|
|
|
|
eid(`popup-${type}`).style.visibility = vis(action);
|
2022-07-08 19:17:56 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-08-12 14:36:19 +01:00
|
|
|
function changeSwitcher(li, b) {
|
2022-07-08 19:17:56 +01:00
|
|
|
if (b) {
|
2022-08-16 11:31:41 +01:00
|
|
|
sSet(li, b);
|
2022-07-13 21:32:00 +01:00
|
|
|
for (i in switchers[li]) {
|
|
|
|
(switchers[li][i] == b) ? enable(`${li}-${b}`) : disable(`${li}-${switchers[li][i]}`)
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
2022-07-13 21:32:00 +01:00
|
|
|
if (li == "theme") detectColorScheme();
|
2022-07-08 19:17:56 +01:00
|
|
|
} else {
|
2022-08-06 16:21:48 +01:00
|
|
|
let pref = switchers[li][0];
|
2022-08-12 14:36:19 +01:00
|
|
|
if (isIOS && exceptions[li]) pref = exceptions[li];
|
2022-08-22 08:30:45 +01:00
|
|
|
sSet(li, pref);
|
2022-07-13 21:32:00 +01:00
|
|
|
for (i in switchers[li]) {
|
2022-08-06 16:21:48 +01:00
|
|
|
(switchers[li][i] == pref) ? enable(`${li}-${pref}`) : disable(`${li}-${switchers[li][i]}`)
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function internetError() {
|
|
|
|
eid("url-input-area").disabled = false
|
|
|
|
changeDownloadButton(2, '!!')
|
|
|
|
popup("error", 1, loc.noInternet);
|
|
|
|
}
|
|
|
|
function checkbox(action) {
|
2022-07-13 21:32:00 +01:00
|
|
|
if (eid(action).checked) {
|
2022-08-16 11:31:41 +01:00
|
|
|
sSet(action, "true");
|
2022-07-13 21:32:00 +01:00
|
|
|
if (action == "alwaysVisibleButton") button();
|
|
|
|
} else {
|
2022-08-16 11:31:41 +01:00
|
|
|
sSet(action, "false");
|
2022-07-13 21:32:00 +01:00
|
|
|
if (action == "alwaysVisibleButton") button();
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
function loadSettings() {
|
2022-08-16 11:31:41 +01:00
|
|
|
if (sGet("alwaysVisibleButton") == "true") {
|
2022-07-13 21:32:00 +01:00
|
|
|
eid("alwaysVisibleButton").checked = true;
|
2022-07-08 19:17:56 +01:00
|
|
|
eid("download-button").value = '>>'
|
|
|
|
eid("download-button").style.padding = '0 1rem';
|
|
|
|
}
|
2022-08-16 11:31:41 +01:00
|
|
|
if (sGet("downloadPopup") == "true" && !isIOS) {
|
2022-07-13 21:32:00 +01:00
|
|
|
eid("downloadPopup").checked = true;
|
|
|
|
}
|
2022-08-16 11:31:41 +01:00
|
|
|
if (!sGet("audioMode")) {
|
2022-08-12 14:36:19 +01:00
|
|
|
toggle("audioMode")
|
|
|
|
}
|
2022-08-23 15:43:56 +01:00
|
|
|
for (let i = 0; i < checkboxes.length; i++) {
|
|
|
|
if (sGet(checkboxes[i]) == "true") eid(checkboxes[i]).checked = true;
|
2022-08-16 11:31:41 +01:00
|
|
|
}
|
|
|
|
updateToggle("audioMode", sGet("audioMode"));
|
2022-08-12 14:36:19 +01:00
|
|
|
for (let i in switchers) {
|
2022-08-16 11:31:41 +01:00
|
|
|
changeSwitcher(i, sGet(i))
|
2022-08-12 14:36:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
function toggle(toggle) {
|
2022-08-16 11:31:41 +01:00
|
|
|
let state = sGet(toggle);
|
2022-08-12 14:36:19 +01:00
|
|
|
if (state) {
|
2022-08-16 11:31:41 +01:00
|
|
|
sSet(toggle, opposite(state))
|
2022-08-22 15:10:54 +01:00
|
|
|
if (opposite(state) == "true") sSet(`${toggle}ToggledOnce`, "true");
|
2022-08-12 14:36:19 +01:00
|
|
|
} else {
|
2022-08-16 11:31:41 +01:00
|
|
|
sSet(toggle, "false")
|
2022-08-12 14:36:19 +01:00
|
|
|
}
|
2022-08-16 11:31:41 +01:00
|
|
|
updateToggle(toggle, sGet(toggle))
|
2022-08-12 14:36:19 +01:00
|
|
|
}
|
|
|
|
function updateToggle(toggle, state) {
|
|
|
|
switch(state) {
|
|
|
|
case "true":
|
|
|
|
eid(toggle).innerHTML = loc.toggleAudio;
|
|
|
|
break;
|
|
|
|
case "false":
|
2022-08-22 15:10:54 +01:00
|
|
|
eid(toggle).innerHTML = sGet(`${toggle}ToggledOnce`) == "true" ? loc.toggleDefault : loc.pressToChange + loc.toggleDefault;
|
2022-08-12 14:36:19 +01:00
|
|
|
break;
|
|
|
|
}
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
|
|
|
async function download(url) {
|
|
|
|
changeDownloadButton(2, '...');
|
|
|
|
eid("url-input-area").disabled = true;
|
2022-08-16 11:31:41 +01:00
|
|
|
let audioMode = sGet("audioMode");
|
|
|
|
let format = ``;
|
|
|
|
if (audioMode == "false") {
|
|
|
|
if (url.includes("youtube.com/") || url.includes("/youtu.be/")) {
|
|
|
|
format = `&format=${sGet("ytFormat")}`
|
|
|
|
} else if ((url.includes("tiktok.com/") || url.includes("douyin.com/")) && sGet("disableTikTokWatermark") == "true") {
|
|
|
|
format = `&nw=true`
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
format = `&nw=true`
|
2022-08-23 15:43:56 +01:00
|
|
|
if (sGet("fullTikTokAudio") == "true") format += `&ttfull=true`
|
2022-08-16 11:31:41 +01:00
|
|
|
}
|
|
|
|
let mode = (sGet("audioMode") == "true") ? `audio=true` : `quality=${sGet("quality")}`
|
|
|
|
fetch(`/api/json?audioFormat=${sGet("audioFormat")}&${mode}${format}&url=${encodeURIComponent(url)}`).then(async (response) => {
|
2022-07-08 19:17:56 +01:00
|
|
|
let j = await response.json();
|
|
|
|
if (j.status != "error" && j.status != "rate-limit") {
|
2022-07-22 09:05:36 +01:00
|
|
|
if (j.url) {
|
|
|
|
switch (j.status) {
|
|
|
|
case "redirect":
|
|
|
|
changeDownloadButton(2, '>>>')
|
|
|
|
setTimeout(() => {
|
|
|
|
changeDownloadButton(1, '>>')
|
2022-07-08 19:17:56 +01:00
|
|
|
eid("url-input-area").disabled = false
|
2022-07-22 09:05:36 +01:00
|
|
|
}, 3000)
|
2022-08-16 11:31:41 +01:00
|
|
|
if (sGet("downloadPopup") == "true") {
|
2022-07-22 09:05:36 +01:00
|
|
|
popup('download', 1, j.url)
|
|
|
|
} else {
|
|
|
|
window.open(j.url, '_blank');
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
2022-07-22 09:05:36 +01:00
|
|
|
break;
|
|
|
|
case "stream":
|
|
|
|
changeDownloadButton(2, '?..')
|
|
|
|
fetch(`${j.url}&p=1&origin=front`).then(async (response) => {
|
|
|
|
let jp = await response.json();
|
|
|
|
if (jp.status == "continue") {
|
|
|
|
changeDownloadButton(2, '>>>')
|
|
|
|
window.location.href = j.url
|
|
|
|
setTimeout(() => {
|
|
|
|
changeDownloadButton(1, '>>')
|
|
|
|
eid("url-input-area").disabled = false
|
|
|
|
}, 5000)
|
|
|
|
} else {
|
|
|
|
eid("url-input-area").disabled = false
|
|
|
|
changeDownloadButton(2, '!!')
|
|
|
|
popup("error", 1, jp.text);
|
|
|
|
}
|
|
|
|
}).catch((error) => internetError());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
eid("url-input-area").disabled = false
|
|
|
|
changeDownloadButton(2, '!!')
|
|
|
|
popup("error", 1, loc.noURLReturned);
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
eid("url-input-area").disabled = false
|
|
|
|
changeDownloadButton(2, '!!')
|
|
|
|
popup("error", 1, j.text);
|
|
|
|
}
|
2022-07-13 21:32:00 +01:00
|
|
|
}).catch((error) => internetError());
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
2022-08-16 08:14:19 +01:00
|
|
|
window.onload = () => {
|
2022-07-08 19:17:56 +01:00
|
|
|
loadSettings();
|
|
|
|
detectColorScheme();
|
|
|
|
changeDownloadButton(0, '>>');
|
|
|
|
eid("cobalt-main-box").style.visibility = 'visible';
|
|
|
|
eid("footer").style.visibility = 'visible';
|
|
|
|
eid("url-input-area").value = "";
|
2022-08-16 11:31:41 +01:00
|
|
|
if (!sGet("seenAbout")) {
|
2022-08-12 14:36:19 +01:00
|
|
|
popup('about', 1, "about");
|
2022-08-16 11:31:41 +01:00
|
|
|
} else if (sGet("changelogStatus") != `${version}` && sGet("disableChangelog") != "true") {
|
2022-08-12 14:36:19 +01:00
|
|
|
popup('about', 1, "changelog");
|
|
|
|
}
|
2022-08-16 11:31:41 +01:00
|
|
|
if (isIOS) sSet("downloadPopup", "true");
|
|
|
|
let urlQuery = new URLSearchParams(window.location.search).get("u");
|
|
|
|
if (urlQuery != null) {
|
|
|
|
eid("url-input-area").value = urlQuery;
|
|
|
|
button();
|
|
|
|
}
|
2022-07-08 19:17:56 +01:00
|
|
|
}
|
|
|
|
eid("url-input-area").addEventListener("keyup", (event) => {
|
2022-08-12 14:36:19 +01:00
|
|
|
if (event.key === 'Enter') eid("download-button").click();
|
2022-08-04 19:09:41 +01:00
|
|
|
})
|
2022-08-16 08:14:19 +01:00
|
|
|
document.onkeydown = (event) => {
|
2022-08-12 14:36:19 +01:00
|
|
|
if (event.key === 'Escape') hideAllPopups();
|
|
|
|
};
|