mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 00:49:41 +02:00
feat: persist notification preferences to server-side settings
Notification prefs are now included in the PUT /api/settings payload and stored in ~/.claudeman/settings.json. On page load, server-stored prefs are loaded as fallback when localStorage is empty (e.g. new browser or cleared cache). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+31
-13
@@ -388,6 +388,11 @@ class ClaudemanApp {
|
|||||||
this.setupEventListeners();
|
this.setupEventListeners();
|
||||||
// Start system stats polling
|
// Start system stats polling
|
||||||
this.startSystemStatsPolling();
|
this.startSystemStatsPolling();
|
||||||
|
// Load server-stored settings (async, re-applies visibility after load)
|
||||||
|
this.loadAppSettingsFromServer().then(() => {
|
||||||
|
this.applyHeaderVisibilitySettings();
|
||||||
|
this.applyMonitorVisibility();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initTerminal() {
|
initTerminal() {
|
||||||
@@ -2518,16 +2523,17 @@ class ClaudemanApp {
|
|||||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(settings));
|
localStorage.setItem('claudeman-app-settings', JSON.stringify(settings));
|
||||||
|
|
||||||
// Save notification preferences separately
|
// Save notification preferences separately
|
||||||
|
const notifPrefsToSave = {
|
||||||
|
enabled: document.getElementById('appSettingsNotifEnabled').checked,
|
||||||
|
browserNotifications: document.getElementById('appSettingsNotifBrowser').checked,
|
||||||
|
audioAlerts: document.getElementById('appSettingsNotifAudio').checked,
|
||||||
|
stuckThresholdMs: (parseInt(document.getElementById('appSettingsNotifStuckMins').value) || 10) * 60000,
|
||||||
|
muteCritical: !document.getElementById('appSettingsNotifCritical').checked,
|
||||||
|
muteWarning: !document.getElementById('appSettingsNotifWarning').checked,
|
||||||
|
muteInfo: !document.getElementById('appSettingsNotifInfo').checked,
|
||||||
|
};
|
||||||
if (this.notificationManager) {
|
if (this.notificationManager) {
|
||||||
this.notificationManager.preferences = {
|
this.notificationManager.preferences = notifPrefsToSave;
|
||||||
enabled: document.getElementById('appSettingsNotifEnabled').checked,
|
|
||||||
browserNotifications: document.getElementById('appSettingsNotifBrowser').checked,
|
|
||||||
audioAlerts: document.getElementById('appSettingsNotifAudio').checked,
|
|
||||||
stuckThresholdMs: (parseInt(document.getElementById('appSettingsNotifStuckMins').value) || 10) * 60000,
|
|
||||||
muteCritical: !document.getElementById('appSettingsNotifCritical').checked,
|
|
||||||
muteWarning: !document.getElementById('appSettingsNotifWarning').checked,
|
|
||||||
muteInfo: !document.getElementById('appSettingsNotifInfo').checked,
|
|
||||||
};
|
|
||||||
this.notificationManager.savePreferences();
|
this.notificationManager.savePreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2535,12 +2541,12 @@ class ClaudemanApp {
|
|||||||
this.applyHeaderVisibilitySettings();
|
this.applyHeaderVisibilitySettings();
|
||||||
this.applyMonitorVisibility();
|
this.applyMonitorVisibility();
|
||||||
|
|
||||||
// Also save to server
|
// Save to server (includes notification prefs for cross-browser persistence)
|
||||||
try {
|
try {
|
||||||
await fetch('/api/settings', {
|
await fetch('/api/settings', {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(settings)
|
body: JSON.stringify({ ...settings, notificationPreferences: notifPrefsToSave })
|
||||||
});
|
});
|
||||||
this.showToast('Settings saved', 'success');
|
this.showToast('Settings saved', 'success');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -2630,10 +2636,22 @@ class ClaudemanApp {
|
|||||||
const res = await fetch('/api/settings');
|
const res = await fetch('/api/settings');
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const settings = await res.json();
|
const settings = await res.json();
|
||||||
// Merge with localStorage (server takes precedence)
|
// Extract notification prefs before merging app settings
|
||||||
|
const { notificationPreferences, ...appSettings } = settings;
|
||||||
|
// Merge app settings with localStorage (server takes precedence)
|
||||||
const localSettings = this.loadAppSettingsFromStorage();
|
const localSettings = this.loadAppSettingsFromStorage();
|
||||||
const merged = { ...localSettings, ...settings };
|
const merged = { ...localSettings, ...appSettings };
|
||||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(merged));
|
localStorage.setItem('claudeman-app-settings', JSON.stringify(merged));
|
||||||
|
|
||||||
|
// Apply notification prefs from server if present (only if localStorage has none)
|
||||||
|
if (notificationPreferences && this.notificationManager) {
|
||||||
|
const localNotifPrefs = localStorage.getItem('claudeman-notification-prefs');
|
||||||
|
if (!localNotifPrefs) {
|
||||||
|
this.notificationManager.preferences = notificationPreferences;
|
||||||
|
this.notificationManager.savePreferences();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
+1
-1
@@ -1306,7 +1306,7 @@ export class WebServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.app.put('/api/settings', async (req) => {
|
this.app.put('/api/settings', async (req) => {
|
||||||
const settings = req.body as { defaultClaudeMdPath?: string; defaultWorkingDir?: string };
|
const settings = req.body as Record<string, unknown>;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dir = dirname(settingsPath);
|
const dir = dirname(settingsPath);
|
||||||
|
|||||||
Reference in New Issue
Block a user