diff --git a/package-lock.json b/package-lock.json index 1d1839e..889f3eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pickle-glass", - "version": "0.2.2", + "version": "0.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pickle-glass", - "version": "0.2.2", + "version": "0.2.3", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { diff --git a/package.json b/package.json index 92beb67..e84cb27 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,9 @@ { "name": "pickle-glass", "productName": "Glass", - "version": "0.2.2", + + "version": "0.2.3", + "description": "Cl*ely for Free", "main": "src/index.js", "scripts": { diff --git a/src/common/config/schema.js b/src/common/config/schema.js index 19e0d8c..00b58f7 100644 --- a/src/common/config/schema.js +++ b/src/common/config/schema.js @@ -6,7 +6,8 @@ const LATEST_SCHEMA = { { name: 'email', type: 'TEXT NOT NULL' }, { name: 'created_at', type: 'INTEGER' }, { name: 'api_key', type: 'TEXT' }, - { name: 'provider', type: 'TEXT DEFAULT \'openai\'' } + { name: 'provider', type: 'TEXT DEFAULT \'openai\'' }, + { name: 'auto_update_enabled', type: 'INTEGER DEFAULT 1' } ] }, sessions: { diff --git a/src/common/services/authService.js b/src/common/services/authService.js index 641a880..ed47d5f 100644 --- a/src/common/services/authService.js +++ b/src/common/services/authService.js @@ -41,63 +41,71 @@ class AuthService { // Initialize immediately for the default local user on startup. // This ensures the key is ready before any login/logout state change. encryptionService.initializeKey(this.currentUserId); + this.initializationPromise = null; } initialize() { - if (this.isInitialized) return; + if (this.isInitialized) return this.initializationPromise; - const auth = getFirebaseAuth(); - onAuthStateChanged(auth, async (user) => { - const previousUser = this.currentUser; + this.initializationPromise = new Promise((resolve) => { + const auth = getFirebaseAuth(); + onAuthStateChanged(auth, async (user) => { + const previousUser = this.currentUser; - if (user) { - // User signed IN - console.log(`[AuthService] Firebase user signed in:`, user.uid); - this.currentUser = user; - this.currentUserId = user.uid; - this.currentUserMode = 'firebase'; + if (user) { + // User signed IN + console.log(`[AuthService] Firebase user signed in:`, user.uid); + this.currentUser = user; + this.currentUserId = user.uid; + this.currentUserMode = 'firebase'; - // ** Initialize encryption key for the logged-in user ** - await encryptionService.initializeKey(user.uid); + // ** Initialize encryption key for the logged-in user ** + await encryptionService.initializeKey(user.uid); - // Start background task to fetch and save virtual key - (async () => { - try { - const idToken = await user.getIdToken(true); - const virtualKey = await getVirtualKeyByEmail(user.email, idToken); + // Start background task to fetch and save virtual key + (async () => { + try { + const idToken = await user.getIdToken(true); + const virtualKey = await getVirtualKeyByEmail(user.email, idToken); - if (global.modelStateService) { - global.modelStateService.setFirebaseVirtualKey(virtualKey); + if (global.modelStateService) { + global.modelStateService.setFirebaseVirtualKey(virtualKey); + } + console.log(`[AuthService] BG: Virtual key for ${user.email} has been processed.`); + + } catch (error) { + console.error('[AuthService] BG: Failed to fetch or save virtual key:', error); } - console.log(`[AuthService] BG: Virtual key for ${user.email} has been processed.`); + })(); - } catch (error) { - console.error('[AuthService] BG: Failed to fetch or save virtual key:', error); + } else { + // User signed OUT + console.log(`[AuthService] No Firebase user.`); + if (previousUser) { + console.log(`[AuthService] Clearing API key for logged-out user: ${previousUser.uid}`); + if (global.modelStateService) { + global.modelStateService.setFirebaseVirtualKey(null); + } } - })(); + this.currentUser = null; + this.currentUserId = 'default_user'; + this.currentUserMode = 'local'; - } else { - // User signed OUT - console.log(`[AuthService] No Firebase user.`); - if (previousUser) { - console.log(`[AuthService] Clearing API key for logged-out user: ${previousUser.uid}`); - if (global.modelStateService) { - global.modelStateService.setFirebaseVirtualKey(null); - } + // ** Initialize encryption key for the default/local user ** + await encryptionService.initializeKey(this.currentUserId); } - this.currentUser = null; - this.currentUserId = 'default_user'; - this.currentUserMode = 'local'; + this.broadcastUserState(); - // ** Initialize encryption key for the default/local user ** - await encryptionService.initializeKey(this.currentUserId); - } - this.broadcastUserState(); + if (!this.isInitialized) { + this.isInitialized = true; + console.log('[AuthService] Initialized and resolved initialization promise.'); + resolve(); + } + }); }); - this.isInitialized = true; - console.log('[AuthService] Initialized and attached to Firebase Auth state.'); + return this.initializationPromise; } async signInWithCustomToken(token) { diff --git a/src/features/settings/SettingsView.js b/src/features/settings/SettingsView.js index 7dbd9f1..bd99937 100644 --- a/src/features/settings/SettingsView.js +++ b/src/features/settings/SettingsView.js @@ -456,6 +456,8 @@ export class SettingsView extends LitElement { presets: { type: Array, state: true }, selectedPreset: { type: Object, state: true }, showPresets: { type: Boolean, state: true }, + autoUpdateEnabled: { type: Boolean, state: true }, + autoUpdateLoading: { type: Boolean, state: true }, }; //////// after_modelStateService //////// @@ -479,10 +481,48 @@ export class SettingsView extends LitElement { this.selectedPreset = null; this.showPresets = false; this.handleUsePicklesKey = this.handleUsePicklesKey.bind(this) + this.autoUpdateEnabled = true; + this.autoUpdateLoading = true; this.loadInitialData(); //////// after_modelStateService //////// } + async loadAutoUpdateSetting() { + if (!window.require) return; + const { ipcRenderer } = window.require('electron'); + this.autoUpdateLoading = true; + try { + const enabled = await ipcRenderer.invoke('settings:get-auto-update'); + this.autoUpdateEnabled = enabled; + console.log('Auto-update setting loaded:', enabled); + } catch (e) { + console.error('Error loading auto-update setting:', e); + this.autoUpdateEnabled = true; // fallback + } + this.autoUpdateLoading = false; + this.requestUpdate(); + } + + async handleToggleAutoUpdate() { + if (!window.require || this.autoUpdateLoading) return; + const { ipcRenderer } = window.require('electron'); + this.autoUpdateLoading = true; + this.requestUpdate(); + try { + const newValue = !this.autoUpdateEnabled; + const result = await ipcRenderer.invoke('settings:set-auto-update', newValue); + if (result && result.success) { + this.autoUpdateEnabled = newValue; + } else { + console.error('Failed to update auto-update setting'); + } + } catch (e) { + console.error('Error toggling auto-update:', e); + } + this.autoUpdateLoading = false; + this.requestUpdate(); + } + //////// after_modelStateService //////// async loadInitialData() { if (!window.require) return; @@ -617,6 +657,7 @@ export class SettingsView extends LitElement { this.setupEventListeners(); this.setupIpcListeners(); this.setupWindowResize(); + this.loadAutoUpdateSetting(); } disconnectedCallback() { @@ -648,6 +689,7 @@ export class SettingsView extends LitElement { } else { this.firebaseUser = null; } + this.loadAutoUpdateSetting(); this.requestUpdate(); }; @@ -1161,6 +1203,9 @@ export class SettingsView extends LitElement { +