moved to new repo

This commit is contained in:
wukko
2022-07-09 00:17:56 +06:00
committed by GitHub
parent 1decab4daf
commit 94acf10e9e
62 changed files with 2187 additions and 4 deletions

488
files/cobalt.css Normal file
View File

@@ -0,0 +1,488 @@
:root {
--transparent: rgba(0, 0, 0, 0);
--without-padding: calc(100% - 4rem);
--border-15: 0.15rem solid var(--accent);
}
@media (prefers-color-scheme: dark) {
:root {
--accent: rgb(225, 225, 225);
--accent-hover: rgb(20, 20, 20);
--accent-press: rgb(10, 10, 10);
--accent-unhover: rgb(100, 100, 100);
--accent-unhover-2: rgb(110, 110, 110);
--background: rgb(0, 0, 0);
}
}
@media (prefers-color-scheme: light) {
:root {
--accent: rgb(25, 25, 25);
--accent-hover: rgb(230 230 230);
--accent-press: rgb(240 240 240);
--accent-unhover: rgb(190, 190, 190);
--accent-unhover-2: rgb(110, 110, 110);
--background: rgb(255, 255, 255);
}
}
[data-theme="dark"] {
--accent: rgb(225, 225, 225);
--accent-hover: rgb(20, 20, 20);
--accent-press: rgb(10, 10, 10);
--accent-unhover: rgb(100, 100, 100);
--accent-unhover-2: rgb(110, 110, 110);
--background: rgb(0, 0, 0);
}
[data-theme="light"] {
--accent: rgb(25, 25, 25);
--accent-hover: rgb(230 230 230);
--accent-press: rgb(240 240 240);
--accent-unhover: rgb(190, 190, 190);
--accent-unhover-2: rgb(110, 110, 110);
--background: rgb(255, 255, 255);
}
html,
body {
margin: 0;
background: var(--background);
color: var(--accent);
font-family: 'Noto Sans Mono', 'Consolas', 'SF Mono', monospace;
user-select: none;
-webkit-tap-highlight-color: var(--transparent);
overflow: hidden;
-ms-overflow-style: none;
scrollbar-width: none;
}
a {
color: var(--accent);
text-decoration: none;
}
::placeholder {
color: var(--accent-unhover-2);
}
::-webkit-scrollbar {
display: none;
}
:focus-visible {
outline: var(--border-15);
}
[type=checkbox] {
margin-right: 0.8rem;
}
[type="checkbox"] {
-webkit-appearance: none;
margin-right: 0.8rem;
z-index: 0;
}
[type="checkbox"]::before {
content: "";
width: 15px;
height: 15px;
border: var(--border-15);
background-color: var(--background);
display: block;
z-index: 5;
position: relative;
}
[type="checkbox"]:checked::before {
box-shadow: inset 0 0 0 0.2rem var(--background);
background-color: var(--accent);
}
button {
background: none;
border: none;
font-family: 'Noto Sans Mono', 'Consolas', 'SF Mono', monospace;
color: var(--accent);
font-size: 0.9rem;
}
input {
border-radius: none;
}
button:hover,
.switch:hover,
.checkbox:hover {
background: var(--accent-hover);
cursor: pointer;
}
button:active,
.switch:active,
.checkbox:active {
background: var(--accent-press);
cursor: pointer;
}
input[type="checkbox"] {
cursor: pointer;
}
.button {
background: none;
border: var(--border-15);
color: var(--accent);
padding: 0.3rem 0.75rem 0.5rem;
font-size: 1rem;
}
.mono {
font-family: 'Noto Sans Mono', 'Consolas', 'SF Mono', monospace;
}
.center {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#cobalt-main-box {
position: fixed;
width: 60%;
height: auto;
display: inline-flex;
padding: 3rem;
}
#logo-area {
padding-right: 3rem;
padding-top: 0.1rem;
text-align: left;
font-size: 1rem;
white-space: nowrap;
}
#download-area {
display: inline-flex;
height: 2rem;
width: 100%;
margin-top: -0.6rem;
}
.box {
background: var(--background);
border: var(--border-15);
color: var(--accent);
}
#url-input-area {
background: var(--background);
padding: 1.2rem 1rem;
width: 100%;
color: var(--accent);
border: 0;
float: right;
border-bottom: 0.1rem solid var(--accent-unhover);
transition: border-bottom 0.2s;
outline: none;
}
#url-input-area:focus {
outline: none;
border-bottom: 0.1rem solid var(--accent);
}
#download-button {
height: 2.5rem;
color: var(--accent);
background: none;
border: none;
font-size: 1.4rem;
cursor: pointer;
padding: 0;
letter-spacing: -0.1rem;
}
#download-button:disabled {
color: var(--accent-unhover);
cursor: not-allowed;
}
#footer {
bottom: 0.5rem;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
font-size: 0.9rem;
text-align: center;
width: auto;
}
#footer-buttons {
display: block;
}
.footer-button {
cursor: pointer;
color: var(--accent-unhover-2);
border: 0.15rem var(--accent-unhover-2) solid;
padding: 0.4rem 0.8rem 0.5rem;
}
.footer-button:hover {
color: var(--accent);
border: var(--border-15);
}
.text-backdrop {
background: var(--accent);
color: var(--background);
padding: 0 0.1rem;
}
::-moz-selection {
background-color: var(--accent);
color: var(--background);
}
::selection {
background-color: var(--accent);
color: var(--background);
}
.popup {
visibility: hidden;
position: fixed;
width: 55%;
height: auto;
z-index: 999;
padding: 3rem;
font-size: 0.9rem;
max-height: 80%;
}
#popup-backdrop {
opacity: 0.5;
background-color: var(--background);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 998;
}
.popup-narrow {
visibility: hidden;
position: fixed;
width: 30%;
height: auto;
z-index: 999;
padding: 3rem 2rem 2rem 2rem;
font-size: 0.9rem;
max-height: 80%;
}
.popup-narrow.scrollable {
height: 80%;
}
.nowrap {
white-space: nowrap;
}
.about-padding {
padding-bottom: 1.5rem;
}
.popup-subtitle {
font-size: 1.1rem;
padding-bottom: 0.5rem;
}
.little-subtitle {
font-size: 1.05rem;
}
.popup-desc {
width: 100%;
text-align: left;
float: left;
line-height: 1.7rem;
}
.popup-title {
font-size: 1.5rem;
margin-bottom: 0.5rem;
line-height: 1.85em;
}
.popup-footer {
bottom: 0;
position: fixed;
margin-bottom: 1.5rem;
background: var(--background);
width: var(--without-padding);
}
.popup-footer-content {
font-size: 0.8rem;
line-height: 1.7rem;
color: var(--accent-unhover-2);
border-top: 0.05rem solid var(--accent-unhover-2);
padding-top: 0.4rem;
}
.popup-above-title {
color: var(--accent-unhover-2);
font-size: 0.8rem;
}
.popup-narrow .popup-content {
overflow-x: hidden;
overflow-y: auto;
height: var(--without-padding);
scrollbar-width: none;
}
.popup-header {
position: relative;
background: var(--background);
z-index: 999;
}
.popup-content.with-footer {
margin-bottom: 3rem;
}
#close {
cursor: pointer;
float: right;
right: 3rem;
position: absolute;
}
.popup-narrow #close {
right: 0rem;
}
.settings-category {
padding-bottom: 1.2rem;
}
.title {
width: 100%;
text-align: left;
line-height: 1.7rem;
color: var(--accent-unhover-2);
border-bottom: 0.05rem solid var(--accent-unhover-2);
padding-bottom: 0.25rem;
}
.checkbox {
display: inline-flex;
align-items: center;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
padding: 0.6rem;
padding-right: 1rem;
border: 0.1rem solid;
width: auto;
margin: 0 1rem 0 0;
}
.checkbox-label {
line-height: 1.3rem;
}
.switch-container {
width: 100%;
}
.subtitle {
width: 100%;
text-align: left;
line-height: 1.7rem;
padding-bottom: 0.4rem;
color: var(--accent);
margin-top: 1rem;
}
.explanation {
padding-top: 1rem;
width: 100%;
font-size: 0.8rem;
text-align: left;
line-height: 1.3rem;
color: var(--accent-unhover-2);
}
.switch {
border-top: solid 0.1rem var(--accent);
border-bottom: solid 0.1rem var(--accent);
padding: 0.8rem;
width: 100%;
text-align: center;
color: var(--accent);
background: var(--background);
display: grid;
align-items: center;
cursor: pointer;
}
.switch.full {
border: solid 0.1rem var(--accent);
}
.switch.left {
border-left: solid 0.1rem var(--accent);
}
.switch.right {
border-right: solid 0.1rem var(--accent);
}
.switch[data-enabled="true"] {
color: var(--background);
background: var(--accent);
cursor: default;
}
.switches {
display: flex;
width: auto;
flex-direction: row;
flex-wrap: nowrap;
}
.text-to-copy {
user-select: text;
border: var(--border-15);
padding: 1rem;
overflow: auto;
}
/* adapt the page according to screen size */
@media screen and (min-width: 2300px) {
html {
zoom: 130%;
}
}
@media screen and (min-width: 3840px) {
html {
zoom: 180%;
}
}
@media screen and (min-width: 5000px) {
html {
zoom: 300%;
}
}
@media screen and (max-width: 1440px) {
#cobalt-main-box,
.popup {
width: 65%;
}
.popup-narrow {
width: 35%;
}
}
@media screen and (max-width: 1024px) {
#cobalt-main-box,
.popup {
width: 75%;
}
.popup-narrow {
width: 50%;
}
}
@media screen and (max-height: 850px) {
.popup-narrow {
height: 80%
}
}
/* mobile page */
@media screen and (max-width: 768px) {
#logo-area {
padding-right: 0;
padding-top: 0;
position: fixed;
line-height: 0;
margin-top: -2rem;
width: 100%;
text-align: center;
}
#cobalt-main-box {
width: 80%;
display: flex;
border: none;
padding: 0;
}
.popup,
.popup-narrow,
.popup-narrow.scrollable {
border: none;
width: 90%;
height: 90%;
max-height: 100%;
}
}
@media screen and (max-width: 524px) {
#logo-area {
padding-right: 0;
padding-top: 0;
position: fixed;
line-height: 0;
margin-top: -2rem;
width: 100%;
text-align: center;
}
#cobalt-main-box {
width: 90%;
display: flex;
border: none;
padding: 0;
}
.popup,
.popup-narrow,
.popup-narrow.scrollable {
border: none;
width: 90%;
height: 90%;
max-height: 100%;
}
}

214
files/cobalt.js Normal file
View File

@@ -0,0 +1,214 @@
function eid(id) {
return document.getElementById(id)
}
function enable(id) {
eid(id).dataset.enabled = "true";
}
function disable(id) {
eid(id).dataset.enabled = "false";
}
function vis(state) {
return (state === 1) ? "visible" : "hidden";
}
function changeDownloadButton(action, text) {
switch (action) {
case 0:
eid("download-button").disabled = true
if (localStorage.getItem("alwaysVisibleButton") == "true") {
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;
}
}
document.addEventListener("keydown", function(event) {
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, '>>');
}
function copy(id) {
let e = document.getElementById(id);
e.classList.add("text-backdrop");
navigator.clipboard.writeText(e.innerText);
setTimeout(() => { e.classList.remove("text-backdrop") }, 600);
}
function detectColorScheme() {
let theme = "auto";
let localTheme = localStorage.getItem("theme");
if (localTheme) {
theme = localTheme;
} else if (!window.matchMedia) {
theme = "dark"
}
document.documentElement.setAttribute("data-theme", theme);
}
function popup(type, action, text) {
eid("popup-backdrop").style.visibility = vis(action);
switch (type) {
case "about":
eid("popup-about").style.visibility = vis(action);
if (!localStorage.getItem("seenAbout")) {
localStorage.setItem("seenAbout", "true");
}
break;
case "error":
eid("desc-error").innerHTML = text;
eid("popup-error").style.visibility = vis(action);
break;
case "settings":
eid("popup-settings").style.visibility = vis(action);
break;
case "changelog":
eid("popup-changelog").style.visibility = vis(action);
break;
case "donate":
eid("popup-donate").style.visibility = vis(action);
break;
}
}
function changeSwitcher(li, b, u) {
if (u) {
localStorage.setItem(li, b);
}
let l = {
"theme": ["auto", "light", "dark"],
"youtubeFormat": ["mp4", "webm", "audio"],
"quality": ["max", "hig", "mid", "low"]
}
if (b) {
for (i in l[li]) {
if (l[li][i] == b) {
enable(`${li}-${b}`)
} else {
disable(`${li}-${l[li][i]}`)
}
}
if (li == "theme") {
detectColorScheme();
}
} else {
localStorage.setItem(li, l[li][0]);
for (i in l[li]) {
if (l[li][i] == l[li][0]) {
enable(`${li}-${l[li][0]}`)
} else {
disable(`${li}-${l[li][i]}`)
}
}
}
}
function internetError() {
eid("url-input-area").disabled = false
changeDownloadButton(2, '!!')
popup("error", 1, loc.noInternet);
}
function checkbox(action) {
switch(action) {
case 'alwaysVisibleButton':
if (eid("always-visible-button").checked) {
localStorage.setItem("alwaysVisibleButton", "true");
button();
} else {
localStorage.setItem("alwaysVisibleButton", "false");
button();
}
break;
}
}
function loadSettings() {
if (localStorage.getItem("alwaysVisibleButton") == "true") {
eid("always-visible-button").checked = true;
eid("download-button").value = '>>'
eid("download-button").style.padding = '0 1rem';
}
changeSwitcher("theme", localStorage.getItem("theme"))
changeSwitcher("youtubeFormat", localStorage.getItem("youtubeFormat"))
changeSwitcher("quality", localStorage.getItem("quality"))
}
async function download(url) {
changeDownloadButton(2, '...');
eid("url-input-area").disabled = true;
let format = '';
if (url.includes(".youtube.com/") || url.includes("/youtu.be/")) {
format = `&format=${localStorage.getItem("youtubeFormat")}`
}
fetch(`/api/json?quality=${localStorage.getItem("quality")}${format}&url=${encodeURIComponent(url)}`).then(async (response) => {
let j = await response.json();
if (j.status != "error" && j.status != "rate-limit") {
switch (j.status) {
case "redirect":
changeDownloadButton(2, '>>>')
setTimeout(() => {
changeDownloadButton(1, '>>')
eid("url-input-area").disabled = false
}, 3000)
if (navigator.userAgent.toLowerCase().match("iphone os")) {
window.location.href = j.url;
} else {
window.open(j.url, '_blank');
}
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, j.text);
}
}).catch((error) => {
internetError()
});
}
window.onload = function () {
loadSettings();
detectColorScheme();
changeDownloadButton(0, '>>');
eid("cobalt-main-box").style.visibility = 'visible';
eid("footer").style.visibility = 'visible';
eid("url-input-area").value = "";
if (!localStorage.getItem("seenAbout")) {
popup('about', 1)
}
}
eid("url-input-area").addEventListener("keyup", (event) => {
if (event.key === 'Enter') {
eid("download-button").click();
}
})

64
files/cobalt.webmanifest Normal file
View File

@@ -0,0 +1,64 @@
{
"name": "cobalt",
"short_name": "cobalt",
"start_url": "/",
"icons": [
{
"src": "/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
}, {
"src": "/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}, {
"src": "/icons/generic.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
}, {
"src": "/icons/maskable/x48.png",
"sizes": "48x48",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}, {
"src": "/icons/maskable/x1280.png",
"sizes": "1280x1280",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#000000",
"background_color": "#000000",
"display": "standalone"
}

View File

@@ -0,0 +1 @@
@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_DdVXQQ.woff2') format('woff2');unicode-range:U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_ndVXQQ.woff2') format('woff2');unicode-range:U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_HdVXQQ.woff2') format('woff2');unicode-range:U+1F00-1FFF}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_7dVXQQ.woff2') format('woff2');unicode-range:U+0370-03FF}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_LdVXQQ.woff2') format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_PdVXQQ.woff2') format('woff2');unicode-range:U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF}@font-face{font-family:'Noto Sans Mono';font-style:normal;font-weight:500;font-stretch:100%;font-display:swap;src:url('notosansmono_3dVQ.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

BIN
files/icons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
files/icons/generic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
files/icons/wide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

2
files/robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-Agent: *
Disallow: /icons/ /fonts/ *.js *.css