225 lines
8.3 KiB
JavaScript
225 lines
8.3 KiB
JavaScript
import './MainHeader.js';
|
|
import './ApiKeyHeader.js';
|
|
import './PermissionHeader.js';
|
|
|
|
class HeaderTransitionManager {
|
|
constructor() {
|
|
this.headerContainer = document.getElementById('header-container');
|
|
this.currentHeaderType = null; // 'apikey' | 'main' | 'permission'
|
|
this.apiKeyHeader = null;
|
|
this.mainHeader = null;
|
|
this.permissionHeader = null;
|
|
|
|
/**
|
|
* only one header window is allowed
|
|
* @param {'apikey'|'main'|'permission'} type
|
|
*/
|
|
this.ensureHeader = (type) => {
|
|
console.log('[HeaderController] ensureHeader: Ensuring header of type:', type);
|
|
if (this.currentHeaderType === type) {
|
|
console.log('[HeaderController] ensureHeader: Header of type:', type, 'already exists.');
|
|
return;
|
|
}
|
|
|
|
this.headerContainer.innerHTML = '';
|
|
|
|
this.apiKeyHeader = null;
|
|
this.mainHeader = null;
|
|
this.permissionHeader = null;
|
|
|
|
// Create new header element
|
|
if (type === 'apikey') {
|
|
this.apiKeyHeader = document.createElement('apikey-header');
|
|
this.apiKeyHeader.stateUpdateCallback = (userState) => this.handleStateUpdate(userState);
|
|
this.headerContainer.appendChild(this.apiKeyHeader);
|
|
} else if (type === 'permission') {
|
|
this.permissionHeader = document.createElement('permission-setup');
|
|
this.permissionHeader.continueCallback = () => this.transitionToMainHeader();
|
|
this.headerContainer.appendChild(this.permissionHeader);
|
|
} else {
|
|
this.mainHeader = document.createElement('main-header');
|
|
this.headerContainer.appendChild(this.mainHeader);
|
|
this.mainHeader.startSlideInAnimation?.();
|
|
}
|
|
|
|
this.currentHeaderType = type;
|
|
this.notifyHeaderState(type === 'permission' ? 'apikey' : type); // Keep permission state as apikey for compatibility
|
|
};
|
|
|
|
console.log('[HeaderController] Manager initialized');
|
|
|
|
this._bootstrap();
|
|
|
|
if (window.require) {
|
|
const { ipcRenderer } = window.require('electron');
|
|
|
|
ipcRenderer.on('user-state-changed', (event, userState) => {
|
|
console.log('[HeaderController] Received user state change:', userState);
|
|
this.handleStateUpdate(userState);
|
|
});
|
|
|
|
ipcRenderer.on('auth-failed', (event, { message }) => {
|
|
console.error('[HeaderController] Received auth failure from main process:', message);
|
|
if (this.apiKeyHeader) {
|
|
this.apiKeyHeader.errorMessage = 'Authentication failed. Please try again.';
|
|
this.apiKeyHeader.isLoading = false;
|
|
}
|
|
});
|
|
ipcRenderer.on('force-show-apikey-header', async () => {
|
|
console.log('[HeaderController] Received broadcast to show apikey header. Switching now.');
|
|
await this._resizeForApiKey();
|
|
this.ensureHeader('apikey');
|
|
});
|
|
}
|
|
}
|
|
|
|
notifyHeaderState(stateOverride) {
|
|
const state = stateOverride || this.currentHeaderType || 'apikey';
|
|
if (window.require) {
|
|
window.require('electron').ipcRenderer.send('header-state-changed', state);
|
|
}
|
|
}
|
|
|
|
async _bootstrap() {
|
|
// The initial state will be sent by the main process via 'user-state-changed'
|
|
// We just need to request it.
|
|
if (window.require) {
|
|
const userState = await window.require('electron').ipcRenderer.invoke('get-current-user');
|
|
console.log('[HeaderController] Bootstrapping with initial user state:', userState);
|
|
this.handleStateUpdate(userState);
|
|
} else {
|
|
// Fallback for non-electron environment (testing/web)
|
|
this.ensureHeader('apikey');
|
|
}
|
|
}
|
|
|
|
|
|
//////// after_modelStateService ////////
|
|
async handleStateUpdate(userState) {
|
|
const { ipcRenderer } = window.require('electron');
|
|
const isConfigured = await ipcRenderer.invoke('model:are-providers-configured');
|
|
|
|
if (isConfigured) {
|
|
const { isLoggedIn } = userState;
|
|
if (isLoggedIn) {
|
|
const permissionResult = await this.checkPermissions();
|
|
if (permissionResult.success) {
|
|
this.transitionToMainHeader();
|
|
} else {
|
|
this.transitionToPermissionHeader();
|
|
}
|
|
} else {
|
|
this.transitionToMainHeader();
|
|
}
|
|
} else {
|
|
await this._resizeForApiKey();
|
|
this.ensureHeader('apikey');
|
|
}
|
|
}
|
|
//////// after_modelStateService ////////
|
|
|
|
async transitionToPermissionHeader() {
|
|
// Prevent duplicate transitions
|
|
if (this.currentHeaderType === 'permission') {
|
|
console.log('[HeaderController] Already showing permission setup, skipping transition');
|
|
return;
|
|
}
|
|
|
|
// Check if permissions were previously completed
|
|
if (window.require) {
|
|
const { ipcRenderer } = window.require('electron');
|
|
try {
|
|
const permissionsCompleted = await ipcRenderer.invoke('check-permissions-completed');
|
|
if (permissionsCompleted) {
|
|
console.log('[HeaderController] Permissions were previously completed, checking current status...');
|
|
|
|
// Double check current permission status
|
|
const permissionResult = await this.checkPermissions();
|
|
if (permissionResult.success) {
|
|
// Skip permission setup if already granted
|
|
this.transitionToMainHeader();
|
|
return;
|
|
}
|
|
|
|
console.log('[HeaderController] Permissions were revoked, showing setup again');
|
|
}
|
|
} catch (error) {
|
|
console.error('[HeaderController] Error checking permissions completed status:', error);
|
|
}
|
|
}
|
|
|
|
await this._resizeForPermissionHeader();
|
|
this.ensureHeader('permission');
|
|
}
|
|
|
|
async transitionToMainHeader(animate = true) {
|
|
if (this.currentHeaderType === 'main') {
|
|
return this._resizeForMain();
|
|
}
|
|
|
|
await this._resizeForMain();
|
|
this.ensureHeader('main');
|
|
}
|
|
|
|
_resizeForMain() {
|
|
if (!window.require) return;
|
|
return window
|
|
.require('electron')
|
|
.ipcRenderer.invoke('resize-header-window', { width: 353, height: 47 })
|
|
.catch(() => {});
|
|
}
|
|
|
|
async _resizeForApiKey() {
|
|
if (!window.require) return;
|
|
return window
|
|
.require('electron')
|
|
.ipcRenderer.invoke('resize-header-window', { width: 350, height: 300 })
|
|
.catch(() => {});
|
|
}
|
|
|
|
async _resizeForPermissionHeader() {
|
|
if (!window.require) return;
|
|
return window
|
|
.require('electron')
|
|
.ipcRenderer.invoke('resize-header-window', { width: 285, height: 220 })
|
|
.catch(() => {});
|
|
}
|
|
|
|
async checkPermissions() {
|
|
if (!window.require) {
|
|
return { success: true };
|
|
}
|
|
|
|
const { ipcRenderer } = window.require('electron');
|
|
|
|
try {
|
|
const permissions = await ipcRenderer.invoke('check-system-permissions');
|
|
console.log('[HeaderController] Current permissions:', permissions);
|
|
|
|
if (!permissions.needsSetup) {
|
|
return { success: true };
|
|
}
|
|
|
|
let errorMessage = '';
|
|
if (!permissions.microphone && !permissions.screen) {
|
|
errorMessage = 'Microphone and screen recording access required';
|
|
}
|
|
|
|
return {
|
|
success: false,
|
|
error: errorMessage
|
|
};
|
|
} catch (error) {
|
|
console.error('[HeaderController] Error checking permissions:', error);
|
|
return {
|
|
success: false,
|
|
error: 'Failed to check permissions'
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
new HeaderTransitionManager();
|
|
});
|