forked from mystiq/hydrogen-web
Create theme chooser
This commit is contained in:
parent
cc2c74fdff
commit
daae7442bb
4 changed files with 58 additions and 0 deletions
|
@ -31,6 +31,17 @@ function appendVariablesToCSS(variables, cssSource) {
|
||||||
return cssSource + getRootSectionWithVariables(variables);
|
return cssSource + getRootSectionWithVariables(variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addThemesToConfig(bundle, themeSummary) {
|
||||||
|
for (const [fileName, info] of Object.entries(bundle)) {
|
||||||
|
if (fileName === "assets/config.json") {
|
||||||
|
const source = new TextDecoder().decode(info.source);
|
||||||
|
const config = JSON.parse(source);
|
||||||
|
config["themes"] = themeSummary;
|
||||||
|
info.source = new TextEncoder().encode(JSON.stringify(config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function parseBundle(bundle) {
|
function parseBundle(bundle) {
|
||||||
const chunkMap = new Map();
|
const chunkMap = new Map();
|
||||||
const assetMap = new Map();
|
const assetMap = new Map();
|
||||||
|
@ -215,6 +226,7 @@ module.exports = function buildThemes(options) {
|
||||||
type: "text/css",
|
type: "text/css",
|
||||||
media: "(prefers-color-scheme: dark)",
|
media: "(prefers-color-scheme: dark)",
|
||||||
href: `./${darkThemeLocation}`,
|
href: `./${darkThemeLocation}`,
|
||||||
|
class: "default-theme",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -224,6 +236,7 @@ module.exports = function buildThemes(options) {
|
||||||
type: "text/css",
|
type: "text/css",
|
||||||
media: "(prefers-color-scheme: light)",
|
media: "(prefers-color-scheme: light)",
|
||||||
href: `./${lightThemeLocation}`,
|
href: `./${lightThemeLocation}`,
|
||||||
|
class: "default-theme",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -261,6 +274,7 @@ module.exports = function buildThemes(options) {
|
||||||
themeSummary[`${name}-${variant}`] = assetHashedFileName;
|
themeSummary[`${name}-${variant}`] = assetHashedFileName;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
addThemesToConfig(bundle, themeSummary);
|
||||||
this.emitFile({
|
this.emitFile({
|
||||||
type: "asset",
|
type: "asset",
|
||||||
name: "theme-summary.json",
|
name: "theme-summary.json",
|
||||||
|
|
|
@ -127,6 +127,14 @@ export class SettingsViewModel extends ViewModel {
|
||||||
return this._formatBytes(this._estimate?.usage);
|
return this._formatBytes(this._estimate?.usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get themes() {
|
||||||
|
return this.platform.themes;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(name) {
|
||||||
|
this.platform.setTheme(name);
|
||||||
|
}
|
||||||
|
|
||||||
_formatBytes(n) {
|
_formatBytes(n) {
|
||||||
if (typeof n === "number") {
|
if (typeof n === "number") {
|
||||||
return Math.round(n / (1024 * 1024)).toFixed(1) + " MB";
|
return Math.round(n / (1024 * 1024)).toFixed(1) + " MB";
|
||||||
|
|
|
@ -307,6 +307,33 @@ export class Platform {
|
||||||
return DEFINE_VERSION;
|
return DEFINE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get themes() {
|
||||||
|
return Object.keys(this.config["themes"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(themeName) {
|
||||||
|
const themeLocation = this.config["themes"][themeName];
|
||||||
|
if (!themeLocation) {
|
||||||
|
throw new Error(`Cannot find theme location for theme "${themeName}"!`);
|
||||||
|
}
|
||||||
|
this._replaceStylesheet(themeLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
_replaceStylesheet(newPath) {
|
||||||
|
// remove default theme
|
||||||
|
const defaultStylesheets = document.getElementsByClassName("default-theme");
|
||||||
|
for (const tag of defaultStylesheets) {
|
||||||
|
tag.remove();
|
||||||
|
}
|
||||||
|
// add new theme
|
||||||
|
const head = document.querySelector("head");
|
||||||
|
const styleTag = document.createElement("link");
|
||||||
|
styleTag.href = `./${newPath}`;
|
||||||
|
styleTag.rel = "stylesheet";
|
||||||
|
styleTag.type = "text/css";
|
||||||
|
head.appendChild(styleTag);
|
||||||
|
}
|
||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
this._disposables.dispose();
|
this._disposables.dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,7 @@ export class SettingsView extends TemplateView {
|
||||||
settingNodes.push(
|
settingNodes.push(
|
||||||
t.h3("Preferences"),
|
t.h3("Preferences"),
|
||||||
row(t, vm.i18n`Scale down images when sending`, this._imageCompressionRange(t, vm)),
|
row(t, vm.i18n`Scale down images when sending`, this._imageCompressionRange(t, vm)),
|
||||||
|
row(t, vm.i18n`Use the following theme`, this._themeOptions(t, vm)),
|
||||||
);
|
);
|
||||||
settingNodes.push(
|
settingNodes.push(
|
||||||
t.h3("Application"),
|
t.h3("Application"),
|
||||||
|
@ -135,4 +136,12 @@ export class SettingsView extends TemplateView {
|
||||||
vm.i18n`no resizing`;
|
vm.i18n`no resizing`;
|
||||||
})];
|
})];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_themeOptions(t, vm) {
|
||||||
|
const optionTags = [];
|
||||||
|
for (const name of vm.themes) {
|
||||||
|
optionTags.push(t.option({value: name}, name));
|
||||||
|
}
|
||||||
|
return t.select({onChange: (e) => vm.setTheme(e.target.value)}, optionTags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue