Merge pull request #3326 from thelounge/xpaw/theme-color
Allow themes to change theme-color
This commit is contained in:
commit
72bebd8681
@ -30,6 +30,8 @@ const noSync = ["syncSettings"];
|
|||||||
// to the server regardless of the clients sync setting.
|
// to the server regardless of the clients sync setting.
|
||||||
const alwaysSync = ["highlights"];
|
const alwaysSync = ["highlights"];
|
||||||
|
|
||||||
|
const defaultThemeColor = document.querySelector('meta[name="theme-color"]').content;
|
||||||
|
|
||||||
// Process usersettings from localstorage.
|
// Process usersettings from localstorage.
|
||||||
let userSettings = JSON.parse(storage.get("settings")) || false;
|
let userSettings = JSON.parse(storage.get("settings")) || false;
|
||||||
|
|
||||||
@ -95,10 +97,19 @@ function applySetting(name, value) {
|
|||||||
$syncWarningOverride.hide();
|
$syncWarningOverride.hide();
|
||||||
$forceSyncButton.hide();
|
$forceSyncButton.hide();
|
||||||
} else if (name === "theme") {
|
} else if (name === "theme") {
|
||||||
value = `themes/${value}.css`;
|
const themeUrl = `themes/${value}.css`;
|
||||||
|
|
||||||
if ($theme.attr("href") !== value) {
|
if ($theme.attr("href") !== themeUrl) {
|
||||||
$theme.attr("href", value);
|
$theme.attr("href", themeUrl);
|
||||||
|
|
||||||
|
const newTheme = $settings.find("#theme-select option[value='" + value + "']");
|
||||||
|
let themeColor = defaultThemeColor;
|
||||||
|
|
||||||
|
if (newTheme.length > 0 && newTheme[0].dataset.themeColor) {
|
||||||
|
themeColor = newTheme[0].dataset.themeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector('meta[name="theme-color"]').content = themeColor;
|
||||||
}
|
}
|
||||||
} else if (name === "userStyles" && !noCSSparamReg.test(window.location.search)) {
|
} else if (name === "userStyles" && !noCSSparamReg.test(window.location.search)) {
|
||||||
$userStyles.html(value);
|
$userStyles.html(value);
|
||||||
|
@ -59,8 +59,12 @@ socket.on("configuration", function(data) {
|
|||||||
|
|
||||||
// If localStorage contains a theme that does not exist on this server, switch
|
// If localStorage contains a theme that does not exist on this server, switch
|
||||||
// back to its default theme.
|
// back to its default theme.
|
||||||
if (!data.themes.map((t) => t.name).includes(options.settings.theme)) {
|
const currentTheme = data.themes.find((t) => t.name === options.settings.theme);
|
||||||
|
|
||||||
|
if (currentTheme === undefined) {
|
||||||
options.processSetting("theme", data.defaultTheme, true);
|
options.processSetting("theme", data.defaultTheme, true);
|
||||||
|
} else if (currentTheme.themeColor) {
|
||||||
|
document.querySelector('meta[name="theme-color"]').content = currentTheme.themeColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFormSubmit() {
|
function handleFormSubmit() {
|
||||||
|
@ -104,7 +104,7 @@
|
|||||||
<label for="theme-select" class="sr-only">Theme</label>
|
<label for="theme-select" class="sr-only">Theme</label>
|
||||||
<select id="theme-select" name="theme" class="input">
|
<select id="theme-select" name="theme" class="input">
|
||||||
{{#each themes}}
|
{{#each themes}}
|
||||||
<option value="{{name}}">
|
<option value="{{name}}" data-theme-color="{{themeColor}}">
|
||||||
{{displayName}}
|
{{displayName}}
|
||||||
</option>
|
</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -9,21 +9,19 @@ const themes = new Map();
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
addTheme,
|
addTheme,
|
||||||
getAll,
|
getAll,
|
||||||
getFilename,
|
getByName,
|
||||||
loadLocalThemes,
|
loadLocalThemes,
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadLocalThemes() {
|
function loadLocalThemes() {
|
||||||
fs.readdir(path.join(__dirname, "..", "..", "..", "public", "themes"), (err, builtInThemes) => {
|
const builtInThemes = fs.readdirSync(
|
||||||
if (err) {
|
path.join(__dirname, "..", "..", "..", "public", "themes")
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
builtInThemes
|
builtInThemes
|
||||||
.filter((theme) => theme.endsWith(".css"))
|
.filter((theme) => theme.endsWith(".css"))
|
||||||
.map(makeLocalThemeObject)
|
.map(makeLocalThemeObject)
|
||||||
.forEach((theme) => themes.set(theme.name, theme));
|
.forEach((theme) => themes.set(theme.name, theme));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTheme(packageName, packageObject) {
|
function addTheme(packageName, packageObject) {
|
||||||
@ -35,13 +33,17 @@ function addTheme(packageName, packageObject) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getAll() {
|
function getAll() {
|
||||||
return _.sortBy(Array.from(themes.values()), "displayName");
|
const filteredThemes = [];
|
||||||
|
|
||||||
|
for (const theme of themes.values()) {
|
||||||
|
filteredThemes.push(_.pick(theme, ["displayName", "name", "themeColor"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.sortBy(filteredThemes, "displayName");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilename(module) {
|
function getByName(name) {
|
||||||
if (themes.has(module)) {
|
return themes.get(name);
|
||||||
return themes.get(module).filename;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeLocalThemeObject(css) {
|
function makeLocalThemeObject(css) {
|
||||||
@ -49,6 +51,7 @@ function makeLocalThemeObject(css) {
|
|||||||
return {
|
return {
|
||||||
displayName: themeName.charAt(0).toUpperCase() + themeName.slice(1),
|
displayName: themeName.charAt(0).toUpperCase() + themeName.slice(1),
|
||||||
name: themeName,
|
name: themeName,
|
||||||
|
themeColor: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,10 +60,12 @@ function makePackageThemeObject(moduleName, module) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const themeColor = /^#[0-9A-F]{6}$/i.test(module.themeColor) ? module.themeColor : null;
|
||||||
const modulePath = Helper.getPackageModulePath(moduleName);
|
const modulePath = Helper.getPackageModulePath(moduleName);
|
||||||
return {
|
return {
|
||||||
displayName: module.name || moduleName,
|
displayName: module.name || moduleName,
|
||||||
filename: path.join(modulePath, module.css),
|
filename: path.join(modulePath, module.css),
|
||||||
name: moduleName,
|
name: moduleName,
|
||||||
|
themeColor: themeColor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -65,13 +65,13 @@ module.exports = function() {
|
|||||||
// local themes will not get those changes.
|
// local themes will not get those changes.
|
||||||
app.get("/themes/:theme.css", (req, res) => {
|
app.get("/themes/:theme.css", (req, res) => {
|
||||||
const themeName = req.params.theme;
|
const themeName = req.params.theme;
|
||||||
const theme = themes.getFilename(themeName);
|
const theme = themes.getByName(themeName);
|
||||||
|
|
||||||
if (theme === undefined) {
|
if (theme === undefined) {
|
||||||
return res.status(404).send("Not found");
|
return res.status(404).send("Not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.sendFile(theme);
|
return res.sendFile(theme.filename);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/packages/:package/:filename", (req, res) => {
|
app.get("/packages/:package/:filename", (req, res) => {
|
||||||
@ -180,6 +180,19 @@ module.exports = function() {
|
|||||||
manager = new ClientManager();
|
manager = new ClientManager();
|
||||||
packages.loadPackages();
|
packages.loadPackages();
|
||||||
|
|
||||||
|
const defaultTheme = themes.getByName(Helper.config.theme);
|
||||||
|
|
||||||
|
if (defaultTheme === undefined) {
|
||||||
|
log.warn(
|
||||||
|
`The specified default theme "${colors.red(
|
||||||
|
Helper.config.theme
|
||||||
|
)}" does not exist, verify your config.`
|
||||||
|
);
|
||||||
|
Helper.config.theme = "default";
|
||||||
|
} else if (defaultTheme.themeColor) {
|
||||||
|
Helper.config.themeColor = defaultTheme.themeColor;
|
||||||
|
}
|
||||||
|
|
||||||
new Identification((identHandler) => {
|
new Identification((identHandler) => {
|
||||||
manager.init(identHandler, sockets);
|
manager.init(identHandler, sockets);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user