Skip to content

Commit

Permalink
feat: ability to add custom css styles
Browse files Browse the repository at this point in the history
  • Loading branch information
ellite committed Jul 3, 2024
1 parent f612357 commit 9f6669f
Show file tree
Hide file tree
Showing 9 changed files with 330 additions and 224 deletions.
37 changes: 37 additions & 0 deletions endpoints/settings/customcss.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

require_once '../../includes/connect_endpoint.php';

if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}

if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);

$customCss = $data['customCss'];

$stmt = $db->prepare('DELETE FROM custom_css_style WHERE user_id = :userId');
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);
$stmt->execute();

$stmt = $db->prepare('INSERT INTO custom_css_style (css, user_id) VALUES (:customCss, :userId)');
$stmt->bindParam(':customCss', $customCss, SQLITE3_TEXT);
$stmt->bindParam(':userId', $userId, SQLITE3_INTEGER);

if ($stmt->execute()) {
die(json_encode([
"success" => true,
"message" => translate("success", $i18n)
]));
} else {
die(json_encode([
"success" => false,
"message" => translate("error", $i18n)
]));
}
}
9 changes: 9 additions & 0 deletions includes/getsettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
$settings['customColors'] = $customColors;
}

$query = "SELECT * FROM custom_css_style WHERE user_id = :userId";
$stmt = $db->prepare($query);
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$customCss = $result->fetchArray(SQLITE3_ASSOC);
if ($customCss) {
$settings['customCss'] = $customCss['css'];
}

$query = "SELECT * FROM admin";
$result = $db->query($query);
$adminSettings = $result->fetchArray(SQLITE3_ASSOC);
Expand Down
8 changes: 8 additions & 0 deletions includes/header.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
$colorTheme = $settings['color_theme'];
}

$customCss = "";
if (isset($settings['customCss'])) {
$customCss = $settings['customCss'];
}

$isAdmin = $_SESSION['userId'] == 1;

function hex2rgb($hex) {
Expand Down Expand Up @@ -78,6 +83,9 @@ function hex2rgb($hex) {
window.lang = "<?=$lang ?>";
window.colorTheme = "<?= $colorTheme ?>";
</script>
<style>
<?= htmlspecialchars($customCss, ENT_QUOTES, 'UTF-8') ?>
</style>
<?php
if (isset($settings['customColors'])) {
?>
Expand Down
2 changes: 1 addition & 1 deletion includes/version.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<?php
$version = "v2.11.2";
$version = "v2.12.0";
?>
12 changes: 12 additions & 0 deletions migrations/000023.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

/*
* This migration adds a table to store custom css styles per user
*/

/** @noinspection PhpUndefinedVariableInspection */
$db->exec('CREATE TABLE IF NOT EXISTS custom_css_style (
css TEXT DEFAULT "",
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES user(id)
)');
224 changes: 1 addition & 223 deletions scripts/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -872,104 +872,6 @@ function addFixerKeyButton() {
document.getElementById("addFixerKey").disabled = false;
});
}

function switchTheme() {
const darkThemeCss = document.querySelector("#dark-theme");
darkThemeCss.disabled = !darkThemeCss.disabled;

const themeChoice = darkThemeCss.disabled ? 'light' : 'dark';
document.cookie = `theme=${themeChoice}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;

document.body.className = themeChoice;

const button = document.getElementById("switchTheme");
button.disabled = true;

fetch('endpoints/settings/theme.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({theme: themeChoice === 'dark'})
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
} else {
showErrorMessage(data.errorMessage);
}
button.disabled = false;
}).catch(error => {
button.disabled = false;
});
}

function setDarkTheme(theme) {
const darkThemeButton = document.querySelector("#theme-dark");
const lightThemeButton = document.querySelector("#theme-light");
const automaticThemeButton = document.querySelector("#theme-automatic");
const darkThemeCss = document.querySelector("#dark-theme");
const themes = {0: 'light', 1: 'dark', 2: 'automatic'};
const themeValue = themes[theme];
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;

darkThemeButton.disabled = true;
lightThemeButton.disabled = true;
automaticThemeButton.disabled = true;

fetch('endpoints/settings/theme.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({theme: theme})
})
.then(response => response.json())
.then(data => {
if (data.success) {
darkThemeButton.disabled = false;
lightThemeButton.disabled = false;
automaticThemeButton.disabled = false;
darkThemeButton.classList.remove('selected');
lightThemeButton.classList.remove('selected');
automaticThemeButton.classList.remove('selected');

document.cookie = `theme=${themeValue}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;

if (theme == 0) {
darkThemeCss.disabled = true;
document.body.className = 'light';
lightThemeButton.classList.add('selected');
}

if (theme == 1) {
darkThemeCss.disabled = false;
document.body.className = 'dark';
darkThemeButton.classList.add('selected');
}

if (theme == 2) {
darkThemeCss.disabled = !prefersDarkMode;
document.body.className = prefersDarkMode ? 'dark' : 'light';
automaticThemeButton.classList.add('selected');
document.cookie = `inUseTheme=${prefersDarkMode ? 'dark' : 'light'}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;
}

showSuccessMessage(data.message);
} else {
showErrorMessage(data.errorMessage);
darkThemeButton.disabled = false;
lightThemeButton.disabled = false;
automaticThemeButton.disabled = false;
}
}).catch(error => {
darkThemeButton.disabled = false;
lightThemeButton.disabled = false;
automaticThemeButton.disabled = false;
});
}

function storeSettingsOnDB(endpoint, value) {
fetch('endpoints/settings/' + endpoint + '.php', {
method: 'POST',
Expand Down Expand Up @@ -1052,128 +954,4 @@ var sortable = Sortable.create(el, {
onEnd: function (evt) {
saveCategorySorting();
},
});


function setTheme(themeColor) {
var currentTheme = 'blue';
var themeIds = ['red-theme', 'green-theme', 'yellow-theme', 'purple-theme'];

themeIds.forEach(function(id) {
var themeStylesheet = document.getElementById(id);
if (themeStylesheet && !themeStylesheet.disabled) {
currentTheme = id.replace('-theme', '');
themeStylesheet.disabled = true;
}
});

if (themeColor !== "blue") {
var enableTheme = document.getElementById(themeColor + '-theme');
enableTheme.disabled = false;
}

var images = document.querySelectorAll('img');
images.forEach(function(img) {
if (img.src.includes('siteicons/' + currentTheme)) {
img.src = img.src.replace(currentTheme, themeColor);
}
});

var labels = document.querySelectorAll('.theme-preview');
labels.forEach(function(label) {
label.classList.remove('is-selected');
});

var targetLabel = document.querySelector(`.theme-preview.${themeColor}`);
if (targetLabel) {
targetLabel.classList.add('is-selected');
}

document.cookie = `colorTheme=${themeColor}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;

fetch('endpoints/settings/colortheme.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ color: themeColor })
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
} else {
showErrorMessage(data.message);
}
})
.catch(error => {
showErrorMessage(translate('unknown_error'));
});

}

function resetCustomColors() {
const button = document.getElementById("reset-colors");
button.disabled = true;

fetch('endpoints/settings/resettheme.php', {
method: 'DELETE',
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
const custom_theme_colors = document.getElementById('custom_theme_colors');
if (custom_theme_colors) {
custom_theme_colors.remove();
}
document.documentElement.style.removeProperty('--main-color');
document.documentElement.style.removeProperty('--accent-color');
document.documentElement.style.removeProperty('--hover-color');
document.getElementById("mainColor").value = "#FFFFFF";
document.getElementById("accentColor").value = "#FFFFFF";
document.getElementById("hoverColor").value = "#FFFFFF";
} else {
showErrorMessage(data.message);
}
button.disabled = false;
})
.catch(error => {
showErrorMessage(translate('unknown_error'));
button.disabled = false;
});
}

function saveCustomColors() {
const button = document.getElementById("save-colors");
button.disabled = true;

const mainColor = document.getElementById("mainColor").value;
const accentColor = document.getElementById("accentColor").value;
const hoverColor = document.getElementById("hoverColor").value;

fetch('endpoints/settings/customtheme.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ mainColor: mainColor, accentColor: accentColor, hoverColor: hoverColor })
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
document.documentElement.style.setProperty('--main-color', mainColor);
document.documentElement.style.setProperty('--accent-color', accentColor);
document.documentElement.style.setProperty('--hover-color', hoverColor);
} else {
showErrorMessage(data.message);
}
button.disabled = false;
})
.catch(error => {
showErrorMessage(translate('unknown_error'));
button.disabled = false;
});

}
});
Loading

0 comments on commit 9f6669f

Please sign in to comment.