diff --git a/src/front/cobalt.css b/src/front/cobalt.css index 5e6a5290..994305d2 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -862,4 +862,37 @@ input[type="checkbox"] { height: 6rem; width: 6rem; } +} +.dropdown-select { + display: inline-flex; + flex-direction: row; + align-items: center; + flex-wrap: nowrap; + /* padding: 0.55rem 1rem 0.8rem 0.7rem; */ + width: fit-content; + background: var(--accent-button-bg); + font-size: 0.9rem; +} +.dropdown-select label { + margin: 0.55rem var(--padding-1) 0.8rem 0.7rem; +} +.dropdown-select select { + background: var(--accent-button-bg); + font-family: var(--font-mono); + color: var(--accent); + line-height: 1.35rem; + height: 2.65rem; + border: none; +} +.dropdown-select select:hover { + background: var(--accent-hover); +} + +.dropdown-select select option:hover { + background: var(--accent-hover); +} + +.dropdown-select select option { + line-height: 0.9rem; + height: 2.25rem; } \ No newline at end of file diff --git a/src/front/cobalt.js b/src/front/cobalt.js index a6ac7fb3..7fc3f731 100644 --- a/src/front/cobalt.js +++ b/src/front/cobalt.js @@ -20,6 +20,7 @@ let checkboxes = ["disableTikTokWatermark", "fullTikTokAudio", "muteAudio"]; let exceptions = { // used for mobile devices "vQuality": "720" } +let dropdowns = ["language"] function eid(id) { return document.getElementById(id) @@ -30,6 +31,19 @@ function sGet(id) { function sSet(id, value) { localStorage.setItem(id, value) } +function setCookie(id, value, expire = 730, path = "/") { // by default expire in 2 years + const d = new Date(); + d.setTime(d.getTime() + (expire * 24 * 60 * 60 * 1000)); + document.cookie = `${id}=${value};expires=${d.toUTCString()};path=${path}`; +} +function getCookie(id) { + const cookies = {}; + for(let i of document.cookie.split(';')) { + const [key, value] = i.split('='); + cookies[key] = value; + } + return cookies[id]; +} function enable(id) { eid(id).dataset.enabled = "true"; } @@ -248,6 +262,15 @@ function checkbox(action) { } action === "disableChangelog" && sGet(action) === "true" ? notificationCheck("disable") : notificationCheck(); } +function dropdownSelect(action) { + let value = eid(`${action}-select`).value; + if(action === "language") { // language has to be a cookie because the server needs to read the value + setCookie(action, value); + window.location.reload(); + } else { + sSet(action, value) + } +} function loadSettings() { try { if (typeof(navigator.clipboard.readText) == "undefined") throw new Error(); @@ -268,6 +291,13 @@ function loadSettings() { for (let i in switchers) { changeSwitcher(i, sGet(i)) } + for (let i of dropdowns) { + if(i == 'language') { + eid(`${i}-select`).value = getCookie(i) || document.documentElement.lang; + } else{ + eid(`${i}-select`).value = sGet(i); + } + } } function changeButton(type, text) { switch (type) { @@ -443,4 +473,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/localization/languages/en.json b/src/localization/languages/en.json index 9600ae8d..083d226c 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -117,6 +117,8 @@ "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." + "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.", + "SettingsAccessibilitySubtitle": "accessibility", + "SettingsAccessibilityLanguage": "interface language:" } } diff --git a/src/localization/manager.js b/src/localization/manager.js index 65c048c8..14b70250 100644 --- a/src/localization/manager.js +++ b/src/localization/manager.js @@ -6,6 +6,7 @@ const locPath = './src/localization/languages' let loc = {} let languages = []; +let languageNames = []; export function loadLoc() { fs.readdir(locPath, (err, files) => { @@ -13,6 +14,7 @@ export function loadLoc() { files.forEach(file => { loc[file.split('.')[0]] = loadJson(`${locPath}/${file}`); languages.push(file.split('.')[0]) + languageNames.push({value: file.split('.')[0], name: loc[file.split('.')[0]].name }) }); }) } @@ -46,3 +48,4 @@ export default function(lang, string, replacement) { } } export const languageList = languages; +export const languagePickerNames = languageNames; \ No newline at end of file diff --git a/src/modules/pageRender/elements.js b/src/modules/pageRender/elements.js index dc016124..e24c0c63 100644 --- a/src/modules/pageRender/elements.js +++ b/src/modules/pageRender/elements.js @@ -173,3 +173,16 @@ export function celebrationsEmoji() { let dm = `${n[1]}-${n[2]}`; return Object.keys(celebrations).includes(dm) ? celebrations[dm] : "🐲"; } + +export function dropdownSelect(label, action, options) { + let items = ` +