| @@ -1,252 +1,216 @@ |
| 1 | // TODO: This file was created by bulk-decaffeinate. | 1 | app.Settings = class Settings { |
| 2 | // Sanity-check the conversion and remove this comment. | 2 | static PREFERENCE_KEYS = [ |
| 3 | /* | 3 | "hideDisabled", |
| 4 | * decaffeinate suggestions: | 4 | "hideIntro", |
| 5 | * DS101: Remove unnecessary use of Array.from | 5 | "manualUpdate", |
| 6 | * DS102: Remove unnecessary code created because of implicit returns | 6 | "fastScroll", |
| 7 | * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining | 7 | "arrowScroll", |
| 8 | * DS104: Avoid inline assignments | 8 | "analyticsConsent", |
| 9 | * DS206: Consider reworking classes to avoid initClass | 9 | "docs", |
| 10 | * DS207: Consider shorter variations of null checks | 10 | "dark", // legacy |
| 11 | * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md | 11 | "theme", |
| 12 | */ | 12 | "layout", |
| 13 | (function () { | 13 | "size", |
| 14 | let PREFERENCE_KEYS = undefined; | 14 | "tips", |
| 15 | let INTERNAL_KEYS = undefined; | 15 | "noAutofocus", |
| 16 | app.Settings = class Settings { | 16 | "autoInstall", |
| 17 | static initClass() { | 17 | "spaceScroll", |
| 18 | PREFERENCE_KEYS = [ | 18 | "spaceTimeout", |
| 19 | "hideDisabled", | 19 | ]; |
| 20 | "hideIntro", | 20 | |
| 21 | "manualUpdate", | 21 | static INTERNAL_KEYS = ["count", "schema", "version", "news"]; |
| 22 | "fastScroll", | 22 | |
| 23 | "arrowScroll", | 23 | static LAYOUTS = [ |
| 24 | "analyticsConsent", | 24 | "_max-width", |
| 25 | "docs", | 25 | "_sidebar-hidden", |
| 26 | "dark", // legacy | 26 | "_native-scrollbars", |
| 27 | "theme", | 27 | "_text-justify-hyphenate", |
| 28 | "layout", | 28 | ]; |
| 29 | "size", | 29 | |
| 30 | "tips", | 30 | static defaults = { |
| 31 | "noAutofocus", | 31 | count: 0, |
| 32 | "autoInstall", | 32 | hideDisabled: false, |
| 33 | "spaceScroll", | 33 | hideIntro: false, |
| 34 | "spaceTimeout", | 34 | news: 0, |
| 35 | ]; | 35 | manualUpdate: false, |
| 36 | | 36 | schema: 1, |
| 37 | INTERNAL_KEYS = ["count", "schema", "version", "news"]; | 37 | analyticsConsent: false, |
| 38 | | 38 | theme: "auto", |
| 39 | this.prototype.LAYOUTS = [ | 39 | spaceScroll: 1, |
| 40 | "_max-width", | 40 | spaceTimeout: 0.5, |
| 41 | "_sidebar-hidden", | 41 | }; |
| 42 | "_native-scrollbars", | | |
| 43 | "_text-justify-hyphenate", | | |
| 44 | ]; | | |
| 45 | | | |
| 46 | this.defaults = { | | |
| 47 | count: 0, | | |
| 48 | hideDisabled: false, | | |
| 49 | hideIntro: false, | | |
| 50 | news: 0, | | |
| 51 | manualUpdate: false, | | |
| 52 | schema: 1, | | |
| 53 | analyticsConsent: false, | | |
| 54 | theme: "auto", | | |
| 55 | spaceScroll: 1, | | |
| 56 | spaceTimeout: 0.5, | | |
| 57 | }; | | |
| 58 | } | | |
| 59 | | | |
| 60 | constructor() { | | |
| 61 | this.store = new CookiesStore(); | | |
| 62 | this.cache = {}; | | |
| 63 | this.autoSupported = | | |
| 64 | window.matchMedia("(prefers-color-scheme)").media !== "not all"; | | |
| 65 | if (this.autoSupported) { | | |
| 66 | this.darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)"); | | |
| 67 | this.darkModeQuery.addListener(() => this.setTheme(this.get("theme"))); | | |
| 68 | } | | |
| 69 | } | | |
| 70 | | | |
| 71 | get(key) { | | |
| 72 | let left; | | |
| 73 | if (this.cache.hasOwnProperty(key)) { | | |
| 74 | return this.cache[key]; | | |
| 75 | } | | |
| 76 | this.cache[key] = | | |
| 77 | (left = this.store.get(key)) != null | | |
| 78 | ? left | | |
| 79 | : this.constructor.defaults[key]; | | |
| 80 | if ( | | |
| 81 | key === "theme" && | | |
| 82 | this.cache[key] === "auto" && | | |
| 83 | !this.darkModeQuery | | |
| 84 | ) { | | |
| 85 | return (this.cache[key] = "default"); | | |
| 86 | } else { | | |
| 87 | return this.cache[key]; | | |
| 88 | } | | |
| 89 | } | | |
| 90 | | | |
| 91 | set(key, value) { | | |
| 92 | this.store.set(key, value); | | |
| 93 | delete this.cache[key]; | | |
| 94 | if (key === "theme") { | | |
| 95 | this.setTheme(value); | | |
| 96 | } | | |
| 97 | } | | |
| 98 | | | |
| 99 | del(key) { | | |
| 100 | this.store.del(key); | | |
| 101 | delete this.cache[key]; | | |
| 102 | } | | |
| 103 | | | |
| 104 | hasDocs() { | | |
| 105 | try { | | |
| 106 | return !!this.store.get("docs"); | | |
| 107 | } catch (error) {} | | |
| 108 | } | | |
| 109 | | | |
| 110 | getDocs() { | | |
| 111 | return ( | | |
| 112 | __guard__(this.store.get("docs"), (x) => x.split("/")) || | | |
| 113 | app.config.default_docs | | |
| 114 | ); | | |
| 115 | } | | |
| 116 | | | |
| 117 | setDocs(docs) { | | |
| 118 | this.set("docs", docs.join("/")); | | |
| 119 | } | | |
| 120 | | | |
| 121 | getTips() { | | |
| 122 | return __guard__(this.store.get("tips"), (x) => x.split("/")) || []; | | |
| 123 | } | | |
| 124 | | | |
| 125 | setTips(tips) { | | |
| 126 | this.set("tips", tips.join("/")); | | |
| 127 | } | | |
| 128 | | | |
| 129 | setLayout(name, enable) { | | |
| 130 | this.toggleLayout(name, enable); | | |
| 131 | | | |
| 132 | const layout = (this.store.get("layout") || "").split(" "); | | |
| 133 | $.arrayDelete(layout, ""); | | |
| 134 | | | |
| 135 | if (enable) { | | |
| 136 | if (layout.indexOf(name) === -1) { | | |
| 137 | layout.push(name); | | |
| 138 | } | | |
| 139 | } else { | | |
| 140 | $.arrayDelete(layout, name); | | |
| 141 | } | | |
| 142 | | | |
| 143 | if (layout.length > 0) { | | |
| 144 | this.set("layout", layout.join(" ")); | | |
| 145 | } else { | | |
| 146 | this.del("layout"); | | |
| 147 | } | | |
| 148 | } | | |
| 149 | | | |
| 150 | hasLayout(name) { | | |
| 151 | const layout = (this.store.get("layout") || "").split(" "); | | |
| 152 | return layout.indexOf(name) !== -1; | | |
| 153 | } | | |
| 154 | | | |
| 155 | setSize(value) { | | |
| 156 | this.set("size", value); | | |
| 157 | } | | |
| 158 | | | |
| 159 | dump() { | | |
| 160 | return this.store.dump(); | | |
| 161 | } | | |
| 162 | | 42 | |
| 163 | export() { | 43 | constructor() { |
| 164 | const data = this.dump(); | 44 | this.store = new CookiesStore(); |
| 165 | for (var key of Array.from(INTERNAL_KEYS)) { | 45 | this.cache = {}; |
| 166 | delete data[key]; | 46 | this.autoSupported = |
| | 47 | window.matchMedia("(prefers-color-scheme)").media !== "not all"; |
| | 48 | if (this.autoSupported) { |
| | 49 | this.darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)"); |
| | 50 | this.darkModeQuery.addListener(() => this.setTheme(this.get("theme"))); |
| | 51 | } |
| | 52 | } |
| | 53 | |
| | 54 | get(key) { |
| | 55 | let left; |
| | 56 | if (this.cache.hasOwnProperty(key)) { |
| | 57 | return this.cache[key]; |
| | 58 | } |
| | 59 | this.cache[key] = |
| | 60 | (left = this.store.get(key)) != null |
| | 61 | ? left |
| | 62 | : this.constructor.defaults[key]; |
| | 63 | if (key === "theme" && this.cache[key] === "auto" && !this.darkModeQuery) { |
| | 64 | return (this.cache[key] = "default"); |
| | 65 | } else { |
| | 66 | return this.cache[key]; |
| | 67 | } |
| | 68 | } |
| | 69 | |
| | 70 | set(key, value) { |
| | 71 | this.store.set(key, value); |
| | 72 | delete this.cache[key]; |
| | 73 | if (key === "theme") { |
| | 74 | this.setTheme(value); |
| | 75 | } |
| | 76 | } |
| | 77 | |
| | 78 | del(key) { |
| | 79 | this.store.del(key); |
| | 80 | delete this.cache[key]; |
| | 81 | } |
| | 82 | |
| | 83 | hasDocs() { |
| | 84 | try { |
| | 85 | return !!this.store.get("docs"); |
| | 86 | } catch (error) {} |
| | 87 | } |
| | 88 | |
| | 89 | getDocs() { |
| | 90 | return this.store.get("docs")?.split("/") || app.config.default_docs; |
| | 91 | } |
| | 92 | |
| | 93 | setDocs(docs) { |
| | 94 | this.set("docs", docs.join("/")); |
| | 95 | } |
| | 96 | |
| | 97 | getTips() { |
| | 98 | return this.store.get("tips")?.split("/") || []; |
| | 99 | } |
| | 100 | |
| | 101 | setTips(tips) { |
| | 102 | this.set("tips", tips.join("/")); |
| | 103 | } |
| | 104 | |
| | 105 | setLayout(name, enable) { |
| | 106 | this.toggleLayout(name, enable); |
| | 107 | |
| | 108 | const layout = (this.store.get("layout") || "").split(" "); |
| | 109 | $.arrayDelete(layout, ""); |
| | 110 | |
| | 111 | if (enable) { |
| | 112 | if (layout.indexOf(name) === -1) { |
| | 113 | layout.push(name); |
| 167 | } | 114 | } |
| 168 | return data; | 115 | } else { |
| | 116 | $.arrayDelete(layout, name); |
| 169 | } | 117 | } |
| 170 | | 118 | |
| 171 | import(data) { | 119 | if (layout.length > 0) { |
| 172 | let key, value; | 120 | this.set("layout", layout.join(" ")); |
| 173 | const object = this.export(); | 121 | } else { |
| 174 | for (key in object) { | 122 | this.del("layout"); |
| 175 | value = object[key]; | | |
| 176 | if (!data.hasOwnProperty(key)) { | | |
| 177 | this.del(key); | | |
| 178 | } | | |
| 179 | } | | |
| 180 | for (key in data) { | | |
| 181 | value = data[key]; | | |
| 182 | if (PREFERENCE_KEYS.indexOf(key) !== -1) { | | |
| 183 | this.set(key, value); | | |
| 184 | } | | |
| 185 | } | | |
| 186 | } | 123 | } |
| | 124 | } |
| 187 | | 125 | |
| 188 | reset() { | 126 | hasLayout(name) { |
| 189 | this.store.reset(); | 127 | const layout = (this.store.get("layout") || "").split(" "); |
| 190 | this.cache = {}; | 128 | return layout.indexOf(name) !== -1; |
| 191 | } | 129 | } |
| 192 | | 130 | |
| 193 | initLayout() { | 131 | setSize(value) { |
| 194 | if (this.get("dark") === 1) { | 132 | this.set("size", value); |
| 195 | this.set("theme", "dark"); | 133 | } |
| 196 | this.del("dark"); | | |
| 197 | } | | |
| 198 | this.setTheme(this.get("theme")); | | |
| 199 | for (var layout of Array.from(this.LAYOUTS)) { | | |
| 200 | this.toggleLayout(layout, this.hasLayout(layout)); | | |
| 201 | } | | |
| 202 | this.initSidebarWidth(); | | |
| 203 | } | | |
| 204 | | 134 | |
| 205 | setTheme(theme) { | 135 | dump() { |
| 206 | if (theme === "auto") { | 136 | return this.store.dump(); |
| 207 | theme = this.darkModeQuery.matches ? "dark" : "default"; | 137 | } |
| 208 | } | | |
| 209 | const { classList } = document.documentElement; | | |
| 210 | classList.remove("_theme-default", "_theme-dark"); | | |
| 211 | classList.add("_theme-" + theme); | | |
| 212 | this.updateColorMeta(); | | |
| 213 | } | | |
| 214 | | 138 | |
| 215 | updateColorMeta() { | 139 | export() { |
| 216 | const color = getComputedStyle(document.documentElement) | 140 | const data = this.dump(); |
| 217 | .getPropertyValue("--headerBackground") | 141 | for (var key of Settings.INTERNAL_KEYS) { |
| 218 | .trim(); | 142 | delete data[key]; |
| 219 | $("meta[name=theme-color]").setAttribute("content", color); | | |
| 220 | } | 143 | } |
| | 144 | return data; |
| | 145 | } |
| 221 | | 146 | |
| 222 | toggleLayout(layout, enable) { | 147 | import(data) { |
| 223 | const { classList } = document.body; | 148 | let key, value; |
| 224 | // sidebar is always shown for settings; its state is updated in app.views.Settings | 149 | const object = this.export(); |
| 225 | if ( | 150 | for (key in object) { |
| 226 | layout !== "_sidebar-hidden" || | 151 | value = object[key]; |
| 227 | !(app.router != null ? app.router.isSettings : undefined) | 152 | if (!data.hasOwnProperty(key)) { |
| 228 | ) { | 153 | this.del(key); |
| 229 | classList.toggle(layout, enable); | | |
| 230 | } | 154 | } |
| 231 | classList.toggle("_overlay-scrollbars", $.overlayScrollbarsEnabled()); | | |
| 232 | } | 155 | } |
| 233 | | 156 | for (key in data) { |
| 234 | initSidebarWidth() { | 157 | value = data[key]; |
| 235 | const size = this.get("size"); | 158 | if (Settings.PREFERENCE_KEYS.indexOf(key) !== -1) { |
| 236 | if (size) { | 159 | this.set(key, value); |
| 237 | document.documentElement.style.setProperty( | | |
| 238 | "--sidebarWidth", | | |
| 239 | size + "px", | | |
| 240 | ); | | |
| 241 | } | 160 | } |
| 242 | } | 161 | } |
| 243 | }; | 162 | } |
| 244 | app.Settings.initClass(); | 163 | |
| 245 | return app.Settings; | 164 | reset() { |
| 246 | })(); | 165 | this.store.reset(); |
| 247 | | 166 | this.cache = {}; |
| 248 | function __guard__(value, transform) { | 167 | } |
| 249 | return typeof value !== "undefined" && value !== null | 168 | |
| 250 | ? transform(value) | 169 | initLayout() { |
| 251 | : undefined; | 170 | if (this.get("dark") === 1) { |
| 252 | } | 171 | this.set("theme", "dark"); |
| | 172 | this.del("dark"); |
| | 173 | } |
| | 174 | this.setTheme(this.get("theme")); |
| | 175 | for (var layout of app.Settings.LAYOUTS) { |
| | 176 | this.toggleLayout(layout, this.hasLayout(layout)); |
| | 177 | } |
| | 178 | this.initSidebarWidth(); |
| | 179 | } |
| | 180 | |
| | 181 | setTheme(theme) { |
| | 182 | if (theme === "auto") { |
| | 183 | theme = this.darkModeQuery.matches ? "dark" : "default"; |
| | 184 | } |
| | 185 | const { classList } = document.documentElement; |
| | 186 | classList.remove("_theme-default", "_theme-dark"); |
| | 187 | classList.add("_theme-" + theme); |
| | 188 | this.updateColorMeta(); |
| | 189 | } |
| | 190 | |
| | 191 | updateColorMeta() { |
| | 192 | const color = getComputedStyle(document.documentElement) |
| | 193 | .getPropertyValue("--headerBackground") |
| | 194 | .trim(); |
| | 195 | $("meta[name=theme-color]").setAttribute("content", color); |
| | 196 | } |
| | 197 | |
| | 198 | toggleLayout(layout, enable) { |
| | 199 | const { classList } = document.body; |
| | 200 | // sidebar is always shown for settings; its state is updated in app.views.Settings |
| | 201 | if ( |
| | 202 | layout !== "_sidebar-hidden" || |
| | 203 | !(app.router != null ? app.router.isSettings : undefined) |
| | 204 | ) { |
| | 205 | classList.toggle(layout, enable); |
| | 206 | } |
| | 207 | classList.toggle("_overlay-scrollbars", $.overlayScrollbarsEnabled()); |
| | 208 | } |
| | 209 | |
| | 210 | initSidebarWidth() { |
| | 211 | const size = this.get("size"); |
| | 212 | if (size) { |
| | 213 | document.documentElement.style.setProperty("--sidebarWidth", size + "px"); |
| | 214 | } |
| | 215 | } |
| | 216 | }; |