diff --git a/layout/sidebar/sidebar.pixy b/layout/sidebar/sidebar.pixy index 81b72c69..56c2f8d8 100644 --- a/layout/sidebar/sidebar.pixy +++ b/layout/sidebar/sidebar.pixy @@ -68,7 +68,7 @@ component Sidebar(user *arn.User) //- if user != nil && user.Role == "admin" //- SidebarButton("Admin", "/admin", "wrench") - a.sidebar-link.action(href="#", data-action="toggleTheme", data-trigger="click") + a.sidebar-link.action(href="#", data-action="nextTheme", data-trigger="click") .sidebar-button Icon("paint-brush") span.sidebar-text Theme diff --git a/scripts/Actions/Theme.ts b/scripts/Actions/Theme.ts index 261da9b0..ef2a997e 100644 --- a/scripts/Actions/Theme.ts +++ b/scripts/Actions/Theme.ts @@ -1,105 +1,157 @@ import AnimeNotifier from "../AnimeNotifier" -let currentTheme = "light" -let timeoutID: number = 0 +let currentThemeName = "light" +let previewTimeoutID: number = 0 +let themeWheel: HTMLElement +let themeWheelTimeoutID: number = 0 -const light = {} -const dark = { - "hue": "45", - "saturation": "100%", +const themes = { + "light": {}, + "dark": { + "link-color-h": "45", + "link-color-s": "100%", + "link-color-l": "66%", + "link-hover-color-l": "76%", - "text-color-l": "90%", - "bg-color": "hsl(0, 0%, 18%)", - "link-color": "hsl(var(--hue), var(--saturation), 66%)", - "link-hover-color": "hsl(var(--hue), var(--saturation), 76%)", - "link-hover-text-shadow": "0 0 8px hsla(var(--hue), var(--saturation), 66%, 0.5)", - "reverse-light-color": "rgba(255, 255, 255, 0.1)", - "reverse-light-hover-color": "rgba(255, 255, 255, 0.2)", - "ui-background": "hsl(0, 0%, 14%)", - "sidebar-background": "hsla(0, 0%, 0%, 0.2)", - "sidebar-opaque-background": "hsl(0, 0%, 18%)", - "table-row-hover-background": "hsla(0, 0%, 100%, 0.01)", + "text-color-l": "90%", + "bg-color-l": "18%", + "bg-color-s": "0%", + "ui-background-l": "14%", - "theme-white": "var(--bg-color)", - "theme-black": "var(--text-color)", + "link-hover-text-shadow": "0 0 8px hsla(var(--link-color-h), var(--link-color-s), var(--link-color-l), 0.5)", + "reverse-light-color": "rgba(255, 255, 255, 0.1)", + "reverse-light-hover-color": "rgba(255, 255, 255, 0.2)", + "sidebar-background": "hsla(0, 0%, 0%, 0.2)", + "sidebar-opaque-background": "hsl(0, 0%, 18%)", + "table-row-hover-background": "hsla(0, 0%, 100%, 0.01)", - "main-color": "var(--link-color)", - "link-active-color": "var(--link-hover-color)", - "button-hover-color": "var(--link-hover-color)", - "button-hover-background": "hsl(0, 0%, 10%)", - "tab-background": "hsla(0, 0%, 0%, 0.1)", - "tab-hover-background": "hsla(0, 0%, 0%, 0.2)", - "tab-active-color": "hsl(0, 0%, 95%)", - "tab-active-background": "hsla(0, 0%, 2%, 0.5)", - "loading-anim-color": "var(--link-color)", - "anime-alternative-title-color": "hsla(0, 0%, 100%, 0.5)", - "anime-list-item-name-color": "var(--text-color)", - "tip-bg-color": "hsl(0, 0%, 10%)", + "theme-white": "var(--bg-color)", + "theme-black": "var(--text-color)", - "post-like-color": "var(--link-color)", - "post-unlike-color": "var(--link-color)", - "post-permalink-color": "var(--link-color)", + "link-active-color": "var(--link-hover-color)", + "button-hover-color": "var(--link-hover-color)", + "button-hover-background": "hsl(var(--bg-color-h), var(--bg-color-s), 10%)", + "tab-background": "hsla(0, 0%, 0%, 0.1)", + "tab-hover-background": "hsla(0, 0%, 0%, 0.2)", + "tab-active-color": "hsl(0, 0%, 95%)", + "tab-active-background": "hsla(0, 0%, 2%, 0.5)", + "loading-anim-color": "var(--link-color)", + "anime-alternative-title-color": "hsla(0, 0%, 100%, 0.5)", + "anime-list-item-name-color": "var(--text-color)", + "tip-bg-color": "hsl(0, 0%, 10%)", + // "tip-bg-color": "hsl(var(--bg-color-h), var(--bg-color-s), 10%)", - "quote-color": "var(--text-color)", + "post-like-color": "var(--link-color)", + "post-unlike-color": "var(--link-color)", + "post-permalink-color": "var(--link-color)", - "calendar-hover-color": "var(--reverse-light-color)" -} + "quote-color": "var(--text-color)", -// Toggle theme -export function toggleTheme(arn: AnimeNotifier) { - // Clear preview interval - clearTimeout(timeoutID) - - if(currentTheme === "light") { - darkTheme(arn) - return + "calendar-hover-color": "var(--reverse-light-color)" } - - lightTheme(arn) + // "crimson": { + // "base-theme": "dark", + // "link-color-h": "0", + // "link-color-l": "78%", + // "link-hover-color-l": "88%", + // "bg-color-s": "70%" + // }, + // "sakura": { + // "base-theme": "light", + // "link-color-h": "348", + // "link-color-s": "100%", + // "link-color-l": "53%", + // "link-hover-color-l": "58%", + // "bg-color-h": "348", + // "bg-color-s": "100%", + // "bg-color-l": "86%", + // "ui-background-l": "91%", + // "tab-active-color": "var(--text-color)", + // "tab-active-background": "hsla(0, 0%, 98%, 0.25)", + // "button-hover-background": "hsl(var(--bg-color-h), var(--bg-color-s), 53%)" + // } } -// Light theme -export function lightTheme(arn: AnimeNotifier) { - let root = document.documentElement +// Next theme +export function nextTheme(arn: AnimeNotifier) { + // if(!themeWheel) { + // themeWheel = document.createElement("div") + // themeWheel.classList.add("theme-wheel") + // themeWheel.classList.add("fade") + // themeWheel.classList.add("fade-out") + // document.body.appendChild(themeWheel) + // } - for(let property in light) { - if(!light.hasOwnProperty(property)) { - continue + // // Show theme wheel + // themeWheel.classList.remove("fade-out") + + // // Clear theme wheel timeout + // clearTimeout(themeWheelTimeoutID) + + // themeWheelTimeoutID = setTimeout(() => { + // // Hide theme wheel + // themeWheel.classList.add("fade-out") + // }, 2000) + + // Sort themes by name + const themesSorted = [ + "light", + "dark" + // "crimson", + // "sakura" + ] + + // Find current index and apply theme of next index + for(let i = 0; i < themesSorted.length; i++) { + if(themesSorted[i] === currentThemeName) { + let newIndex = (i + 1) % themesSorted.length + applyTheme(themesSorted[newIndex]) + break } - - root.style.setProperty(`--${property}`, light[property]) } - currentTheme = "light" -} + // Clear preview timeout + clearTimeout(previewTimeoutID) -// Dark theme -export function darkTheme(arn: AnimeNotifier) { - let root = document.documentElement - - if(!arn.user || arn.user.dataset.pro !== "true") { - arn.statusMessage.showInfo("Previewing Dark theme for 30 seconds. If you would like to use it permanently, please support us.", 5000) + // Show preview message + if(currentThemeName !== "light" && (!arn.user || arn.user.dataset.pro !== "true")) { + arn.statusMessage.showInfo(`Previewing "${currentThemeName}" theme for 30 seconds. If you would like to use it permanently, please support us.`, 5000) // After 30 seconds, switch back to default theme if the user doesn't own a PRO account - timeoutID = setTimeout(() => { - if(currentTheme === "dark") { - toggleTheme(arn) - arn.statusMessage.showInfo("Dark theme preview time has ended. If you would like to use it permanently, please support us.", 5000) + previewTimeoutID = setTimeout(() => { + if(currentThemeName !== "light") { + applyTheme("light") + arn.statusMessage.showInfo("Theme preview time has ended. If you would like to use it permanently, please support us.", 5000) } }, 30000) } +} - for(let property in dark) { - if(!dark.hasOwnProperty(property)) { +// Apply theme +export function applyTheme(themeName: string) { + let root = document.documentElement + let theme = themes[themeName] + + // Apply base theme + if(theme["base-theme"]) { + applyTheme(theme["base-theme"]) + } + + for(let property in theme) { + if(!theme.hasOwnProperty(property)) { continue } - if(light[property] === undefined) { - light[property] = root.style.getPropertyValue(`--${property}`) + if(property === "base-theme") { + continue } - root.style.setProperty(`--${property}`, dark[property]) + if(themes.light[property] === undefined) { + themes.light[property] = root.style.getPropertyValue(`--${property}`) + } + + root.style.setProperty(`--${property}`, theme[property]) } - currentTheme = "dark" + currentThemeName = themeName } \ No newline at end of file diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 4ae3b1eb..353df1b2 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -110,7 +110,7 @@ export default class AnimeNotifier { // Theme if(this.user && this.user.dataset.pro === "true" && this.user.dataset.theme !== "light") { - actions.darkTheme(this) + actions.applyTheme(this.user.dataset.theme) } // Status message diff --git a/styles/include/config.scarlet b/styles/include/config.scarlet index d173cb7f..1bbb0570 100644 --- a/styles/include/config.scarlet +++ b/styles/include/config.scarlet @@ -3,10 +3,21 @@ text-color-h = 0 text-color-s = 0% text-color-l = 23.5% text-color = hsl(text-color-h, text-color-s, text-color-l) -bg-color = rgb(246, 246, 246) -main-color = rgb(248, 165, 130) -link-color = rgb(215, 38, 15) -link-hover-color = rgb(242, 60, 30) + +bg-color-h = 0 +bg-color-s = 0% +bg-color-l = 96% +bg-color = hsl(bg-color-h, bg-color-s, bg-color-l) + +link-color-h = 7 +link-color-s = 87% +link-color-l = 45% +link-color = hsl(link-color-h, link-color-s, link-color-l) + +link-hover-color-l = 53% +link-hover-color = hsl(link-color-h, link-color-s, link-hover-color-l) +// link-hover-color = hsl(8, 89%, 53%) + link-active-color = link-hover-color pro-color = hsla(0, 100%, 73%, 0.87) anime-alternative-title-color = hsla(0, 0%, 0%, 0.5) @@ -24,7 +35,10 @@ ui-border-color = rgba(0, 0, 0, 0.1) ui-border = 1px solid ui-border-color ui-hover-border-color = rgba(0, 0, 0, 0.15) ui-hover-border = 1px solid ui-hover-border-color -ui-background = rgb(254, 254, 254) + +ui-background-l = 99.5% +ui-background = hsl(bg-color-h, bg-color-s, ui-background-l) + // ui-hover-background = rgb(254, 254, 254) // ui-background = linear-gradient(to bottom, rgba(0, 0, 0, 0.02) 0%, rgba(0, 0, 0, 0.037) 100%) // ui-hover-background = linear-gradient(to bottom, rgba(0, 0, 0, 0.01) 0%, rgba(0, 0, 0, 0.027) 100%) @@ -36,8 +50,11 @@ input-height = 2.5rem input-focus-border-color = rgb(248, 165, 130) // Button +button-color = link-color button-hover-color = white button-hover-background = link-hover-color + +// Tab tab-background = rgba(0, 0, 0, 0.02) tab-hover-background = bg-color tab-active-color = white @@ -92,7 +109,7 @@ feature-card-icon-color = white tip-bg-color = white // Loading animation -loading-anim-color = main-color +loading-anim-color = hsl(18, 89%, 74%) // Shadow shadow-light = 4px 4px 8px rgba(0, 0, 0, 0.05) diff --git a/styles/include/dark.scarlet b/styles/include/dark.scarlet deleted file mode 100644 index a6f50837..00000000 --- a/styles/include/dark.scarlet +++ /dev/null @@ -1,43 +0,0 @@ -// // Dark theme - -// // Main color -// hue = 45 -// saturation = 100% - -// // Main -// text-color = hsl(0, 0%, 90%) -// bg-color = hsl(0, 0%, 24%) -// link-color = hsl(hue, saturation, 66%) -// link-hover-color = hsl(hue, saturation, 76%) -// link-hover-text-shadow = 0 0 8px hsla(hue, saturation, 66%, 0.5) -// ui-background = hsla(0, 0%, 8%, 0.3) -// sidebar-background = rgba(0, 0, 0, 0.2) -// sidebar-opaque-background = ui-background -// table-row-hover-background = hsla(0, 0%, 100%, 0.01) - -// // White/black -// theme-white = bg-color -// theme-black = text-color - -// main-color = link-color -// link-active-color = link-hover-color -// button-hover-color = link-hover-color -// button-hover-background = hsla(0, 0%, 12%, 0.5) -// tab-background = hsla(0, 0%, 0%, 0.1) -// tab-hover-background = hsla(0, 0%, 0%, 0.2) -// tab-active-color = hsl(0, 0%, 95%) -// tab-active-background = hsla(0, 0%, 2%, 0.5) -// loading-anim-color = link-color -// anime-alternative-title-color = hsla(0, 0%, 100%, 0.5) -// anime-list-item-name-color = text-color - -// // Forum -// post-like-color = link-color -// post-unlike-color = link-color -// post-permalink-color = link-color - -// // Quote -// quote-color = text-color - -// Calendar -// calendar-hover-color = reverse-light-color \ No newline at end of file diff --git a/styles/input.scarlet b/styles/input.scarlet index dfcaf7a5..1145e097 100644 --- a/styles/input.scarlet +++ b/styles/input.scarlet @@ -40,7 +40,7 @@ input button, .button horizontal padding 0.5rem 1rem - color link-color + color button-color align-items center pointer-events all height input-height diff --git a/styles/theme-wheel.scarlet b/styles/theme-wheel.scarlet new file mode 100644 index 00000000..37017639 --- /dev/null +++ b/styles/theme-wheel.scarlet @@ -0,0 +1,15 @@ +.theme-wheel + position fixed + right content-padding + bottom content-padding + width 200px + height 200px + border 1px solid red + background rgba(255, 255, 255, 0.1) + border-radius 50% + + &.fade-out + pointer-events none + +.theme-wheel-theme + // \ No newline at end of file