settings big update
This commit is contained in:
parent
64111891eb
commit
401e83de6f
@ -4,6 +4,109 @@ const userRepository = require('../../common/repositories/user');
|
|||||||
const settingsRepository = require('./repositories');
|
const settingsRepository = require('./repositories');
|
||||||
const { getStoredApiKey, getStoredProvider, windowPool } = require('../../electron/windowManager');
|
const { getStoredApiKey, getStoredProvider, windowPool } = require('../../electron/windowManager');
|
||||||
|
|
||||||
|
// Configuration constants
|
||||||
|
const NOTIFICATION_CONFIG = {
|
||||||
|
RELEVANT_WINDOW_TYPES: ['settings', 'main'],
|
||||||
|
DEBOUNCE_DELAY: 300, // prevent spam during bulk operations (ms)
|
||||||
|
MAX_RETRY_ATTEMPTS: 3,
|
||||||
|
RETRY_BASE_DELAY: 1000, // exponential backoff base (ms)
|
||||||
|
};
|
||||||
|
|
||||||
|
// window targeting system
|
||||||
|
class WindowNotificationManager {
|
||||||
|
constructor() {
|
||||||
|
this.pendingNotifications = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send notifications only to relevant windows
|
||||||
|
* @param {string} event - Event name
|
||||||
|
* @param {*} data - Event data
|
||||||
|
* @param {object} options - Notification options
|
||||||
|
*/
|
||||||
|
notifyRelevantWindows(event, data = null, options = {}) {
|
||||||
|
const {
|
||||||
|
windowTypes = NOTIFICATION_CONFIG.RELEVANT_WINDOW_TYPES,
|
||||||
|
debounce = NOTIFICATION_CONFIG.DEBOUNCE_DELAY
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
if (debounce > 0) {
|
||||||
|
this.debounceNotification(event, () => {
|
||||||
|
this.sendToTargetWindows(event, data, windowTypes);
|
||||||
|
}, debounce);
|
||||||
|
} else {
|
||||||
|
this.sendToTargetWindows(event, data, windowTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendToTargetWindows(event, data, windowTypes) {
|
||||||
|
const relevantWindows = this.getRelevantWindows(windowTypes);
|
||||||
|
|
||||||
|
if (relevantWindows.length === 0) {
|
||||||
|
console.log(`[WindowNotificationManager] No relevant windows found for event: ${event}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[WindowNotificationManager] Sending ${event} to ${relevantWindows.length} relevant windows`);
|
||||||
|
|
||||||
|
relevantWindows.forEach(win => {
|
||||||
|
try {
|
||||||
|
if (data) {
|
||||||
|
win.webContents.send(event, data);
|
||||||
|
} else {
|
||||||
|
win.webContents.send(event);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`[WindowNotificationManager] Failed to send ${event} to window:`, error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getRelevantWindows(windowTypes) {
|
||||||
|
const allWindows = BrowserWindow.getAllWindows();
|
||||||
|
const relevantWindows = [];
|
||||||
|
|
||||||
|
allWindows.forEach(win => {
|
||||||
|
if (win.isDestroyed()) return;
|
||||||
|
|
||||||
|
for (const [windowName, poolWindow] of windowPool || []) {
|
||||||
|
if (poolWindow === win && windowTypes.includes(windowName)) {
|
||||||
|
if (windowName === 'settings' || win.isVisible()) {
|
||||||
|
relevantWindows.push(win);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return relevantWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
debounceNotification(key, fn, delay) {
|
||||||
|
// Clear existing timeout
|
||||||
|
if (this.pendingNotifications.has(key)) {
|
||||||
|
clearTimeout(this.pendingNotifications.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new timeout
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
fn();
|
||||||
|
this.pendingNotifications.delete(key);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
this.pendingNotifications.set(key, timeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
// Clear all pending notifications
|
||||||
|
this.pendingNotifications.forEach(timeoutId => clearTimeout(timeoutId));
|
||||||
|
this.pendingNotifications.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global instance
|
||||||
|
const windowNotificationManager = new WindowNotificationManager();
|
||||||
|
|
||||||
// Default keybinds configuration
|
// Default keybinds configuration
|
||||||
const DEFAULT_KEYBINDS = {
|
const DEFAULT_KEYBINDS = {
|
||||||
mac: {
|
mac: {
|
||||||
@ -124,11 +227,10 @@ async function createPreset(title, prompt) {
|
|||||||
|
|
||||||
const result = await settingsRepository.createPreset({ uid, title, prompt });
|
const result = await settingsRepository.createPreset({ uid, title, prompt });
|
||||||
|
|
||||||
// 모든 윈도우에 프리셋 업데이트 알림
|
windowNotificationManager.notifyRelevantWindows('presets-updated', {
|
||||||
BrowserWindow.getAllWindows().forEach(win => {
|
action: 'created',
|
||||||
if (!win.isDestroyed()) {
|
presetId: result.id,
|
||||||
win.webContents.send('presets-updated');
|
title
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { success: true, id: result.id };
|
return { success: true, id: result.id };
|
||||||
@ -147,11 +249,10 @@ async function updatePreset(id, title, prompt) {
|
|||||||
|
|
||||||
await settingsRepository.updatePreset(id, { title, prompt }, uid);
|
await settingsRepository.updatePreset(id, { title, prompt }, uid);
|
||||||
|
|
||||||
// 모든 윈도우에 프리셋 업데이트 알림
|
windowNotificationManager.notifyRelevantWindows('presets-updated', {
|
||||||
BrowserWindow.getAllWindows().forEach(win => {
|
action: 'updated',
|
||||||
if (!win.isDestroyed()) {
|
presetId: id,
|
||||||
win.webContents.send('presets-updated');
|
title
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
@ -170,11 +271,9 @@ async function deletePreset(id) {
|
|||||||
|
|
||||||
await settingsRepository.deletePreset(id, uid);
|
await settingsRepository.deletePreset(id, uid);
|
||||||
|
|
||||||
// 모든 윈도우에 프리셋 업데이트 알림
|
windowNotificationManager.notifyRelevantWindows('presets-updated', {
|
||||||
BrowserWindow.getAllWindows().forEach(win => {
|
action: 'deleted',
|
||||||
if (!win.isDestroyed()) {
|
presetId: id
|
||||||
win.webContents.send('presets-updated');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
@ -271,6 +370,9 @@ async function updateContentProtection(enabled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
|
// cleanup
|
||||||
|
windowNotificationManager.cleanup();
|
||||||
|
|
||||||
// IPC handlers for settings
|
// IPC handlers for settings
|
||||||
ipcMain.handle('settings:getSettings', async () => {
|
ipcMain.handle('settings:getSettings', async () => {
|
||||||
return await getSettings();
|
return await getSettings();
|
||||||
@ -316,8 +418,23 @@ function initialize() {
|
|||||||
console.log('[SettingsService] Initialized and ready.');
|
console.log('[SettingsService] Initialized and ready.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup function
|
||||||
|
function cleanup() {
|
||||||
|
windowNotificationManager.cleanup();
|
||||||
|
console.log('[SettingsService] Cleaned up resources.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function notifyPresetUpdate(action, presetId, title = null) {
|
||||||
|
const data = { action, presetId };
|
||||||
|
if (title) data.title = title;
|
||||||
|
|
||||||
|
windowNotificationManager.notifyRelevantWindows('presets-updated', data);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initialize,
|
initialize,
|
||||||
|
cleanup,
|
||||||
|
notifyPresetUpdate,
|
||||||
getSettings,
|
getSettings,
|
||||||
saveSettings,
|
saveSettings,
|
||||||
getPresets,
|
getPresets,
|
||||||
|
21
src/index.js
21
src/index.js
@ -275,30 +275,15 @@ function setupWebDataHandlers() {
|
|||||||
break;
|
break;
|
||||||
case 'create-preset':
|
case 'create-preset':
|
||||||
result = await presetRepository.create({ ...payload, uid: currentUserId });
|
result = await presetRepository.create({ ...payload, uid: currentUserId });
|
||||||
// 모든 윈도우에 프리셋 업데이트 알림
|
settingsService.notifyPresetUpdate('created', result.id, payload.title);
|
||||||
BrowserWindow.getAllWindows().forEach(win => {
|
|
||||||
if (!win.isDestroyed()) {
|
|
||||||
win.webContents.send('presets-updated');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'update-preset':
|
case 'update-preset':
|
||||||
result = await presetRepository.update(payload.id, payload.data, currentUserId);
|
result = await presetRepository.update(payload.id, payload.data, currentUserId);
|
||||||
// 모든 윈도우에 프리셋 업데이트 알림
|
settingsService.notifyPresetUpdate('updated', payload.id, payload.data.title);
|
||||||
BrowserWindow.getAllWindows().forEach(win => {
|
|
||||||
if (!win.isDestroyed()) {
|
|
||||||
win.webContents.send('presets-updated');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case 'delete-preset':
|
case 'delete-preset':
|
||||||
result = await presetRepository.delete(payload, currentUserId);
|
result = await presetRepository.delete(payload, currentUserId);
|
||||||
// 모든 윈도우에 프리셋 업데이트 알림
|
settingsService.notifyPresetUpdate('deleted', payload);
|
||||||
BrowserWindow.getAllWindows().forEach(win => {
|
|
||||||
if (!win.isDestroyed()) {
|
|
||||||
win.webContents.send('presets-updated');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// BATCH
|
// BATCH
|
||||||
|
Loading…
x
Reference in New Issue
Block a user