electronipchecker/src/main/store.ts

205 lines
4.8 KiB
TypeScript
Raw Normal View History

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<StoreSchema> | null = null
export function getStore(): Store<StoreSchema> {
if (!storeInstance) {
const dataDir = getDataDirectory()
storeInstance = new Store<StoreSchema>({
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<Channel>): 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 }