diff --git a/package.json b/package.json index 77a8ab9..c755a84 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "5.2.2", + "version": "5.3", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", diff --git a/src/front/cobalt.css b/src/front/cobalt.css index 80c5e09..5e6a529 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -8,6 +8,7 @@ --line-height: 1.65rem; --red: rgb(255, 0, 61); --color: rgb(107, 67, 139); + --gap: 0.6rem; } @media (prefers-color-scheme: dark) { :root { @@ -179,14 +180,17 @@ input[type="checkbox"] { position: fixed; width: 60%; height: auto; - display: inline-flex; + display: flex; + flex-direction: row; } -#logo-area { - padding-right: 3rem; - padding-top: 0.1rem; +#logo { text-align: left; font-size: 1rem; white-space: nowrap; + width: 7rem; + height: 2.5rem; + align-items: center; + display: flex; } #download-area { display: flex; @@ -196,7 +200,6 @@ input[type="checkbox"] { #cobalt-main-box #top { display: inline-flex; height: 2.5rem; - margin-top: -0.6rem; flex-direction: row; } #cobalt-main-box #bottom { @@ -222,13 +225,11 @@ input[type="checkbox"] { font-size: 0.8rem; } #url-clear { + height: 100%; background: none; - padding: 0 1.1rem; - font-size: 1rem; + padding: 0 1rem 0.2rem; transform: none; - line-height: 0; - height: 1.6rem; - margin-top: .4rem; + font-size: 1rem; } #url-input-area:focus { outline: none; @@ -260,7 +261,7 @@ input[type="checkbox"] { #cobalt-main-box #bottom, #footer-buttons, #footer-buttons, .footer-pair { - gap: 0.6rem; + gap: var(--gap); } #footer-buttons, .footer-pair { display: flex; @@ -270,7 +271,7 @@ input[type="checkbox"] { .footer-button { width: auto!important; color: var(--accent-unhover-2); - padding: 0.6rem 1.2rem!important; + padding: var(--gap) 1.2rem!important; align-content: center; } .notification-dot { @@ -339,7 +340,6 @@ input[type="checkbox"] { } .changelog-banner { width: 100%; - background-color: var(--accent-button-bg); max-height: 300px; margin-bottom: 1.65rem; float: left; @@ -488,7 +488,7 @@ input[type="checkbox"] { .switch { padding: 0.7rem; width: 100%; - text-align: center; + text-align: left; color: var(--accent); background: var(--accent-button-bg); display: flex; @@ -601,7 +601,7 @@ input[type="checkbox"] { position: absolute; background: var(--background); color: var(--accent); - padding: 0.3rem 0.6rem; + padding: 0.3rem var(--gap); font-size: 0.8rem; opacity: 0.7; margin: 0.4rem; @@ -612,7 +612,7 @@ input[type="checkbox"] { } #cobalt-main-box #bottom button { width: auto; - padding: 0.6rem 1.2rem; + padding: var(--gap) 1.2rem; } .collapse-list { background: var(--accent-press); @@ -723,11 +723,6 @@ input[type="checkbox"] { padding-bottom: 2rem; } } -@media screen and (min-width: 720px) { - #leftHandedLayout-chkbx { - display: none; - } -} /* mobile page */ @media screen and (max-width: 720px) { #cobalt-main-box, #footer { @@ -753,9 +748,18 @@ input[type="checkbox"] { font-size: 1.3rem; line-height: 2rem; } - .footer-button { + .footer-button, + #audioMode-false, + #audioMode-true, + #paste { font-size: 0!important; } + .footer-button .emoji, + #audioMode-false .emoji, + #audioMode-true .emoji, + #paste .emoji { + margin-right: 0; + } .switch, .checkbox, .category-title, .subtitle, #popup-desc { font-size: .75rem; } @@ -772,27 +776,14 @@ input[type="checkbox"] { .category-title { margin-bottom: 0.8rem; } - .footer-button .emoji { - margin-right: 0; - } } @media screen and (max-width: 720px) { + #cobalt-main-box #bottom { + flex-direction: column-reverse; + } #cobalt-main-box #bottom button { width: 100%; } - #cobalt-main-box #bottom { - flex-direction: row-reverse; - } - #cobalt-main-box #bottom[data-lefthanded="true"] { - flex-direction: row; - } - #pasteFromClipboard .emoji { - margin-right: 0; - } - #pasteFromClipboard { - width: 20%!important; - font-size: 0; - } #footer { bottom: 4%; transform: translate(-50%, 0%); @@ -804,19 +795,17 @@ input[type="checkbox"] { .footer-pair .footer-button { width: 100%!important; } - #logo-area { - padding-right: 0; - padding-top: 0; - position: fixed; - line-height: 0; - margin-top: -2rem; + #logo { width: 100%; - text-align: center; + height: auto; + justify-content: center; } #cobalt-main-box { display: flex; border: none; padding: 0; + flex-direction: column; + gap: var(--gap); } } @media screen and (max-width: 949px) { diff --git a/src/front/cobalt.js b/src/front/cobalt.js index 7b6a7dd..a6ac7fb 100644 --- a/src/front/cobalt.js +++ b/src/front/cobalt.js @@ -13,9 +13,10 @@ let switchers = { "vQuality": ["1080", "max", "2160", "1440", "720", "480", "360"], "aFormat": ["mp3", "best", "ogg", "wav", "opus"], "dubLang": ["original", "auto"], - "vimeoDash": ["false", "true"] + "vimeoDash": ["false", "true"], + "audioMode": ["false", "true"] } -let checkboxes = ["disableTikTokWatermark", "fullTikTokAudio", "muteAudio", "leftHandedLayout"]; +let checkboxes = ["disableTikTokWatermark", "fullTikTokAudio", "muteAudio"]; let exceptions = { // used for mobile devices "vQuality": "720" } @@ -244,37 +245,14 @@ function checkbox(action) { sSet(action, !!eid(action).checked); switch(action) { case "alwaysVisibleButton": button(); break; - case "leftHandedLayout": - eid("bottom").setAttribute("data-lefthanded", sGet("leftHandedLayout")); - break; } - sGet(action) === "true" ? notificationCheck("disable") : notificationCheck(); -} -function updateToggle(toggl, state) { - switch(state) { - case "true": - eid(toggl).innerHTML = loc.toggleAudio; - break; - case "false": - eid(toggl).innerHTML = loc.toggleDefault; - break; - } -} -function toggle(toggl) { - let state = sGet(toggl); - if (state) { - sSet(toggl, opposite(state)) - if (opposite(state) === "true") sSet(`${toggl}ToggledOnce`, "true"); - } else { - sSet(toggl, "false") - } - updateToggle(toggl, sGet(toggl)) + action === "disableChangelog" && sGet(action) === "true" ? notificationCheck("disable") : notificationCheck(); } function loadSettings() { try { if (typeof(navigator.clipboard.readText) == "undefined") throw new Error(); } catch (err) { - eid("pasteFromClipboard").style.display = "none" + eid("paste").style.display = "none"; } if (sGet("alwaysVisibleButton") === "true") { eid("alwaysVisibleButton").checked = true; @@ -284,13 +262,9 @@ function loadSettings() { if (sGet("downloadPopup") === "true" && !isIOS) { eid("downloadPopup").checked = true; } - if (!sGet("audioMode")) { - toggle("audioMode") - } for (let i = 0; i < checkboxes.length; i++) { if (sGet(checkboxes[i]) === "true") eid(checkboxes[i]).checked = true; } - updateToggle("audioMode", sGet("audioMode")); for (let i in switchers) { changeSwitcher(i, sGet(i)) } @@ -451,7 +425,6 @@ window.onload = () => { eid("cobalt-main-box").style.visibility = 'visible'; eid("footer").style.visibility = 'visible'; eid("url-input-area").value = ""; - eid("bottom").setAttribute("data-lefthanded", sGet("leftHandedLayout")); notificationCheck(); if (isIOS) sSet("downloadPopup", "true"); let urlQuery = new URLSearchParams(window.location.search).get("u"); @@ -470,4 +443,4 @@ eid("url-input-area").addEventListener("keyup", (event) => { document.onkeydown = (event) => { if (event.key === "Tab" || event.ctrlKey) eid("url-input-area").focus(); if (event.key === 'Escape') hideAllPopups(); -}; \ No newline at end of file +} diff --git a/src/front/updateBanners/cattired.webp b/src/front/updateBanners/cattired.webp new file mode 100644 index 0000000..f108ac8 Binary files /dev/null and b/src/front/updateBanners/cattired.webp differ diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json index 8fe874b..9600ae8 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -78,7 +78,7 @@ "ImagePickerExplanationPhone": "press and hold an image to save it.", "ErrorNoUrlReturned": "i didn't get a download link from the server. this should never happen. try again, but if it still doesn't work, {ContactLink}.", "ErrorUnknownStatus": "i received a response i can't process. this should never happen. try again, but if it still doesn't work, {ContactLink}.", - "PasteFromClipboard": "paste", + "PasteFromClipboard": "paste and download", "ChangelogOlder": "previous versions", "ChangelogPressToExpand": "expand", "Miscellaneous": "miscellaneous", @@ -117,7 +117,6 @@ "SettingsDubDefault": "original", "SettingsDubAuto": "auto", "SettingsVimeoPrefer": "vimeo downloads type", - "SettingsVimeoPreferDescription": "progressive: direct file link to vimeo's cdn. max quality is 1080p.\ndash: video and audio are merged by {appName} into one file. max quality is 4k.\n\npick \"progressive\" if you want best editor/player/social media compatibility. if progressive download isn't available, dash is used instead.", - "LeftHanded": "left-handed layout" + "SettingsVimeoPreferDescription": "progressive: direct file link to vimeo's cdn. max quality is 1080p.\ndash: video and audio are merged by {appName} into one file. max quality is 4k.\n\npick \"progressive\" if you want best editor/player/social media compatibility. if progressive download isn't available, dash is used instead." } } diff --git a/src/localization/languages/ru.json b/src/localization/languages/ru.json index 2612767..abcab52 100644 --- a/src/localization/languages/ru.json +++ b/src/localization/languages/ru.json @@ -78,7 +78,7 @@ "ImagePickerExplanationPhone": "зажми и удерживай картинку, чтобы её сохранить.", "ErrorNoUrlReturned": "я не получил ссылку для скачивания от сервера. такого происходить не должно. попробуй ещё раз, а если не поможет, то {ContactLink}.", "ErrorUnknownStatus": "сервер ответил мне чем-то непонятным. такого происходить не должно. попробуй ещё раз, а если не поможет, то {ContactLink}.", - "PasteFromClipboard": "вставить", + "PasteFromClipboard": "вставить и скачать", "ChangelogOlder": "предыдущие версии (на английском)", "ChangelogPressToExpand": "раскрыть", "Miscellaneous": "разное", @@ -117,7 +117,6 @@ "SettingsDubDefault": "оригинал", "SettingsDubAuto": "авто", "SettingsVimeoPrefer": "тип загрузок с vimeo", - "SettingsVimeoPreferDescription": "progressive: прямая ссылка на файл с сервера vimeo. максимальное качество: 1080p.\ndash: {appName} совмещает видео и аудио в один файл. максимальное качество: 4k.\n\nвыбирай \"progressive\", если тебе нужна наилучшая совместимость с плеерами/редакторами/соцсетями. если \"progressive\" файл недоступен, {appName} скачает \"dash\".", - "LeftHanded": "режим левши" + "SettingsVimeoPreferDescription": "progressive: прямая ссылка на файл с сервера vimeo. максимальное качество: 1080p.\ndash: {appName} совмещает видео и аудио в один файл. максимальное качество: 4k.\n\nвыбирай \"progressive\", если тебе нужна наилучшая совместимость с плеерами/редакторами/соцсетями. если \"progressive\" файл недоступен, {appName} скачает \"dash\"." } } diff --git a/src/modules/changelog/changelog.json b/src/modules/changelog/changelog.json index f4aaaba..1abf011 100644 --- a/src/modules/changelog/changelog.json +++ b/src/modules/changelog/changelog.json @@ -1,11 +1,16 @@ { "current": { + "version": "5.3", + "title": "better looks, better feel", + "banner": "cattired.webp", + "content": "this update isn't as big as previous ones, but it still greatly enhances the cobalt experience.\n\nhere's what's up:\n*; new mode switcher! elegant and 100% clear. should no longer cause any confusion. let me know if you like it better this way :D\n*; wide paste button on mobile is back, but now it's even closer to your finger.\n*; removed the weird grey chin on changelog banners.\n*; removed left-handed layout toggle since it is no longer needed.\n*; fixed input area display in chromium 112+.\n*; centered the main action box.\n*; cleaned up css of main action box to get rid of tricks and ensure correct display on all devices.\n\nhopefully from now on i'll focus on adding support for more services.\nthank you for using cobalt. stay cool :)" + }, + "history": [{ "version": "5.2", "title": "fastest one in the game", "banner": "catspeed.webp", "content": "hey, notice anything different? well, at very least the page loaded way faster! this update includes many improvements and fixes, but also some new features.\n\ntl;dr:\n*; twitter retweet links are now supported.\n*; all vimeo videos should now be possible to download.\n*; you now can download audio from vimeo.\n*; it's now possible to pick between preferred vimeo download method in settings.\n*; fixed issues related to tiktok, twitter, twitter spaces, and vimeo downloads.\n*; overall cobalt performance should be MUCH better.\n\nservice improvements:\n*; added support for twitter retweet links. now all kinds of tweet links are supported.\n*; fixed the issue related to periods in tiktok usernames (#96).\n*; fixed twitter spaces downloads.\n*; added support for audio downloads from vimeo.\n*; added ability to choose between \"progressive\" and \"dash\" vimeo downloads. go to settings > video to pick your preference.\n*; fixed the issue related to vimeo quality picking.\n*; fixed the issue when vimeo module wouldn't show appropriate errors and instead would fallback to default ones.\n*; improved audio only downloads for some edge cases.\n*; (hopefully) better youtube reliability.\n*; temporarily disabled douyin support due to api endpoint cut off.\n\ninterface improvements:\n*; merged clipboard and mode switcher rows into one for mobile view.\n*; added left-handed layout toggle for those who prefer to have the clipboard button on left.\n*; new custom-made clipboard icon. now it clearly indicates what it does.\n*; improved english and russian localization. both are way more direct and less bloaty.\n*; frontend page is now rendered once and is cached on disk instead of being rendered every time someone requests a page. this greatly improves page loading speeds and further reduces strain put on the server.\n*; frontend page is now minimized just like js and css files. this should minimize traffic wasted on loading the page, along with minor loading speed improvement.\n*; added proper checkbox icon for better clarity.\n*; checkboxes are now stretched edge-to-edge on phone to be easier to manage for right-handed people.\n*; removed button hover highlights on phones.\n*; fixed button press animations for safari on ios.\n*; fixed text selection on ios. previously you could select text or images anywhere, but now they're selectable in limited places, just like on other platforms.\n*; frontend platform is now marked in settings: p is for pc; m is for mobile; i is for ios. this is done for possible future debugging and issue-solving.\n*; better error messaging.\n\ninternal improvements:\n*; better rate limiting, there should be way less cases of accidental limits.\n*; added support for m3u8 playlists. this will be useful for future additions, and is currently used by vimeo module.\n*; added support for \"chop\" stream format for vimeo downloads.\n*; fixed vk user id extraction. i assumed the - in url was a separator, but it's actually a part of id.\n*; completely reworked the vimeo module. it's much cleaner and better performant now.\n*; minor clean ups across the board.\n\nnot really related to this update, but thank you for 50k monthly users! i really appreciate that you're still here, because that means i'm doing some things right :D" - }, - "history": [{ + }, { "version": "5.1", "title": "the evil has been defeated", "banner": "happymeowth.webp", diff --git a/src/modules/pageRender/elements.js b/src/modules/pageRender/elements.js index 43a4036..dc01612 100644 --- a/src/modules/pageRender/elements.js +++ b/src/modules/pageRender/elements.js @@ -10,6 +10,8 @@ export function switcher(obj) { items += `` } } + + if (obj.noParent) return `
${items}
`; return `
${obj.subtitle ? `
${obj.subtitle}
` : ``}
${items}
diff --git a/src/modules/pageRender/onDemand.js b/src/modules/pageRender/onDemand.js index ce29d64..65babd4 100644 --- a/src/modules/pageRender/onDemand.js +++ b/src/modules/pageRender/onDemand.js @@ -7,9 +7,9 @@ export function changelogHistory() { // blockId 0 let history = changelogManager("history"); let render = ``; - let historyLen = history.length + let historyLen = history.length; for (let i in history) { - let separator = (i !== 0 && i !== historyLen) ? '
' : '' + let separator = (i !== 0 && i !== historyLen) ? '
' : ''; render += `${separator}${history[i]["banner"] ? `
` : ''}` } cache['0'] = render; diff --git a/src/modules/pageRender/page.js b/src/modules/pageRender/page.js index f99941c..25e785b 100644 --- a/src/modules/pageRender/page.js +++ b/src/modules/pageRender/page.js @@ -314,7 +314,7 @@ export default function(obj) { "action": "light", "text": t('SettingsThemeLight') }] - }) + checkbox("alwaysVisibleButton", t('SettingsKeepDownloadButton'), 4, t('AccessibilityKeepDownloadButton')) + checkbox("leftHandedLayout", t('LeftHanded'), 4) + }) + checkbox("alwaysVisibleButton", t('SettingsKeepDownloadButton'), 4, t('AccessibilityKeepDownloadButton')) }) + settingsCategory({ name: "miscellaneous", title: t('Miscellaneous'), @@ -362,16 +362,26 @@ export default function(obj) { })}