diff --git a/ui/index.html b/ui/index.html
index 599abb8e..4044a8d2 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -34,6 +34,7 @@
+
-
-
-
@@ -42,6 +43,7 @@
-
+
diff --git a/ui/media/auto-save.js b/ui/media/auto-save.js
index bb807c08..64cd4330 100644
--- a/ui/media/auto-save.js
+++ b/ui/media/auto-save.js
@@ -28,7 +28,8 @@ var SETTINGS_IDS_LIST = [
"show_only_filtered_image",
"upscale_model",
"preview-image",
- "modifier-card-size-slider"
+ "modifier-card-size-slider",
+ "theme"
]
async function initSettings() {
diff --git a/ui/media/main.css b/ui/media/main.css
index e92de109..53d6d01c 100644
--- a/ui/media/main.css
+++ b/ui/media/main.css
@@ -26,9 +26,7 @@
--make-image-border: 2px solid hsl(var(--accent-hue), 100%, calc(var(--accent-lightness) - 21%));
}
-
-/* Light Theme */
-/* :root {
+.theme-light {
--background-color1: white;
--background-color2: #dddddd;
--background-color3: #e7e9eb;
@@ -39,11 +37,9 @@
--input-text-color: black;
--input-background-color: #f8f9fa;
--input-border-color: grey;
-} */
+}
-
-/* Discord Theme */
-/* :root {
+.theme-discord {
--background-color1: #36393f;
--background-color2: #2f3136;
--background-color3: #292b2f;
@@ -60,10 +56,9 @@
--input-border-size: 2px;
--input-background-color: #202225;
--input-border-color: var(--input-background-color);
-} */
+}
-/* Example "Custom" Theme */
-/* :root {
+.theme-cool-blue {
--main-hue: 222;
--main-saturation: 18%;
--value-base: 19%;
@@ -83,12 +78,78 @@
--input-background-color: var(--background-color3);
--input-text-color: #ccc;
--input-border-color: var(--background-color4);
-} */
+}
+
+
+.theme-blurple {
+ --main-hue: 235;
+ --main-saturation: 18%;
+ --value-base: 16%;
+ --value-step: 3%;
+ --background-color1: hsl(var(--main-hue), var(--main-saturation), var(--value-base));
+ --background-color2: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) - (1 * var(--value-step))));
+ --background-color3: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) - (2 * var(--value-step))));
+ --background-color4: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) - (3 * var(--value-step))));
+
+ --make-image-border: none;
+
+ --button-color: var(--accent-color);
+ --button-border: none;
+
+ --input-border-size: 1px;
+ --input-background-color: var(--background-color3);
+ --input-text-color: #ccc;
+ --input-border-color: var(--background-color4);
+}
+
+.theme-super-dark {
+ --main-hue: 222;
+ --main-saturation: 18%;
+ --value-base: 5%;
+ --value-step: 5%;
+ --background-color1: hsl(var(--main-hue), var(--main-saturation), var(--value-base));
+ --background-color2: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) + (1 * var(--value-step))));
+ --background-color3: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) + (2 * var(--value-step))));
+ --background-color4: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) + (3 * var(--value-step))));
+
+ --make-image-border: none;
+
+ --button-color: var(--accent-color);
+ --button-border: none;
+
+ --input-border-size: 0px;
+ --input-background-color: var(--background-color3);
+ --input-text-color: #ccc;
+ --input-border-color: var(--background-color4);
+}
+
+.theme-wild {
+ --main-hue: 128;
+ --main-saturation: 18%;
+ --value-base: 20%;
+ --value-step: 5%;
+ --background-color1: hsl(var(--main-hue), var(--main-saturation), var(--value-base));
+ --background-color2: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) - (1 * var(--value-step))));
+ --background-color3: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) - (2 * var(--value-step))));
+ --background-color4: hsl(var(--main-hue), var(--main-saturation), calc(var(--value-base) - (3 * var(--value-step))));
+
+ --accent-hue: 212;
+ --make-image-border: none;
+
+ --button-color: var(--accent-color);
+ --button-border: none;
+
+ --input-border-size: 1px;
+ --input-background-color: hsl(222, var(--main-saturation), calc(var(--value-base) - (2 * var(--value-step))));
+ --input-text-color: red;
+ --input-border-color: green;
+}
* {
font-family: Work Sans, Verdana, Geneva, sans-serif;
box-sizing: border-box;
+ transition: background 0.5s, color 0.5s, background-color 0.5s;
}
body {
@@ -564,7 +625,8 @@ img {
button,
input[type="file"],
input[type="checkbox"],
-select {
+select,
+option {
cursor: pointer;
}
@@ -690,7 +752,7 @@ input[type="range"]::-moz-range-thumb {
}
#save-settings-config > div {
- background: rgb(44, 45, 48);
+ background: var(--background-color2);
max-width: 600px;
margin: auto;
margin-top: 100px;
diff --git a/ui/media/main.js b/ui/media/main.js
index 176c1c39..31f17b0f 100644
--- a/ui/media/main.js
+++ b/ui/media/main.js
@@ -46,6 +46,7 @@ let useFullPrecisionField = document.querySelector('#use_full_precision')
let saveToDiskField = document.querySelector('#save_to_disk')
let diskPathField = document.querySelector('#diskPath')
let autoSaveSettingsField = document.querySelector('#auto_save_settings')
+let themeField = document.querySelector('#theme')
// let allowNSFWField = document.querySelector("#allow_nsfw")
let useBetaChannelField = document.querySelector("#use_beta_channel")
let promptStrengthSlider = document.querySelector('#prompt_strength_slider')
@@ -1743,4 +1744,66 @@ async function loadModifiers() {
} catch (e) {
console.log('error fetching modifiers', e)
}
-}
\ No newline at end of file
+}
+
+var DEFAULT_THEME = {};
+var THEMES = []; // initialized in initTheme from data in css
+
+function getThemeName(theme) {
+ theme = theme.replace("theme-", "");
+ theme = theme.split("-").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
+ return theme;
+}
+// init themefield
+function initTheme() {
+ Array.from(document.styleSheets)
+ .filter(sheet => sheet.href.startsWith(window.location.origin))
+ .flatMap(sheet => Array.from(sheet.cssRules))
+ .forEach(rule => {
+ var selector = rule.selectorText; // TODO: also do selector == ":root", re-run un-set props
+ if (selector && selector.startsWith(".theme-")) {
+ var theme_key = selector.substring(1);
+ THEMES.push({
+ key: theme_key,
+ name: getThemeName(theme_key),
+ rule: rule
+ })
+ }
+ if (selector && selector == ":root") {
+ DEFAULT_THEME = {
+ key: "theme-default",
+ name: "Default",
+ rule: rule
+ };
+ }
+ });
+
+ THEMES.forEach(theme => {
+ var new_option = document.createElement("option");
+ new_option.setAttribute("value", theme.key);
+ new_option.innerText = theme.name;
+ themeField.appendChild(new_option);
+ });
+}
+initTheme();
+
+function themeFieldChanged() {
+ var theme_key = themeField.value;
+
+ var body = document.querySelector("body");
+ body.classList.remove(...THEMES.map(theme => theme.key));
+ body.classList.add(theme_key);
+
+ body.style = "";
+ var theme = THEMES.find(t => t.key == theme_key);
+ if (theme) {
+ // refresh variables incase they are back referencing
+ Array.from(DEFAULT_THEME.rule.style)
+ .filter(cssVariable => !Array.from(theme.rule.style).includes(cssVariable))
+ .forEach(cssVariable => {
+ body.style.setProperty(cssVariable, DEFAULT_THEME.rule.style.getPropertyValue(cssVariable));
+ });
+ }
+}
+
+themeField.addEventListener('change', themeFieldChanged);