import Store from 'electron-store' import { app } from 'electron' import * as path from 'path' import * as fs from 'fs' import type { AppSettings, Channel, ErrorLogEntry } from '../shared/types' // Default settings export const defaultSettings: AppSettings = { general: { startMinimized: false, minimizeToTray: true, autoStart: false, language: 'tr', }, monitoring: { pingInterval: 30, streamCheckInterval: 60, timeout: 5000, retryCount: 2, }, notifications: { enabled: true, windows: { enabled: true }, telegram: { enabled: false, botToken: '', chatId: '', }, email: { enabled: false, smtpHost: '', smtpPort: 587, smtpUser: '', smtpPass: '', fromEmail: '', toEmail: '', }, autoNotify: true, notifyOnPingFail: true, notifyOnStreamError: true, notifyOn404: true, notifyOnConnReset: true, }, panel: { apiUrl: '', authToken: '', monitorId: '', enabled: false, }, } // Check if running in portable mode function isPortableMode(): boolean { // Check for portable marker file next to exe const exePath = app.getPath('exe') const exeDir = path.dirname(exePath) const portableMarker = path.join(exeDir, 'portable.txt') const portableDataDir = path.join(exeDir, 'data') // Portable mode if: // 1. portable.txt exists next to exe // 2. OR data folder exists next to exe // 3. OR running from a removable drive (simplified check) if (fs.existsSync(portableMarker) || fs.existsSync(portableDataDir)) { return true } // Check if exe name contains "Portable" if (exePath.toLowerCase().includes('portable')) { return true } return false } // Get the data directory for storing config function getDataDirectory(): string { if (isPortableMode()) { const exeDir = path.dirname(app.getPath('exe')) const dataDir = path.join(exeDir, 'data') // Create data directory if it doesn't exist if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir, { recursive: true }) } return dataDir } // Use default app data location return app.getPath('userData') } // Store schema interface StoreSchema { settings: AppSettings channels: Channel[] errorLog: ErrorLogEntry[] windowBounds: { x?: number y?: number width: number height: number } } // Create store instance let storeInstance: Store | null = null export function getStore(): Store { if (!storeInstance) { const dataDir = getDataDirectory() storeInstance = new Store({ name: 'ip-monitor-config', cwd: dataDir, defaults: { settings: defaultSettings, channels: [], errorLog: [], windowBounds: { width: 1400, height: 900, }, }, // Enable encryption for sensitive data encryptionKey: 'ip-monitor-v1-key', // Clear invalid config clearInvalidConfig: true, }) console.log(`[Store] Config location: ${dataDir}`) console.log(`[Store] Portable mode: ${isPortableMode()}`) } return storeInstance } // Helper functions for common operations export function getSettings(): AppSettings { return getStore().get('settings', defaultSettings) } export function saveSettings(settings: AppSettings): void { getStore().set('settings', settings) } export function getChannels(): Channel[] { return getStore().get('channels', []) } export function saveChannels(channels: Channel[]): void { getStore().set('channels', channels) } export function addChannel(channel: Channel): void { const channels = getChannels() channels.push(channel) saveChannels(channels) } export function updateChannel(channelId: string, updates: Partial): void { const channels = getChannels() const index = channels.findIndex(c => c.id === channelId) if (index !== -1) { channels[index] = { ...channels[index], ...updates } saveChannels(channels) } } export function removeChannel(channelId: string): void { const channels = getChannels().filter(c => c.id !== channelId) saveChannels(channels) } export function getErrorLog(): ErrorLogEntry[] { return getStore().get('errorLog', []) } export function addErrorLog(entry: ErrorLogEntry): void { const log = getErrorLog() log.unshift(entry) // Add to beginning // Keep only last 100 entries if (log.length > 100) { log.length = 100 } getStore().set('errorLog', log) } export function clearErrorLog(): void { getStore().set('errorLog', []) } export function getWindowBounds() { return getStore().get('windowBounds') } export function saveWindowBounds(bounds: { x?: number; y?: number; width: number; height: number }): void { getStore().set('windowBounds', bounds) } // Export portable mode check export { isPortableMode }