165 lines
3.6 KiB
JavaScript

import config from "config"
import store from "store"
import { ConfigProvider } from "antd"
export class ThemeController {
constructor(params) {
this.params = { ...params }
this.themeManifestStorageKey = "theme"
this.modificationStorageKey = "themeModifications"
this.variantStorageKey = "themeVariation"
this.theme = null
this.mutation = null
this.currentVariant = null
this.init()
return this
}
static get currentVariant() {
return document.documentElement.style.getPropertyValue("--themeVariant")
}
init = () => {
let theme = this.getStoragedTheme()
const modifications = this.getStoragedModifications()
const variantKey = this.getStoragedVariant()
if (!theme) {
// load default theme
theme = this.getDefaultTheme()
} else {
// load URL and initialize theme
}
// set global theme
this.theme = theme
// override with static vars
if (theme.staticVars) {
this.update(theme.staticVars)
}
// override theme with modifications
if (modifications) {
this.update(modifications)
}
// apply variation
this.applyVariant(variantKey)
}
getRootVariables = () => {
let attributes = document.documentElement.getAttribute("style").trim().split(";")
attributes = attributes.slice(0, (attributes.length - 1))
attributes = attributes.map((variable) => {
let [key, value] = variable.split(":")
key = key.split("--")[1]
return [key, value]
})
return Object.fromEntries(attributes)
}
getDefaultTheme = () => {
// TODO: Use evite CONSTANTS_API
return config.defaultTheme
}
getStoragedTheme = () => {
return store.get(this.themeManifestStorageKey)
}
getStoragedModifications = () => {
return store.get(this.modificationStorageKey)
}
getStoragedVariant = () => {
return store.get(this.variantStorageKey)
}
setVariant = (variationKey) => {
return store.set(this.variantStorageKey, variationKey)
}
setModifications = (modifications) => {
return store.set(this.modificationStorageKey, modifications)
}
resetDefault = () => {
store.remove(this.themeManifestStorageKey)
store.remove(this.modificationStorageKey)
window.app.settings.set("primaryColor", this.theme.staticVars.primaryColor)
return this.init()
}
update = (update) => {
if (typeof update !== "object") {
return false
}
this.mutation = {
...this.theme.staticVars,
...this.mutation,
...update
}
Object.keys(this.mutation).forEach(key => {
document.documentElement.style.setProperty(`--${key}`, this.mutation[key])
})
document.documentElement.className = `theme-${this.currentVariant}`
document.documentElement.style.setProperty(`--themeVariant`, this.currentVariant)
ConfigProvider.config({ theme: this.mutation })
}
applyVariant = (variant = (this.theme.defaultVariant ?? "light")) => {
const values = this.theme.variants[variant]
if (values) {
this.currentVariant = variant
this.update(values)
this.setVariant(variant)
}
}
}
export const extension = {
key: "theme",
expose: [
{
initialization: [
async (app, main) => {
app.ThemeController = new ThemeController()
main.eventBus.on("darkMode", (value) => {
if (value) {
app.ThemeController.applyVariant("dark")
} else {
app.ThemeController.applyVariant("light")
}
})
main.eventBus.on("modifyTheme", (value) => {
app.ThemeController.update(value)
app.ThemeController.setModifications(app.ThemeController.mutation)
})
main.eventBus.on("resetTheme", () => {
app.ThemeController.resetDefault()
})
main.setToWindowContext("ThemeController", app.ThemeController)
},
],
},
],
}
export default extension