7.0: ui refresh and more
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { celebrations } from "../config.js";
|
||||
import emoji from "../emoji.js";
|
||||
|
||||
export const backButtonSVG = `<svg width="22" height="22" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.7551 27.5102L3 15.7551L14.7551 4L16.7755 5.99417L8.45773 14.312H30V17.1982H8.45773L16.7755 25.4898L14.7551 27.5102Z" fill="#FFFFFF"/>
|
||||
</svg>`
|
||||
|
||||
export function switcher(obj) {
|
||||
let items = ``;
|
||||
if (obj.name === "download") {
|
||||
@@ -19,26 +23,18 @@ export function switcher(obj) {
|
||||
${obj.explanation ? `<div class="explanation">${obj.explanation}</div>` : ``}
|
||||
</div>`
|
||||
}
|
||||
export function checkbox(obj) {
|
||||
let paddings = ["bottom-margin", "top-margin", "no-margin", "top-margin-only"];
|
||||
let checkboxes = ``;
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
let paddingClass = obj[i].padding && paddings.includes(obj[i].padding) ? ` ${obj[i].padding}` : '';
|
||||
|
||||
export function checkbox(action, text, paddingType, aria) {
|
||||
let paddingClass = ` `
|
||||
switch (paddingType) {
|
||||
case 1:
|
||||
paddingClass += "bottom-margin"
|
||||
break;
|
||||
case 2:
|
||||
paddingClass += "top-margin"
|
||||
break;
|
||||
case 3:
|
||||
paddingClass += "no-margin"
|
||||
break;
|
||||
case 4:
|
||||
paddingClass += "top-margin-only"
|
||||
checkboxes += `<label id="${obj[i].action}-chkbx" class="checkbox${paddingClass}">
|
||||
<input id="${obj[i].action}" type="checkbox" aria-label="${obj[i].aria ? obj[i].aria : obj[i].name}" onclick="checkbox('${obj[i].action}')">
|
||||
<span>${obj[i].name}</span>
|
||||
</label>`
|
||||
}
|
||||
return `<label id="${action}-chkbx" class="checkbox${paddingClass}">
|
||||
<input id="${action}" type="checkbox" ${aria ? `aria-label="${aria}"` : `aria-label="${text}"`} onclick="checkbox('${action}')">
|
||||
<span>${text}</span>
|
||||
</label>`
|
||||
return checkboxes
|
||||
}
|
||||
export function sep(paddingType) {
|
||||
let paddingClass = ``
|
||||
@@ -50,7 +46,7 @@ export function sep(paddingType) {
|
||||
return `<div class="separator${paddingClass}"></div>`
|
||||
}
|
||||
export function popup(obj) {
|
||||
let classes = obj.classes ? obj.classes : []
|
||||
let classes = obj.classes ? obj.classes : [];
|
||||
let body = obj.body;
|
||||
if (Array.isArray(obj.body)) {
|
||||
body = ``
|
||||
@@ -65,37 +61,44 @@ export function popup(obj) {
|
||||
}
|
||||
}
|
||||
return `
|
||||
${obj.standalone ? `<div id="popup-${obj.name}" class="popup center box${classes.length > 0 ? ' ' + classes.join(' ') : ''}" style="visibility: hidden;">` : ''}
|
||||
<div id="popup-header" class="popup-header">
|
||||
${obj.standalone && !obj.buttonOnly ? `<button id="close-button" class="switch up" onclick="popup('${obj.name}', 0)" ${obj.header.closeAria ? `aria-label="${obj.header.closeAria}"` : ''}>x</button>` : ''}
|
||||
${obj.buttonOnly ? obj.header.emoji : ``}
|
||||
${obj.header.aboveTitle ? `<a id="popup-above-title" target="_blank" href="${obj.header.aboveTitle.url}">${obj.header.aboveTitle.text}</a>` : ''}
|
||||
${obj.header.title ? `<div id="popup-title">${obj.header.title}</div>` : ''}
|
||||
${obj.header.subtitle ? `<div id="popup-subtitle">${obj.header.subtitle}</div>` : ''}
|
||||
${obj.standalone ? `<div id="popup-${obj.name}" class="popup center${!obj.buttonOnly ? " box": ''}${classes.length > 0 ? ' ' + classes.join(' ') : ''}">` : ''}
|
||||
<div id="popup-header" class="popup-header${!obj.buttonOnly ? " glass-bkg": ''}">
|
||||
<div id="popup-header-contents">
|
||||
${obj.buttonOnly ? obj.header.emoji : ``}
|
||||
${obj.header.aboveTitle ? `<a id="popup-above-title" target="_blank" href="${obj.header.aboveTitle.url}">${obj.header.aboveTitle.text}</a>` : ''}
|
||||
${obj.header.title ? `<div id="popup-title">${obj.header.title}</div>` : ''}
|
||||
${obj.header.subtitle ? `<div id="popup-subtitle">${obj.header.subtitle}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div id="popup-content"${obj.footer ? ' class="with-footer"' : ''}>
|
||||
<div id="popup-content" class="popup-content-inner">
|
||||
${body}${obj.buttonOnly ? `<button id="close-error" class="switch" onclick="popup('${obj.name}', 0)">${obj.buttonText}</button>` : ''}
|
||||
</div>
|
||||
${obj.footer ? `<div id="popup-footer" class="popup-footer">
|
||||
<a id="popup-bottom" class="popup-footer-content" target="_blank" href="${obj.footer.url}">${obj.footer.text}</a>
|
||||
</div>` : ''}
|
||||
${obj.standalone ? `</div>` : ''}`
|
||||
}
|
||||
|
||||
export function multiPagePopup(obj) {
|
||||
let tabs = ``
|
||||
let tabContent = ``
|
||||
let tabs = `
|
||||
<button id="back-button" class="switch tab-${obj.name}" onclick="popup('${obj.name}', 0)" ${obj.closeAria ? `aria-label="${obj.closeAria}"` : ''}>
|
||||
${backButtonSVG}
|
||||
</button>`;
|
||||
|
||||
let tabContent = ``;
|
||||
for (let i = 0; i < obj.tabs.length; i++) {
|
||||
tabs += `<button id="tab-button-${obj.name}-${obj.tabs[i]["name"]}" class="switch tab tab-${obj.name}" onclick="changeTab(event, 'tab-${obj.name}-${obj.tabs[i]["name"]}', '${obj.name}')">${obj.tabs[i]["title"]}</button>`
|
||||
tabContent += `<div id="tab-${obj.name}-${obj.tabs[i]["name"]}" class="popup-tab-content tab-content-${obj.name}">${obj.tabs[i]["content"]}</div>`
|
||||
}
|
||||
|
||||
return `
|
||||
<div id="popup-${obj.name}" class="popup center box scrollable" style="visibility: hidden;">
|
||||
<div id="popup-content">${obj.header ? `<div id="popup-header" class="popup-header">
|
||||
${obj.header.aboveTitle ? `<a id="popup-above-title" target="_blank" href="${obj.header.aboveTitle.url}">${obj.header.aboveTitle.text}</a>` : ''}
|
||||
${obj.header.title ? `<div id="popup-title">${obj.header.title}</div>` : ''}
|
||||
${obj.header.subtitle ? `<div id="popup-subtitle">${obj.header.subtitle}</div>` : ''}</div>` : ''}${tabContent}</div>
|
||||
<div id="popup-tabs" class="switches popup-tabs"><div class="switches popup-tabs-child">${tabs}</div><button id="close-button" class="switch tab-${obj.name}" onclick="popup('${obj.name}', 0)" ${obj.closeAria ? `aria-label="${obj.closeAria}"` : ''}>x</button></div>
|
||||
<div id="popup-${obj.name}" class="popup center box scrollable">
|
||||
<div id="popup-content">
|
||||
${obj.header ? `<div id="popup-header" class="popup-header glass-bkg">
|
||||
<div id="popup-header-contents">
|
||||
${obj.header.aboveTitle ? `<a id="popup-above-title" target="_blank" href="${obj.header.aboveTitle.url}">${obj.header.aboveTitle.text}</a>` : ''}
|
||||
${obj.header.title ? `<div id="popup-title">${obj.header.title}</div>` : ''}
|
||||
${obj.header.subtitle ? `<div id="popup-subtitle">${obj.header.subtitle}</div>` : ''}
|
||||
</div>
|
||||
</div>` : ''}${tabContent}</div>
|
||||
<div id="popup-tabs" class="switches popup-tabs glass-bkg"><div class="switches popup-tabs-child">${tabs}</div></div>
|
||||
</div>`
|
||||
}
|
||||
export function collapsibleList(arr) {
|
||||
@@ -112,24 +115,28 @@ export function collapsibleList(arr) {
|
||||
return items;
|
||||
}
|
||||
export function popupWithBottomButtons(obj) {
|
||||
let tabs = ``
|
||||
let tabs = `
|
||||
<button id="back-button" class="switch tab-${obj.name}" onclick="popup('${obj.name}', 0)" ${obj.closeAria ? `aria-label="${obj.closeAria}"` : ''}>
|
||||
${backButtonSVG}
|
||||
</button>`
|
||||
|
||||
for (let i = 0; i < obj.buttons.length; i++) {
|
||||
tabs += obj.buttons[i]
|
||||
}
|
||||
tabs += `<button id="close-button" class="switch tab-${obj.name}" onclick="popup('${obj.name}', 0)" ${obj.closeAria ? `aria-label="${obj.closeAria}"` : ''}>x</button>`
|
||||
return `
|
||||
<div id="popup-${obj.name}" class="popup center box scrollable" style="visibility: hidden;">
|
||||
<div id="popup-content">${obj.header ? `<div id="popup-header" class="popup-header">
|
||||
${obj.header.aboveTitle ? `<a id="popup-above-title" target="_blank" href="${obj.header.aboveTitle.url}">${obj.header.aboveTitle.text}</a>` : ''}
|
||||
${obj.header.title ? `<div id="popup-title">${obj.header.title}</div>` : ''}
|
||||
${obj.header.subtitle ? `<div id="popup-subtitle">${obj.header.subtitle}</div>` : ''}
|
||||
${obj.header.explanation ? `<div class="explanation">${obj.header.explanation}</div>` : ''}</div>` : ''}${obj.content}</div>
|
||||
<div id="popup-buttons" class="switches popup-tabs">${tabs}</div>
|
||||
<div id="popup-${obj.name}" class="popup center box scrollable">
|
||||
<div id="popup-content">
|
||||
${obj.header ? `<div id="popup-header" class="popup-header glass-bkg">
|
||||
<div id="popup-header-contents">
|
||||
${obj.header.aboveTitle ? `<a id="popup-above-title" target="_blank" href="${obj.header.aboveTitle.url}">${obj.header.aboveTitle.text}</a>` : ''}
|
||||
${obj.header.title ? `<div id="popup-title">${obj.header.title}</div>` : ''}
|
||||
${obj.header.subtitle ? `<div id="popup-subtitle">${obj.header.subtitle}</div>` : ''}
|
||||
${obj.header.explanation ? `<div class="explanation">${obj.header.explanation}</div>` : ''}
|
||||
</div>
|
||||
</div>` : ''}${obj.content}</div>
|
||||
<div id="popup-tabs" class="switches popup-tabs glass-bkg"><div id="picker-buttons" class="switches popup-tabs-child">${tabs}</div></div>
|
||||
</div>`
|
||||
}
|
||||
export function backdropLink(link, text) {
|
||||
return `<a class="text-backdrop italic" href="${link}" target="_blank">${text}</a>`
|
||||
}
|
||||
export function socialLink(emji, name, handle, url) {
|
||||
return `<div class="cobalt-support-link">${emji} ${name}: <a class="text-backdrop italic" href="${url}" target="_blank">${handle}</a></div>`
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import changelogManager from "../changelog/changelogManager.js"
|
||||
import { cleanHTML } from "../sub/utils.js";
|
||||
|
||||
let cache = {}
|
||||
|
||||
@@ -10,8 +11,16 @@ export function changelogHistory() { // blockId 0
|
||||
let historyLen = history.length;
|
||||
for (let i in history) {
|
||||
let separator = (i !== 0 && i !== historyLen) ? '<div class="separator"></div>' : '';
|
||||
render += `${separator}${history[i]["banner"] ? `<div class="changelog-banner"><img class="changelog-img" src="${history[i]["banner"]}" onerror="this.style.display='none'" loading="lazy"></img></div>` : ''}<div id="popup-desc" class="changelog-subtitle">${history[i]["title"]}</div><div id="popup-desc" class="desc-padding">${history[i]["content"]}</div>`
|
||||
|
||||
render += `
|
||||
${separator}${history[i]["banner"] ? `<div class="changelog-banner">
|
||||
<img class="changelog-img" src="${history[i]["banner"]}" onerror="this.style.display='none'" loading="lazy"></img>
|
||||
</div>` : ''}
|
||||
<div id="popup-desc" class="changelog-tags">${history[i]["version"]}</div>
|
||||
<div id="popup-desc" class="changelog-subtitle">${history[i]["title"]}</div>
|
||||
<div id="popup-desc" class="desc-padding">${history[i]["content"]}</div>`
|
||||
}
|
||||
render = cleanHTML(render);
|
||||
cache['0'] = render;
|
||||
return render;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { backdropLink, checkbox, collapsibleList, explanation, footerButtons, multiPagePopup, popup, popupWithBottomButtons, sep, settingsCategory, switcher, socialLink } from "./elements.js";
|
||||
import { services as s, appName, authorInfo, version, repo, donations, supportedAudio } from "../config.js";
|
||||
import { checkbox, collapsibleList, explanation, footerButtons, multiPagePopup, popup, popupWithBottomButtons, sep, settingsCategory, switcher, socialLink } from "./elements.js";
|
||||
import { services as s, authorInfo, version, repo, donations, supportedAudio } from "../config.js";
|
||||
import { getCommitInfo } from "../sub/currentCommit.js";
|
||||
import loc from "../../localization/manager.js";
|
||||
import emoji from "../emoji.js";
|
||||
@@ -30,6 +30,7 @@ for (let i in donations["crypto"]) {
|
||||
|
||||
export default function(obj) {
|
||||
const t = (str, replace) => { return loc(obj.lang, str, replace) };
|
||||
|
||||
let ua = obj.useragent.toLowerCase();
|
||||
let isIOS = ua.match("iphone os");
|
||||
let isMobile = ua.match("android") || ua.match("iphone os");
|
||||
@@ -40,26 +41,32 @@ export default function(obj) {
|
||||
audioFormats[0]["text"] = t('SettingsAudioFormatBest');
|
||||
|
||||
try {
|
||||
return `<!DOCTYPE html>
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="${obj.lang}">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="viewport-fit=cover width=device-width, initial-scale=1, maximum-scale=${isIOS ? `1` : `5`}" />
|
||||
<meta name="viewport" content="viewport-fit=cover, width=device-width, height=device-height, initial-scale=1, maximum-scale=${isIOS ? `1` : `5`}" />
|
||||
|
||||
<title>${appName}</title>
|
||||
<title>${t("AppTitleCobalt")}</title>
|
||||
|
||||
<meta property="og:url" content="${process.env.webURL || process.env.selfURL}" />
|
||||
<meta property="og:title" content="${appName}" />
|
||||
<meta property="og:title" content="${t("AppTitleCobalt")}" />
|
||||
<meta property="og:description" content="${t('EmbedBriefDescription')}" />
|
||||
<meta property="og:image" content="${process.env.webURL || process.env.selfURL}icons/generic.png" />
|
||||
<meta name="title" content="${appName}" />
|
||||
<meta name="title" content="${t("AppTitleCobalt")}" />
|
||||
<meta name="description" content="${t('AboutSummary')}" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="${t("AppTitleCobalt")}">
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="icons/favicon.ico" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png" />
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png" />
|
||||
|
||||
<link rel="manifest" href="manifest.webmanifest" />
|
||||
@@ -69,9 +76,10 @@ export default function(obj) {
|
||||
<noscript><div style="margin: 2rem;">${t('NoScriptMessage')}</div></noscript>
|
||||
</head>
|
||||
<body id="cobalt-body" ${platform === "p" ? 'class="desktop"' : ''} data-nosnippet ontouchstart>
|
||||
<body id="notification-area"></div>
|
||||
${multiPagePopup({
|
||||
name: "about",
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
tabs: [{
|
||||
name: "about",
|
||||
title: `${emoji("🐲")} ${t('AboutTab')}`,
|
||||
@@ -82,30 +90,40 @@ export default function(obj) {
|
||||
text: t('MadeWithLove'),
|
||||
url: authorInfo.link
|
||||
},
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
title: `${emoji("🔮", 30)} ${t('TitlePopupAbout')}`
|
||||
},
|
||||
body: [{
|
||||
text: t('AboutSummary')
|
||||
}, {
|
||||
text: collapsibleList([{
|
||||
"name": "services",
|
||||
"title": t("CollapseServices"),
|
||||
"body": `${enabledServices}<br/><br/>${t("ServicesNote")}`
|
||||
name: "services",
|
||||
title: t("CollapseServices"),
|
||||
body: `${enabledServices}<br/><br/>${t("ServicesNote")}`
|
||||
}, {
|
||||
"name": "support",
|
||||
"title": t("CollapseSupport"),
|
||||
"body": `${t("FollowSupport")}<br/>
|
||||
${socialLink(emoji("🐦"), "twitter", authorInfo.support.twitter.handle, authorInfo.support.twitter.url)}
|
||||
${socialLink(emoji("👾"), "discord", authorInfo.support.discord.handle, authorInfo.support.discord.url)}
|
||||
${socialLink(emoji("🐘"), "mastodon", authorInfo.support.mastodon.handle, authorInfo.support.mastodon.url)}<br/>
|
||||
name: "support",
|
||||
title: t("CollapseSupport"),
|
||||
body: `
|
||||
${t("SupportSelfTroubleshooting")}<br/>
|
||||
${t("FollowSupport")}<br/>
|
||||
${socialLink(
|
||||
emoji("🐦"), "twitter", authorInfo.support.twitter.handle, authorInfo.support.twitter.url
|
||||
)}
|
||||
${socialLink(
|
||||
emoji("👾"), "discord", authorInfo.support.discord.handle, authorInfo.support.discord.url
|
||||
)}
|
||||
${socialLink(
|
||||
emoji("🐘"), "mastodon", authorInfo.support.mastodon.handle, authorInfo.support.mastodon.url
|
||||
)}<br/>
|
||||
${t("SourceCode")}<br/>
|
||||
${socialLink(emoji("🐙"), "github", repo.replace("https://github.com/", ''), repo)}<br/>
|
||||
${socialLink(
|
||||
emoji("🐙"), "github", repo.replace("https://github.com/", ''), repo
|
||||
)}<br/>
|
||||
${t("SupportNote")}`
|
||||
}, {
|
||||
"name": "privacy",
|
||||
"title": t("CollapsePrivacy"),
|
||||
"body": t("PrivacyPolicy")
|
||||
name: "privacy",
|
||||
title: t("CollapsePrivacy"),
|
||||
body: t("PrivacyPolicy")
|
||||
}])
|
||||
}]
|
||||
})
|
||||
@@ -115,7 +133,7 @@ export default function(obj) {
|
||||
content: popup({
|
||||
name: "changelog",
|
||||
header: {
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
title: `${emoji("🪄", 30)} ${t('TitlePopupChangelog')}`
|
||||
},
|
||||
body: [{
|
||||
@@ -123,8 +141,14 @@ export default function(obj) {
|
||||
raw: true
|
||||
}, {
|
||||
text: changelogManager("banner") ?
|
||||
`<div class="changelog-banner"><img class="changelog-img" src="${changelogManager("banner")}" onerror="this.style.display='none'" loading="lazy"></img></div>`: '',
|
||||
`<div class="changelog-banner">
|
||||
<img class="changelog-img" src="${changelogManager("banner")}" onerror="this.style.display='none'" loading="lazy"></img>
|
||||
</div>`: '',
|
||||
raw: true
|
||||
}, {
|
||||
text: changelogManager("version"),
|
||||
classes: ["changelog-tags"],
|
||||
nopadding: true
|
||||
}, {
|
||||
text: changelogManager("title"),
|
||||
classes: ["changelog-subtitle"],
|
||||
@@ -132,19 +156,26 @@ export default function(obj) {
|
||||
}, {
|
||||
text: changelogManager("content")
|
||||
}, {
|
||||
text: `${sep()}<span class="text-backdrop">${obj.hash}:</span> ${com[0]}`,
|
||||
text: sep(),
|
||||
raw: true
|
||||
},{
|
||||
text: `<a class="text-backdrop changelog-tag-version" href="${repo}/commit/${obj.hash}">#${obj.hash}</a>`,
|
||||
classes: ["changelog-tags"],
|
||||
nopadding: true
|
||||
}, {
|
||||
text: com[0],
|
||||
classes: ["changelog-subtitle"],
|
||||
nopadding: true
|
||||
}, {
|
||||
text: com[1]
|
||||
}, {
|
||||
text: backdropLink(`${repo}/commits`, t('LinkGitHubChanges')),
|
||||
classes: ["bottom-link"]
|
||||
}, {
|
||||
text: `<div class="category-title">${t('ChangelogOlder')}</div>`,
|
||||
raw: true
|
||||
}, {
|
||||
text: `<div id="changelog-history"><button class="switch bottom-margin" onclick="loadOnDemand('changelog-history', '0')">${t("ChangelogPressToExpand")}</button></div>`,
|
||||
text: `
|
||||
<div id="changelog-history">
|
||||
<button class="switch bottom-margin" onclick="loadOnDemand('changelog-history', '0')">${t("ChangelogPressToExpand")}</button>
|
||||
</div>`,
|
||||
raw: true
|
||||
}]
|
||||
})
|
||||
@@ -154,14 +185,17 @@ export default function(obj) {
|
||||
content: popup({
|
||||
name: "donate",
|
||||
header: {
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
title: emoji("💸", 30) + t('TitlePopupDonate')
|
||||
},
|
||||
body: [{
|
||||
text: `<div class="category-title">${t('DonateSub')}</div>`,
|
||||
raw: true
|
||||
}, {
|
||||
text: `<div class="changelog-banner"><img class="changelog-img" src="updateBanners/catsleep.webp" onerror="this.style.display='none'" loading="lazy"></img></div>`,
|
||||
text: `
|
||||
<div class="changelog-banner">
|
||||
<img class="changelog-img" src="updateBanners/catsleep.webp" onerror="this.style.display='none'" loading="lazy"></img>
|
||||
</div>`,
|
||||
raw: true
|
||||
}, {
|
||||
text: t('DonateExplanation')
|
||||
@@ -189,7 +223,7 @@ export default function(obj) {
|
||||
})}
|
||||
${multiPagePopup({
|
||||
name: "settings",
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
header: {
|
||||
aboveTitle: {
|
||||
text: `v.${version}-${obj.hash}${platform} (${obj.branch})`,
|
||||
@@ -207,33 +241,37 @@ export default function(obj) {
|
||||
name: "vQuality",
|
||||
explanation: t('SettingsQualityDescription'),
|
||||
items: [{
|
||||
"action": "max",
|
||||
"text": "4320p+"
|
||||
action: "max",
|
||||
text: "8k+"
|
||||
}, {
|
||||
"action": "2160",
|
||||
"text": "2160p"
|
||||
action: "2160",
|
||||
text: "4k"
|
||||
}, {
|
||||
"action": "1440",
|
||||
"text": "1440p"
|
||||
action: "1440",
|
||||
text: "1440p"
|
||||
}, {
|
||||
"action": "1080",
|
||||
"text": "1080p"
|
||||
action: "1080",
|
||||
text: "1080p"
|
||||
}, {
|
||||
"action": "720",
|
||||
"text": "720p"
|
||||
action: "720",
|
||||
text: "720p"
|
||||
}, {
|
||||
"action": "480",
|
||||
"text": "480p"
|
||||
action: "480",
|
||||
text: "480p"
|
||||
}, {
|
||||
"action": "360",
|
||||
"text": "360p"
|
||||
action: "360",
|
||||
text: "360p"
|
||||
}]
|
||||
})
|
||||
})
|
||||
+ settingsCategory({
|
||||
name: "tiktok",
|
||||
title: "tiktok",
|
||||
body: checkbox("disableTikTokWatermark", t('SettingsRemoveWatermark'), 3)
|
||||
body: checkbox([{
|
||||
action: "disableTikTokWatermark",
|
||||
name: t("SettingsRemoveWatermark"),
|
||||
padding: "no-margin"
|
||||
}])
|
||||
})
|
||||
+ settingsCategory({
|
||||
name: t('SettingsCodecSubtitle'),
|
||||
@@ -241,14 +279,14 @@ export default function(obj) {
|
||||
name: "vCodec",
|
||||
explanation: t('SettingsCodecDescription'),
|
||||
items: [{
|
||||
"action": "h264",
|
||||
"text": "h264 (mp4)"
|
||||
action: "h264",
|
||||
text: "h264 (mp4)"
|
||||
}, {
|
||||
"action": "av1",
|
||||
"text": "av1 (mp4)"
|
||||
action: "av1",
|
||||
text: "av1 (mp4)"
|
||||
}, {
|
||||
"action": "vp9",
|
||||
"text": "vp9 (webm)"
|
||||
action: "vp9",
|
||||
text: "vp9 (webm)"
|
||||
}]
|
||||
})
|
||||
})
|
||||
@@ -258,11 +296,11 @@ export default function(obj) {
|
||||
name: "vimeoDash",
|
||||
explanation: t('SettingsVimeoPreferDescription'),
|
||||
items: [{
|
||||
"action": "false",
|
||||
"text": "progressive"
|
||||
action: "false",
|
||||
text: "progressive"
|
||||
}, {
|
||||
"action": "true",
|
||||
"text": "dash"
|
||||
action: "true",
|
||||
text: "dash"
|
||||
}]
|
||||
})
|
||||
})
|
||||
@@ -272,31 +310,44 @@ export default function(obj) {
|
||||
content: settingsCategory({
|
||||
name: "general",
|
||||
title: t('SettingsFormatSubtitle'),
|
||||
body:
|
||||
switcher({
|
||||
name: "aFormat",
|
||||
explanation: t('SettingsAudioFormatDescription'),
|
||||
items: audioFormats
|
||||
}) + sep(0) + checkbox("muteAudio", t('SettingsVideoMute'), 3) + explanation(t('SettingsVideoMuteExplanation'))
|
||||
}) + settingsCategory({
|
||||
name: "dub",
|
||||
title: t("SettingsAudioDub"),
|
||||
body: switcher({
|
||||
name: "dubLang",
|
||||
explanation: t('SettingsAudioDubDescription'),
|
||||
items: [{
|
||||
"action": "original",
|
||||
"text": t('SettingsDubDefault')
|
||||
}, {
|
||||
"action": "auto",
|
||||
"text": t('SettingsDubAuto')
|
||||
}]
|
||||
})
|
||||
}) + settingsCategory({
|
||||
name: "tiktok",
|
||||
title: "tiktok",
|
||||
body: checkbox("fullTikTokAudio", t('SettingsAudioFullTikTok'), 3) + explanation(t('SettingsAudioFullTikTokDescription'))
|
||||
})
|
||||
body: switcher({
|
||||
name: "aFormat",
|
||||
explanation: t('SettingsAudioFormatDescription'),
|
||||
items: audioFormats
|
||||
})
|
||||
+ sep(0)
|
||||
+ checkbox([{
|
||||
action: "muteAudio",
|
||||
name: t("SettingsVideoMute"),
|
||||
padding: "no-margin"
|
||||
}])
|
||||
+ explanation(t('SettingsVideoMuteExplanation'))
|
||||
})
|
||||
+ settingsCategory({
|
||||
name: "dub",
|
||||
title: t("SettingsAudioDub"),
|
||||
body: switcher({
|
||||
name: "dubLang",
|
||||
explanation: t('SettingsAudioDubDescription'),
|
||||
items: [{
|
||||
action: "original",
|
||||
text: t('SettingsDubDefault')
|
||||
}, {
|
||||
action: "auto",
|
||||
text: t('SettingsDubAuto')
|
||||
}]
|
||||
})
|
||||
})
|
||||
+ settingsCategory({
|
||||
name: "tiktok",
|
||||
title: "tiktok",
|
||||
body: checkbox([{
|
||||
action: "fullTikTokAudio",
|
||||
name: t("SettingsAudioFullTikTok"),
|
||||
padding: "no-margin"
|
||||
}])
|
||||
+ explanation(t('SettingsAudioFullTikTokDescription'))
|
||||
})
|
||||
}, {
|
||||
name: "other",
|
||||
title: `${emoji("🪅")} ${t('SettingsOtherTab')}`,
|
||||
@@ -307,26 +358,51 @@ export default function(obj) {
|
||||
name: "theme",
|
||||
subtitle: t('SettingsThemeSubtitle'),
|
||||
items: [{
|
||||
"action": "auto",
|
||||
"text": t('SettingsThemeAuto')
|
||||
action: "auto",
|
||||
text: t('SettingsThemeAuto')
|
||||
}, {
|
||||
"action": "dark",
|
||||
"text": t('SettingsThemeDark')
|
||||
action: "dark",
|
||||
text: t('SettingsThemeDark')
|
||||
}, {
|
||||
"action": "light",
|
||||
"text": t('SettingsThemeLight')
|
||||
action: "light",
|
||||
text: t('SettingsThemeLight')
|
||||
}]
|
||||
}) + checkbox("alwaysVisibleButton", t('SettingsKeepDownloadButton'), 4, t('AccessibilityKeepDownloadButton'))
|
||||
}) + settingsCategory({
|
||||
})
|
||||
})
|
||||
+ settingsCategory({
|
||||
name: "accessibility",
|
||||
title: t('Accessibility'),
|
||||
body: checkbox([{
|
||||
action: "alwaysVisibleButton",
|
||||
name: t("SettingsKeepDownloadButton"),
|
||||
aria: t("AccessibilityKeepDownloadButton")
|
||||
}, {
|
||||
action: "reduceTransparency",
|
||||
name: t("SettingsReduceTransparency")
|
||||
}, {
|
||||
action: "disableAnimations",
|
||||
name: t("SettingsDisableAnimations"),
|
||||
padding: "no-margin"
|
||||
}])
|
||||
})
|
||||
+ settingsCategory({
|
||||
name: "miscellaneous",
|
||||
title: t('Miscellaneous'),
|
||||
body: checkbox("disableChangelog", t('SettingsDisableNotifications')) + `${!isIOS ? checkbox("downloadPopup", t('SettingsEnableDownloadPopup'), 1, t('AccessibilityEnableDownloadPopup')) : ''}`
|
||||
body: checkbox([{
|
||||
action: "disableChangelog",
|
||||
name: t("SettingsDisableNotifications")
|
||||
}, {
|
||||
action: "downloadPopup",
|
||||
name: t("SettingsEnableDownloadPopup"),
|
||||
padding: "no-margin",
|
||||
aria: t("AccessibilityEnableDownloadPopup")
|
||||
}])
|
||||
})
|
||||
}],
|
||||
})}
|
||||
${popupWithBottomButtons({
|
||||
name: "picker",
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
header: {
|
||||
title: `<div id="picker-title"></div>`,
|
||||
explanation: `<div id="picker-subtitle"></div>`,
|
||||
@@ -334,100 +410,109 @@ export default function(obj) {
|
||||
buttons: [`<a id="picker-download" class="switch" target="_blank" href="/">${t('ImagePickerDownloadAudio')}</a>`],
|
||||
content: '<div id="picker-holder"></div>'
|
||||
})}
|
||||
${popup({
|
||||
name: "download",
|
||||
standalone: true,
|
||||
buttonOnly: true,
|
||||
classes: ["small"],
|
||||
header: {
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
emoji: emoji("🐱", 78, 1, 1),
|
||||
title: t('TitlePopupDownload')
|
||||
},
|
||||
body: switcher({
|
||||
<div id="popup-download-container" class="popup-from-bottom">
|
||||
${popup({
|
||||
name: "download",
|
||||
explanation: `${!isIOS ? t('DownloadPopupDescription') : t('DownloadPopupDescriptionIOS')}`,
|
||||
items: `<a id="pd-download" class="switch full" target="_blank" href="/">${t('Download')}</a>
|
||||
<div id="pd-share" class="switch full">${t('ShareURL')}</div>
|
||||
<div id="pd-copy" class="switch full">${t('CopyURL')}</div>`
|
||||
}),
|
||||
buttonText: t('PopupCloseDone')
|
||||
})}
|
||||
${popup({
|
||||
name: "error",
|
||||
standalone: true,
|
||||
buttonOnly: true,
|
||||
classes: ["small"],
|
||||
header: {
|
||||
closeAria: t('AccessibilityClosePopup'),
|
||||
title: t('TitlePopupError'),
|
||||
emoji: emoji("😿", 78, 1, 1),
|
||||
},
|
||||
body: `<div id="desc-error" class="desc-padding subtext"></div>`,
|
||||
buttonText: t('ErrorPopupCloseButton')
|
||||
})}
|
||||
<div id="popup-backdrop" style="visibility: hidden;" onclick="hideAllPopups()"></div>
|
||||
<div id="urgent-notice" class="urgent-notice explanation center" onclick="popup('about', 1, 'donate')" style="visibility: hidden;">${emoji("💖", 18)} ${t("UrgentDonate")}</div>
|
||||
<div id="cobalt-main-box" class="center" style="visibility: hidden;">
|
||||
<div id="logo">${appName}</div>
|
||||
<div id="download-area">
|
||||
<div id="top">
|
||||
<input id="url-input-area" class="mono" type="text" autocorrect="off" maxlength="128" autocapitalize="off" placeholder="${t('LinkInput')}" aria-label="${t('AccessibilityInputArea')}" oninput="button()"></input>
|
||||
<button id="url-clear" onclick="clearInput()" style="display:none;">x</button>
|
||||
<input id="download-button" class="mono dontRead" onclick="download(document.getElementById('url-input-area').value)" type="submit" value="" disabled=true aria-label="${t('AccessibilityDownloadButton')}">
|
||||
</div>
|
||||
<div id="bottom">
|
||||
<button id="paste" class="switch" onclick="pasteClipboard()" aria-label="${t('PasteFromClipboard')}">${emoji("📋", 22)} ${t('PasteFromClipboard')}</button>
|
||||
${switcher({
|
||||
name: "audioMode",
|
||||
noParent: true,
|
||||
items: [{
|
||||
"action": "false",
|
||||
"text": `${emoji("✨")} ${t("ModeToggleAuto")}`
|
||||
}, {
|
||||
"action": "true",
|
||||
"text": `${emoji("🎶")} ${t("ModeToggleAudio")}`
|
||||
}]
|
||||
})}
|
||||
standalone: true,
|
||||
buttonOnly: true,
|
||||
classes: ["small", "glass-bkg"],
|
||||
header: {
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
emoji: emoji("🐱", 78, 1, 1),
|
||||
title: t('TitlePopupDownload')
|
||||
},
|
||||
body: switcher({
|
||||
name: "download",
|
||||
explanation: `${!isIOS ? t('DownloadPopupDescription') : t('DownloadPopupDescriptionIOS')}`,
|
||||
items: `<a id="pd-download" class="switch full" target="_blank" href="/"><span>${t('Download')}</span></a>
|
||||
<div id="pd-share" class="switch full">${t('ShareURL')}</div>
|
||||
<div id="pd-copy" class="switch full">${t('CopyURL')}</div>`
|
||||
}),
|
||||
buttonText: t('PopupCloseDone')
|
||||
})}
|
||||
</div>
|
||||
<div id="popup-error-container" class="popup-from-bottom">
|
||||
${popup({
|
||||
name: "error",
|
||||
standalone: true,
|
||||
buttonOnly: true,
|
||||
classes: ["small", "glass-bkg"],
|
||||
header: {
|
||||
closeAria: t('AccessibilityGoBack'),
|
||||
title: t('TitlePopupError'),
|
||||
emoji: emoji("😿", 78, 1, 1),
|
||||
},
|
||||
body: `<div id="desc-error" class="desc-padding subtext"></div>`,
|
||||
buttonText: t('ErrorPopupCloseButton')
|
||||
})}
|
||||
</div>
|
||||
<div id="popup-backdrop" onclick="hideAllPopups()"></div>
|
||||
<div id="home">
|
||||
<div id="urgent-notice" class="urgent-notice explanation" onclick="popup('about', 1, 'donate')" style="visibility: hidden;">${emoji("💖", 18)} ${t("UrgentDonate")}</div>
|
||||
<div id="cobalt-main-box" class="center" style="visibility: hidden;">
|
||||
<div id="logo">${t("AppTitleCobalt")}</div>
|
||||
<div id="download-area">
|
||||
<div id="top">
|
||||
<input id="url-input-area" class="mono" type="text" autocorrect="off" maxlength="128" autocapitalize="off" placeholder="${t('LinkInput')}" aria-label="${t('AccessibilityInputArea')}" oninput="button()"></input>
|
||||
<button id="url-clear" onclick="clearInput()" style="display:none;">x</button>
|
||||
<input id="download-button" class="mono dontRead" onclick="download(document.getElementById('url-input-area').value)" type="submit" value="" disabled=true aria-label="${t('AccessibilityDownloadButton')}">
|
||||
</div>
|
||||
<div id="bottom">
|
||||
<button id="paste" class="switch" onclick="pasteClipboard()" aria-label="${t('PasteFromClipboard')}">${emoji("📋", 22)} ${t('PasteFromClipboard')}</button>
|
||||
${switcher({
|
||||
name: "audioMode",
|
||||
noParent: true,
|
||||
items: [{
|
||||
action: "false",
|
||||
text: `${emoji("✨")} ${t("ModeToggleAuto")}`
|
||||
}, {
|
||||
action: "true",
|
||||
text: `${emoji("🎶")} ${t("ModeToggleAudio")}`
|
||||
}]
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer id="footer" style="visibility: hidden;">
|
||||
${footerButtons([{
|
||||
name: "about",
|
||||
type: "popup",
|
||||
text: `${emoji("🐲" , 22)} ${t('AboutTab')}`,
|
||||
aria: t('AccessibilityOpenAbout')
|
||||
}, {
|
||||
name: "about",
|
||||
type: "popup",
|
||||
context: "donate",
|
||||
text: `${emoji("💖", 22)} ${t('Donate')}`,
|
||||
aria: t('AccessibilityOpenDonate')
|
||||
}, {
|
||||
name: "settings",
|
||||
type: "popup",
|
||||
text: `${emoji("⚙️", 22)} ${t('TitlePopupSettings')}`,
|
||||
aria: t('AccessibilityOpenSettings')
|
||||
}])}
|
||||
</footer>
|
||||
</div>
|
||||
<footer id="footer" style="visibility: hidden;">
|
||||
${/* big action buttons are ALWAYS either first or last, because usual buttons are bundled in pairs and are sandwiched between bigger buttons for mobile view */
|
||||
footerButtons([{
|
||||
name: "about",
|
||||
type: "popup",
|
||||
text: `${emoji("🐲" , 22)} ${t('AboutTab')}`,
|
||||
aria: t('AccessibilityOpenAbout')
|
||||
}, {
|
||||
name: "about",
|
||||
type: "popup",
|
||||
context: "donate",
|
||||
text: `${emoji("💖", 22)} ${t('Donate')}`,
|
||||
aria: t('AccessibilityOpenDonate')
|
||||
}, {
|
||||
name: "settings",
|
||||
type: "popup",
|
||||
text: `${emoji("⚙️", 22)} ${t('TitlePopupSettings')}`,
|
||||
aria: t('AccessibilityOpenSettings')
|
||||
}])}
|
||||
</footer>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
const loc = {
|
||||
noInternet: ` + "`" + t('ErrorNoInternet') + "`" + `,
|
||||
noURLReturned: ` + "`" + t('ErrorNoUrlReturned') + "`" + `,
|
||||
unknownStatus: ` + "`" + t('ErrorUnknownStatus') + "`" + `,
|
||||
collapseHistory: ` + "`" + t('ChangelogPressToHide') + "`" + `,
|
||||
pickerDefault: ` + "`" + t('MediaPickerTitle') + "`" + `,
|
||||
pickerImages: ` + "`" + t('ImagePickerTitle') + "`" + `,
|
||||
pickerImagesExpl: ` + "`" + t(`ImagePickerExplanation${isMobile ? "Phone" : "PC"}`) + "`" + `,
|
||||
pickerDefaultExpl: ` + "`" + t(`MediaPickerExplanation${isMobile ? `Phone${isIOS ? "IOS" : ""}` : "PC"}`) + "`" + `,
|
||||
};
|
||||
let apiURL = '${process.env.apiURL ? process.env.apiURL.slice(0, -1) : ''}';
|
||||
const loc = {
|
||||
noInternet: ` + "`" + t('ErrorNoInternet') + "`" + `,
|
||||
noURLReturned: ` + "`" + t('ErrorNoUrlReturned') + "`" + `,
|
||||
unknownStatus: ` + "`" + t('ErrorUnknownStatus') + "`" + `,
|
||||
collapseHistory: ` + "`" + t('ChangelogPressToHide') + "`" + `,
|
||||
pickerDefault: ` + "`" + t('MediaPickerTitle') + "`" + `,
|
||||
pickerImages: ` + "`" + t('ImagePickerTitle') + "`" + `,
|
||||
pickerImagesExpl: ` + "`" + t(`ImagePickerExplanation${isMobile ? "Phone" : "PC"}`) + "`" + `,
|
||||
pickerDefaultExpl: ` + "`" + t(`MediaPickerExplanation${isMobile ? "Phone" : "PC"}`) + "`" + `,
|
||||
featureErrorGeneric: ` + "`" + t('FeatureErrorGeneric') + "`" + `,
|
||||
clipboardErrorNoPermission: ` + "`" + t('ClipboardErrorNoPermission') + "`" + `,
|
||||
clipboardErrorFirefox: ` + "`" + t('ClipboardErrorFirefox') + "`" + `,
|
||||
};
|
||||
let apiURL = '${process.env.apiURL ? process.env.apiURL.slice(0, -1) : ''}';
|
||||
</script>
|
||||
<script type="text/javascript" src="cobalt.js"></script>
|
||||
</html>`;
|
||||
</html>
|
||||
`
|
||||
} catch (err) {
|
||||
return `${t('ErrorPageRenderFail', obj.hash)}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user