mirror of
https://github.com/MasterAcnolo/Freedom-Loader.git
synced 2026-07-29 18:25:47 +02:00
Feat: Add theme reloading functionality with refresh button in settings panel
This commit is contained in:
@@ -3,7 +3,7 @@ const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { logger, logDir } = require("../server/logger");
|
||||
const { configFeatures, featuresPath } = require("../config");
|
||||
const { getThemes } = require("./themeManager");
|
||||
const { getThemes, reloadThemes } = require("./themeManager");
|
||||
const config = require("../config");
|
||||
const { validateDownloadPath, getDefaultDownloadPath } = require("./pathValidator");
|
||||
|
||||
@@ -57,7 +57,7 @@ function registerIpcHandlers(getMainWindow) {
|
||||
getMainWindow()?.setProgressBar(percent / 100);
|
||||
});
|
||||
|
||||
// Contrôles fenêtre (custom top bar)
|
||||
// TOPBAR ACTION
|
||||
ipcMain.on("window-minimize", () => getMainWindow()?.minimize());
|
||||
ipcMain.on("window-maximize", () => {
|
||||
const win = getMainWindow();
|
||||
@@ -66,7 +66,7 @@ function registerIpcHandlers(getMainWindow) {
|
||||
});
|
||||
ipcMain.on("window-close", () => getMainWindow()?.close());
|
||||
|
||||
// Actions custom
|
||||
|
||||
ipcMain.on("open-devtools", () =>
|
||||
getMainWindow()?.webContents.openDevTools({ mode: "detach" })
|
||||
);
|
||||
@@ -79,9 +79,16 @@ function registerIpcHandlers(getMainWindow) {
|
||||
);
|
||||
ipcMain.on("open-config", () => shell.openPath(configFolderPath));
|
||||
|
||||
|
||||
|
||||
// THEME
|
||||
ipcMain.handle("get-themes", () => getThemes());
|
||||
|
||||
ipcMain.on("open-theme", () => shell.openPath(themeFolderPath));
|
||||
|
||||
ipcMain.handle("get-themes", () => getThemes());
|
||||
ipcMain.handle("reload-themes", async () => {
|
||||
return await reloadThemes();
|
||||
});
|
||||
|
||||
// Modification des features
|
||||
ipcMain.handle("set-feature", (event, { key, value }) => {
|
||||
|
||||
@@ -178,4 +178,11 @@ function getThemes() {
|
||||
return cachedThemes ?? [];
|
||||
}
|
||||
|
||||
module.exports = { initThemes, getThemes };
|
||||
async function reloadThemes() {
|
||||
const themes = await loadThemesFromFolder();
|
||||
cachedThemes = themes.sort((a, b) => getThemeOrder(a.id) - getThemeOrder(b.id));
|
||||
logger.info(`Themes reloaded: ${cachedThemes.length} theme(s)`);
|
||||
return cachedThemes;
|
||||
}
|
||||
|
||||
module.exports = { initThemes, getThemes , reloadThemes };
|
||||
@@ -9,6 +9,7 @@ contextBridge.exposeInMainWorld("electronAPI", {
|
||||
getVersion: () => ipcRenderer.invoke("version"),
|
||||
getValidatedDownloadPath: (path) => ipcRenderer.invoke("validate-download-path", path),
|
||||
getThemes: () => ipcRenderer.invoke("get-themes"),
|
||||
reloadThemes: () => ipcRenderer.invoke("reload-themes")
|
||||
});
|
||||
|
||||
// Contrôles de fenêtre et outils custom pour la topbar
|
||||
|
||||
@@ -54,12 +54,18 @@
|
||||
|
||||
<div class="setting-item" id="theme" style="margin-left: 32px;">
|
||||
<div class="setting-info">
|
||||
<div style="display: flex;">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<span class="setting-title">Thème</span>
|
||||
|
||||
<select id="themeSelect" data-key="theme" aria-label="Choisir le thème">
|
||||
|
||||
</select>
|
||||
<button id="refresh-themes-btn" title="Refresh themes" class="refresh-themes-btn">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 4v6h6M23 20v-6h-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<small>Choose the theme of the application</small>
|
||||
</div>
|
||||
|
||||
@@ -108,4 +108,18 @@ themeSelect.addEventListener("change", (e) => {
|
||||
}
|
||||
});
|
||||
|
||||
async function refreshThemes() {
|
||||
loadedThemes = await window.electronAPI.reloadThemes();
|
||||
populateThemeSelect(loadedThemes);
|
||||
|
||||
const features = await window.electronAPI.getFeatures();
|
||||
const savedId = features.theme;
|
||||
const theme = loadedThemes.find(t => t.id === savedId) || loadedThemes[0];
|
||||
|
||||
themeSelect.value = theme.id;
|
||||
applyTheme(theme);
|
||||
}
|
||||
|
||||
window.refreshThemes = refreshThemes;
|
||||
|
||||
initThemes();
|
||||
@@ -39,6 +39,16 @@ document.getElementById("open-json-btn").addEventListener("click", () => {
|
||||
window.topbarAPI.openConfig(); // ton IPC existant
|
||||
});
|
||||
|
||||
// Refresh Themes
|
||||
document.getElementById("refresh-themes-btn").addEventListener("click", function() {
|
||||
this.classList.add("spinning");
|
||||
window.refreshThemes();
|
||||
|
||||
setTimeout(() => {
|
||||
this.classList.remove("spinning");
|
||||
}, 600);
|
||||
});
|
||||
|
||||
|
||||
/* clic sur l'overlay = fermer */
|
||||
settingsPanel.addEventListener("click", closePanel);
|
||||
|
||||
@@ -232,6 +232,33 @@ details summary {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* REFRESH THEMES BUTTON */
|
||||
.refresh-themes-btn {
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--form-input-border-color);
|
||||
background-color: var(--form-input-bg-color);
|
||||
color: var(--form-input-text-color);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.refresh-themes-btn:hover {
|
||||
background-color: var(--form-button-bg-hover-color);
|
||||
}
|
||||
|
||||
.refresh-themes-btn.spinning svg {
|
||||
animation: spin 0.6s ease-in-out;
|
||||
}
|
||||
|
||||
.refresh-themes-btn svg {
|
||||
color: currentColor;
|
||||
transition: transform 0.6s ease-in-out;
|
||||
}
|
||||
|
||||
/* ANIMATION */
|
||||
@keyframes popIn {
|
||||
from { transform: scale(0.95); opacity: 0; }
|
||||
@@ -242,3 +269,8 @@ details summary {
|
||||
from { transform: translateX(20px); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
Reference in New Issue
Block a user