123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- import { defaultFeatures, getFeatures, saveFeatureConf } from "../config";
- import { dbg, info } from "../constants";
- import { featInfo } from "./index";
- import { FeatureConfig } from "../types";
- import { addGlobalStyle } from "../utils";
- import changelog from "../../changelog.md";
- const branch = dbg ? "develop" : "main";
- //#MARKER menu
- /** Adds an element to open the BetterYTM menu */
- export async function addMenu() {
- // bg & menu
- const backgroundElem = document.createElement("div");
- backgroundElem.id = "betterytm-menu-bg";
- backgroundElem.title = "Click here to close the menu";
- backgroundElem.style.visibility = "hidden";
- backgroundElem.style.display = "none";
- backgroundElem.addEventListener("click", (e) => {
- if((e.target as HTMLElement).id === "betterytm-menu-bg")
- closeMenu();
- });
- const menuContainer = document.createElement("div");
- menuContainer.title = "";
- menuContainer.id = "betterytm-menu";
- menuContainer.style.borderRadius = "15px";
- menuContainer.style.display = "flex";
- menuContainer.style.flexDirection = "column";
- menuContainer.style.justifyContent = "space-between";
- // title
- const titleCont = document.createElement("div");
- titleCont.style.padding = "8px 20px 15px 8px";
- titleCont.style.display = "flex";
- titleCont.style.justifyContent = "space-between";
- titleCont.id = "betterytm-menu-titlecont";
- const titleElem = document.createElement("h2");
- titleElem.id = "betterytm-menu-title";
- titleElem.innerText = "BetterYTM - Configuration";
- const linksCont = document.createElement("div");
- linksCont.id = "betterytm-menu-linkscont";
- const addLink = (imgSrc: string, href: string, title: string) => {
- const anchorElem = document.createElement("a");
- anchorElem.className = "betterytm-menu-link";
- anchorElem.rel = "noopener noreferrer";
- anchorElem.target = "_blank";
- anchorElem.href = href;
- anchorElem.title = title;
- anchorElem.style.marginLeft = "10px";
-
- const imgElem = document.createElement("img");
- imgElem.className = "betterytm-menu-img";
- imgElem.src = imgSrc;
- imgElem.style.width = "32px";
- imgElem.style.height = "32px";
- anchorElem.appendChild(imgElem);
- linksCont.appendChild(anchorElem);
- };
- addLink(`https://raw.githubusercontent.com/Sv443/BetterYTM/${branch}/resources/external/github.png`, info.namespace, `${info.name} on GitHub`);
- addLink(`https://raw.githubusercontent.com/Sv443/BetterYTM/${branch}/resources/external/greasyfork.png`, "https://greasyfork.org/xyz", `${info.name} on GreasyFork`);
- const closeElem = document.createElement("img");
- closeElem.id = "betterytm-menu-close";
- closeElem.src = `https://raw.githubusercontent.com/Sv443/BetterYTM/${branch}/resources/icon/close.png`;
- closeElem.title = "Click to close the menu";
- closeElem.style.marginLeft = "50px";
- closeElem.style.width = "32px";
- closeElem.style.height = "32px";
- closeElem.addEventListener("click", closeMenu);
- linksCont.appendChild(closeElem);
- titleCont.appendChild(titleElem);
- titleCont.appendChild(linksCont);
- // TODO: features
- const featuresCont = document.createElement("div");
- featuresCont.id = "betterytm-menu-opts";
- featuresCont.style.display = "flex";
- featuresCont.style.flexDirection = "column";
- /** Gets called whenever the feature config is changed */
- const confChanged = async (key: keyof typeof defaultFeatures, initialVal: number | boolean | Record<string, unknown>, newVal: number | boolean | Record<string, unknown>) => {
- const fmt = (val: unknown) => typeof val === "object" ? JSON.stringify(val) : String(val);
- dbg && console.info(`BetterYTM: Feature config changed, key '${key}' from value '${fmt(initialVal)}' to '${fmt(newVal)}'`);
- const featConf = { ...await getFeatures() };
- featConf[key] = newVal as never;
- await saveFeatureConf(featConf);
- dbg && console.log("BetterYTM: Saved feature config changes:\n", await GM.getValue("betterytm-config"));
- };
- const features = await getFeatures();
- const featKeys = Object.keys(features);
- for(const key of featKeys) {
- const ftInfo = featInfo[key as keyof typeof features];
- if(!ftInfo)
- continue;
- const { desc, type, default: ftDef } = ftInfo;
- // @ts-ignore
- const step = ftInfo?.step ?? undefined;
- const val = features[key as keyof typeof features];
- const initialVal = val || ftDef || undefined;
- const ftConfElem = document.createElement("div");
- ftConfElem.id = `betterytm-ftconf-${key}`;
- ftConfElem.style.display = "flex";
- ftConfElem.style.flexDirection = "row";
- ftConfElem.style.justifyContent = "space-between";
- ftConfElem.style.padding = "8px 20px";
- {
- const textElem = document.createElement("span");
- textElem.style.display = "inline-block";
- textElem.style.fontSize = "15px";
- textElem.innerText = desc;
- ftConfElem.appendChild(textElem);
- }
- {
- let inputType = "text";
- switch(type)
- {
- case "toggle":
- inputType = "checkbox";
- break;
- case "slider":
- inputType = "range";
- break;
- case "number":
- inputType = "number";
- break;
- }
- const inputElemId = `betterytm-ftconf-${key}-input`;
- const ctrlElem = document.createElement("span");
- ctrlElem.style.display = "inline-block";
- ctrlElem.style.whiteSpace = "nowrap";
- const inputElem = document.createElement("input");
- inputElem.id = inputElemId;
- inputElem.style.marginRight = "37px";
- inputElem.type = inputType;
- if(type === "toggle")
- inputElem.style.marginLeft = "5px";
- if(typeof initialVal !== "undefined")
- inputElem.value = String(initialVal);
- if(type === "number" && step)
- inputElem.step = step;
- // @ts-ignore
- if(ftInfo.min && ftInfo.max) {
- // @ts-ignore
- inputElem.min = ftInfo.min;
- // @ts-ignore
- inputElem.max = ftInfo.max;
- }
- if(type === "toggle" && typeof initialVal !== "undefined")
- inputElem.checked = Boolean(initialVal);
- const fmtVal = (v: unknown) => String(v);
- const toggleLabelText = (toggled: boolean) => toggled ? "On" : "Off";
- let labelElem: HTMLLabelElement | undefined;
- if(type === "slider") {
- labelElem = document.createElement("label");
- labelElem.classList.add("betterytm-ftconf-label");
- labelElem.style.marginRight = "20px";
- labelElem.style.fontSize = "16px";
- labelElem.htmlFor = inputElemId;
- labelElem.innerText = fmtVal(initialVal);
- inputElem.addEventListener("input", () => {
- if(labelElem)
- labelElem.innerText = fmtVal(parseInt(inputElem.value));
- });
- }
- else if(type === "toggle" && typeof initialVal !== "undefined") {
- labelElem = document.createElement("label");
- labelElem.classList.add("betterytm-ftconf-label");
- labelElem.style.paddingLeft = "10px";
- labelElem.style.paddingRight = "5px";
- labelElem.style.fontSize = "16px";
- labelElem.htmlFor = inputElemId;
- labelElem.innerText = toggleLabelText(Boolean(initialVal));
- inputElem.addEventListener("input", () => {
- if(labelElem)
- labelElem.innerText = toggleLabelText(inputElem.checked);
- });
- }
- inputElem.addEventListener("input", ({ currentTarget }) => {
- const elem = currentTarget as HTMLInputElement;
- let v = parseInt(elem.value);
- if(isNaN(v))
- v = Number(elem.value);
- if(typeof initialVal !== "undefined")
- confChanged(key as keyof FeatureConfig, initialVal, (type !== "toggle" ? v : elem.checked));
- });
- const resetElem = document.createElement("button");
- resetElem.innerText = "Reset";
- resetElem.addEventListener("click", () => {
- inputElem[type !== "toggle" ? "value" : "checked"] = ftDef as never;
- if(labelElem) {
- if(type === "toggle")
- labelElem.innerText = toggleLabelText(inputElem.checked);
- else
- labelElem.innerText = fmtVal(parseInt(inputElem.value));
- }
- if(typeof initialVal !== "undefined")
- confChanged(key as keyof FeatureConfig, initialVal, ftDef);
- });
- labelElem && ctrlElem.appendChild(labelElem);
- ctrlElem.appendChild(inputElem);
- ctrlElem.appendChild(resetElem);
- ftConfElem.appendChild(ctrlElem);
- }
- featuresCont.appendChild(ftConfElem);
- }
- const footerElem = document.createElement("div");
- footerElem.style.marginTop = "20px";
- footerElem.style.fontSize = "17px";
- footerElem.style.textDecoration = "underline";
- footerElem.style.padding = "8px 20px";
- footerElem.innerText = "You need to reload the page to apply changes.";
- const reloadElem = document.createElement("button");
- reloadElem.style.marginLeft = "20px";
- reloadElem.innerText = "Reload now";
- reloadElem.title = "Click to reload the page";
- reloadElem.addEventListener("click", () => location.reload());
- footerElem.appendChild(reloadElem);
- featuresCont.appendChild(footerElem);
- // finalize
- const menuBody = document.createElement("div");
- menuBody.id = "betterytm-menu-body";
- menuBody.appendChild(titleCont);
- menuBody.appendChild(featuresCont);
- const versionCont = document.createElement("div");
- versionCont.style.display = "flex";
- versionCont.style.justifyContent = "space-around";
- versionCont.style.fontSize = "1.15em";
- versionCont.style.marginTop = "10px";
- versionCont.style.marginBottom = "5px";
- const versionElem = document.createElement("span");
- versionElem.id = "betterytm-menu-version";
- versionElem.innerText = `v${info.version}`;
- versionCont.appendChild(versionElem);
- featuresCont.appendChild(versionCont);
- menuContainer.appendChild(menuBody);
- menuContainer.appendChild(versionCont);
- backgroundElem.appendChild(menuContainer);
- document.body.appendChild(backgroundElem);
- // add style
- const menuStyle = `\
- #betterytm-menu-bg {
- display: block;
- position: fixed;
- width: 100vw;
- height: 100vh;
- top: 0;
- left: 0;
- z-index: 15;
- background-color: rgba(0, 0, 0, 0.6);
- }
- /* TODO:FIXME: needs better positioning (vw and vh === "big no no") */
- #betterytm-menu {
- display: inline-block;
- position: fixed;
- width: 50vw;
- height: auto;
- min-height: 500px;
- left: 25vw;
- top: 25vh;
- z-index: 16;
- overflow: auto;
- padding: 8px;
- color: #fff;
- background-color: #212121;
- }
- #betterytm-menu-titlecont {
- display: flex;
- }
- #betterytm-menu-title {
- font-size: 20px;
- margin-top: 5px;
- margin-bottom: 8px;
- }
- #betterytm-menu-linkscont {
- display: flex;
- }
- .betterytm-menu-link {
- display: inline-block;
- }
- /*.betterytm-menu-img {
- }*/
- #betterytm-menu-close {
- cursor: pointer;
- }
- .betterytm-ftconf-label {
- user-select: none;
- }`;
- dbg && console.log("BetterYTM: Added menu elem:", backgroundElem);
- addGlobalStyle(menuStyle, "menu");
- }
- export function closeMenu() {
- const menuBg = document.querySelector("#betterytm-menu-bg") as HTMLElement;
- menuBg.style.visibility = "hidden";
- menuBg.style.display = "none";
- }
- export function openMenu() {
- const menuBg = document.querySelector("#betterytm-menu-bg") as HTMLElement;
- menuBg.style.visibility = "visible";
- menuBg.style.display = "block";
- }
- //#MARKER changelog
- export async function initChangelog() {
- // const clStyle = `\
- // #betterytm-changelog-bg {
- // display: block;
- // position: fixed;
- // width: 100vw;
- // height: 100vh;
- // top: 0;
- // left: 0;
- // z-index: 15;
- // background-color: rgba(0, 0, 0, 0.6);
- // }
- // #betterytm-changelog {
- // display: inline-block;
- // position: fixed;
- // width: 50vw;
- // height: auto;
- // min-height: 500px;
- // left: 25vw;
- // top: 25vh;
- // z-index: 16;
- // overflow: auto;
- // padding: 8px;
- // color: #fff;
- // background-color: #212121;
- // }
- // #betterytm-changelog-close {
- // cursor: pointer;
- // }`;
- // console.log("#DEBUG _CHANGELOG:", changelog);
- // const cl = document.createElement("div");
- // cl.style.position = "fixed";
- // cl.style.top = "0";
- // cl.style.left = "0";
- // cl.style.minWidth = "500px";
- // cl.style.minHeight = "500px";
- // cl.style.overflowY = "scroll";
- // cl.innerHTML = changelog;
- // document.addEventListener("DOMContentLoaded", () => document.body.appendChild(cl));
- void ["TODO", changelog];
- }
|