minor fix
This commit is contained in:
parent
4c51d5133c
commit
ba8401345b
@ -1,17 +0,0 @@
|
|||||||
FROM python:3.11-slim
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
gcc \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
COPY requirements.txt .
|
|
||||||
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
|
||||||
|
|
||||||
COPY backend/ .
|
|
||||||
|
|
||||||
EXPOSE 8000
|
|
||||||
|
|
||||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
|
@ -1,15 +0,0 @@
|
|||||||
FROM node:18-alpine
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY package*.json ./
|
|
||||||
|
|
||||||
RUN npm ci --only=production
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
EXPOSE 3000
|
|
||||||
|
|
||||||
CMD ["npm", "start"]
|
|
@ -1,35 +0,0 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
backend:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.backend
|
|
||||||
container_name: pickleglass-backend
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "8000:8000"
|
|
||||||
environment:
|
|
||||||
- DATABASE_URL=/app/data/pickleglass.db
|
|
||||||
volumes:
|
|
||||||
- ./backend:/app
|
|
||||||
- ./data:/app/data
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.frontend
|
|
||||||
container_name: pickleglass-frontend
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "3000:3000"
|
|
||||||
environment:
|
|
||||||
- NEXT_PUBLIC_API_URL=http://localhost:8000
|
|
||||||
depends_on:
|
|
||||||
- backend
|
|
||||||
volumes:
|
|
||||||
- .:/app
|
|
||||||
- /app/node_modules
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
mongodb_data:
|
|
@ -346,9 +346,18 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
const isValid = await this.validateApiKey(this.apiKey.trim());
|
const isValid = await this.validateApiKey(this.apiKey.trim());
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
console.log('API key valid - starting slide out animation');
|
console.log('API key valid - checking system permissions...');
|
||||||
this.startSlideOutAnimation();
|
|
||||||
this.validatedApiKey = this.apiKey.trim();
|
const permissionResult = await this.checkAndRequestPermissions();
|
||||||
|
|
||||||
|
if (permissionResult.success) {
|
||||||
|
console.log('All permissions granted - starting slide out animation');
|
||||||
|
this.startSlideOutAnimation();
|
||||||
|
this.validatedApiKey = this.apiKey.trim();
|
||||||
|
} else {
|
||||||
|
this.errorMessage = permissionResult.error || 'Permission setup required';
|
||||||
|
console.log('Permission setup incomplete:', permissionResult);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.errorMessage = 'Invalid API key - please check and try again';
|
this.errorMessage = 'Invalid API key - please check and try again';
|
||||||
console.log('API key validation failed');
|
console.log('API key validation failed');
|
||||||
@ -398,6 +407,58 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkAndRequestPermissions() {
|
||||||
|
if (!window.require) {
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { ipcRenderer } = window.require('electron');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const permissions = await ipcRenderer.invoke('check-system-permissions');
|
||||||
|
console.log('[Permissions] Current status:', permissions);
|
||||||
|
|
||||||
|
if (!permissions.needsSetup) {
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!permissions.microphone) {
|
||||||
|
console.log('[Permissions] Requesting microphone permission...');
|
||||||
|
const micResult = await ipcRenderer.invoke('request-microphone-permission');
|
||||||
|
|
||||||
|
if (!micResult.success) {
|
||||||
|
console.log('[Permissions] Microphone permission denied');
|
||||||
|
await ipcRenderer.invoke('open-system-preferences', 'microphone');
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: 'Please grant microphone access in System Preferences'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!permissions.screen) {
|
||||||
|
console.log('[Permissions] Screen recording permission needed');
|
||||||
|
await ipcRenderer.invoke('open-system-preferences', 'screen-recording');
|
||||||
|
|
||||||
|
this.errorMessage = 'Please grant screen recording permission and try again';
|
||||||
|
this.requestUpdate();
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: 'Please grant screen recording access in System Preferences'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Permissions] Error checking/requesting permissions:', error);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: 'Failed to check permissions'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
startSlideOutAnimation() {
|
startSlideOutAnimation() {
|
||||||
this.classList.add('sliding-out');
|
this.classList.add('sliding-out');
|
||||||
}
|
}
|
||||||
|
@ -10,25 +10,25 @@ export class AppHeader extends LitElement {
|
|||||||
display: block;
|
display: block;
|
||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
transition: transform 0.25s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.25s ease-out;
|
transition: transform 0.2s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.2s ease-out;
|
||||||
|
will-change: transform, opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.hiding) {
|
:host(.hiding) {
|
||||||
animation: slideUp 0.45s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards;
|
animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.6, 1) forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.showing) {
|
:host(.showing) {
|
||||||
animation: slideDown 0.5s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;
|
animation: slideDown 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.sliding-in) {
|
:host(.sliding-in) {
|
||||||
animation: fadeIn 0.25s ease-out forwards;
|
animation: fadeIn 0.2s ease-out forwards;
|
||||||
will-change: opacity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.hidden) {
|
:host(.hidden) {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-180%) scale(0.8);
|
transform: translateY(-150%) scale(0.85);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,65 +36,50 @@ export class AppHeader extends LitElement {
|
|||||||
0% {
|
0% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0) scale(1);
|
transform: translateY(0) scale(1);
|
||||||
filter: blur(0px) brightness(1);
|
filter: blur(0px);
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
}
|
||||||
25% {
|
30% {
|
||||||
opacity: 0.85;
|
opacity: 0.7;
|
||||||
transform: translateY(-20%) scale(0.96);
|
transform: translateY(-20%) scale(0.98);
|
||||||
filter: blur(0px) brightness(0.95);
|
filter: blur(0.5px);
|
||||||
box-shadow: 0 6px 28px rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
}
|
||||||
50% {
|
70% {
|
||||||
opacity: 0.5;
|
opacity: 0.3;
|
||||||
transform: translateY(-60%) scale(0.9);
|
transform: translateY(-80%) scale(0.92);
|
||||||
filter: blur(1px) brightness(0.85);
|
filter: blur(1.5px);
|
||||||
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
75% {
|
|
||||||
opacity: 0.15;
|
|
||||||
transform: translateY(-120%) scale(0.85);
|
|
||||||
filter: blur(2px) brightness(0.75);
|
|
||||||
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-180%) scale(0.8);
|
transform: translateY(-150%) scale(0.85);
|
||||||
filter: blur(3px) brightness(0.7);
|
filter: blur(2px);
|
||||||
box-shadow: 0 0px 0px rgba(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes slideDown {
|
@keyframes slideDown {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-180%) scale(0.8);
|
transform: translateY(-150%) scale(0.85);
|
||||||
filter: blur(3px) brightness(0.7);
|
filter: blur(2px);
|
||||||
box-shadow: 0 0px 0px rgba(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
40% {
|
30% {
|
||||||
opacity: 0.6;
|
opacity: 0.5;
|
||||||
transform: translateY(-30%) scale(0.95);
|
transform: translateY(-50%) scale(0.92);
|
||||||
filter: blur(1px) brightness(0.9);
|
filter: blur(1px);
|
||||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
}
|
||||||
70% {
|
65% {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
transform: translateY(-5%) scale(1.01);
|
transform: translateY(-5%) scale(0.99);
|
||||||
filter: blur(0.3px) brightness(1.02);
|
filter: blur(0.2px);
|
||||||
box-shadow: 0 7px 28px rgba(0, 0, 0, 0.28);
|
|
||||||
}
|
}
|
||||||
85% {
|
85% {
|
||||||
opacity: 0.98;
|
opacity: 0.98;
|
||||||
transform: translateY(1%) scale(0.995);
|
transform: translateY(2%) scale(1.005);
|
||||||
filter: blur(0.1px) brightness(1.01);
|
filter: blur(0px);
|
||||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.31);
|
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0) scale(1);
|
transform: translateY(0) scale(1);
|
||||||
filter: blur(0px) brightness(1);
|
filter: blur(0px);
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,6 +303,7 @@ export class AppHeader extends LitElement {
|
|||||||
this.hasSlidIn = false;
|
this.hasSlidIn = false;
|
||||||
this.settingsHideTimer = null;
|
this.settingsHideTimer = null;
|
||||||
this.isSessionActive = false;
|
this.isSessionActive = false;
|
||||||
|
this.animationEndTimer = null;
|
||||||
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
@ -388,7 +374,15 @@ export class AppHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleVisibility() {
|
toggleVisibility() {
|
||||||
if (this.isAnimating) return;
|
if (this.isAnimating) {
|
||||||
|
console.log('[AppHeader] Animation already in progress, ignoring toggle');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.animationEndTimer) {
|
||||||
|
clearTimeout(this.animationEndTimer);
|
||||||
|
this.animationEndTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.isAnimating = true;
|
this.isAnimating = true;
|
||||||
|
|
||||||
@ -403,17 +397,34 @@ export class AppHeader extends LitElement {
|
|||||||
this.classList.remove('showing', 'hidden');
|
this.classList.remove('showing', 'hidden');
|
||||||
this.classList.add('hiding');
|
this.classList.add('hiding');
|
||||||
this.isVisible = false;
|
this.isVisible = false;
|
||||||
|
|
||||||
|
this.animationEndTimer = setTimeout(() => {
|
||||||
|
if (this.classList.contains('hiding')) {
|
||||||
|
this.handleAnimationEnd({ target: this });
|
||||||
|
}
|
||||||
|
}, 350);
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
this.classList.remove('hiding', 'hidden');
|
this.classList.remove('hiding', 'hidden');
|
||||||
this.classList.add('showing');
|
this.classList.add('showing');
|
||||||
this.isVisible = true;
|
this.isVisible = true;
|
||||||
|
|
||||||
|
this.animationEndTimer = setTimeout(() => {
|
||||||
|
if (this.classList.contains('showing')) {
|
||||||
|
this.handleAnimationEnd({ target: this });
|
||||||
|
}
|
||||||
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAnimationEnd(e) {
|
handleAnimationEnd(e) {
|
||||||
if (e.target !== this) return;
|
if (e.target !== this) return;
|
||||||
|
|
||||||
|
if (this.animationEndTimer) {
|
||||||
|
clearTimeout(this.animationEndTimer);
|
||||||
|
this.animationEndTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.isAnimating = false;
|
this.isAnimating = false;
|
||||||
|
|
||||||
if (this.classList.contains('hiding')) {
|
if (this.classList.contains('hiding')) {
|
||||||
@ -434,7 +445,7 @@ export class AppHeader extends LitElement {
|
|||||||
} else if (this.classList.contains('sliding-in')) {
|
} else if (this.classList.contains('sliding-in')) {
|
||||||
this.classList.remove('sliding-in');
|
this.classList.remove('sliding-in');
|
||||||
this.hasSlidIn = true;
|
this.hasSlidIn = true;
|
||||||
console.log('AppHeader slide-in animation completed');
|
console.log('[AppHeader] Slide-in animation completed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,6 +471,11 @@ export class AppHeader extends LitElement {
|
|||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
this.removeEventListener('animationend', this.handleAnimationEnd);
|
this.removeEventListener('animationend', this.handleAnimationEnd);
|
||||||
|
|
||||||
|
if (this.animationEndTimer) {
|
||||||
|
clearTimeout(this.animationEndTimer);
|
||||||
|
this.animationEndTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
ipcRenderer.removeAllListeners('toggle-header-visibility');
|
ipcRenderer.removeAllListeners('toggle-header-visibility');
|
||||||
|
@ -81,11 +81,31 @@ class HeaderTransitionManager {
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.warn('[HeaderController] Login payload indicates verification failure. Proceeding to AppHeader UI only.');
|
console.warn('[HeaderController] Login payload indicates verification failure. Proceeding to AppHeader UI only.');
|
||||||
this.transitionToAppHeader();
|
// Check permissions before transitioning
|
||||||
|
const permissionResult = await this.checkPermissions();
|
||||||
|
if (permissionResult.success) {
|
||||||
|
this.transitionToAppHeader();
|
||||||
|
} else {
|
||||||
|
console.log('[HeaderController] Permissions not granted after login error');
|
||||||
|
if (this.apiKeyHeader) {
|
||||||
|
this.apiKeyHeader.errorMessage = permissionResult.error || 'Permission setup required';
|
||||||
|
this.apiKeyHeader.requestUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[HeaderController] Sign-in failed', error);
|
console.error('[HeaderController] Sign-in failed', error);
|
||||||
this.transitionToAppHeader();
|
// Check permissions before transitioning
|
||||||
|
const permissionResult = await this.checkPermissions();
|
||||||
|
if (permissionResult.success) {
|
||||||
|
this.transitionToAppHeader();
|
||||||
|
} else {
|
||||||
|
console.log('[HeaderController] Permissions not granted after sign-in failure');
|
||||||
|
if (this.apiKeyHeader) {
|
||||||
|
this.apiKeyHeader.errorMessage = permissionResult.error || 'Permission setup required';
|
||||||
|
this.apiKeyHeader.requestUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -125,7 +145,17 @@ class HeaderTransitionManager {
|
|||||||
console.log('[HeaderController] Firebase sign-in successful via ID token');
|
console.log('[HeaderController] Firebase sign-in successful via ID token');
|
||||||
} else {
|
} else {
|
||||||
console.warn('[HeaderController] No ID token received from deeplink, virtual key request may fail');
|
console.warn('[HeaderController] No ID token received from deeplink, virtual key request may fail');
|
||||||
this.transitionToAppHeader();
|
// Check permissions before transitioning
|
||||||
|
const permissionResult = await this.checkPermissions();
|
||||||
|
if (permissionResult.success) {
|
||||||
|
this.transitionToAppHeader();
|
||||||
|
} else {
|
||||||
|
console.log('[HeaderController] Permissions not granted after Firebase auth');
|
||||||
|
if (this.apiKeyHeader) {
|
||||||
|
this.apiKeyHeader.errorMessage = permissionResult.error || 'Permission setup required';
|
||||||
|
this.apiKeyHeader.requestUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[HeaderController] Firebase auth failed:', error);
|
console.error('[HeaderController] Firebase auth failed:', error);
|
||||||
@ -173,11 +203,25 @@ class HeaderTransitionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
console.log('[HeaderController] User is logged in, transitioning to AppHeader');
|
console.log('[HeaderController] User is logged in, checking permissions...');
|
||||||
this.transitionToAppHeader(!this.hasApiKey);
|
const permissionResult = await this.checkPermissions();
|
||||||
|
if (permissionResult.success) {
|
||||||
|
this.transitionToAppHeader(!this.hasApiKey);
|
||||||
|
} else {
|
||||||
|
console.log('[HeaderController] Permissions not granted, staying on ApiKeyHeader');
|
||||||
|
if (this.apiKeyHeader) {
|
||||||
|
this.apiKeyHeader.errorMessage = permissionResult.error || 'Permission setup required';
|
||||||
|
this.apiKeyHeader.requestUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (this.hasApiKey) {
|
} else if (this.hasApiKey) {
|
||||||
console.log('[HeaderController] No Firebase user but API key exists, showing AppHeader');
|
console.log('[HeaderController] No Firebase user but API key exists, checking permissions...');
|
||||||
this.transitionToAppHeader(false);
|
const permissionResult = await this.checkPermissions();
|
||||||
|
if (permissionResult.success) {
|
||||||
|
this.transitionToAppHeader(false);
|
||||||
|
} else {
|
||||||
|
console.log('[HeaderController] Permissions not granted, staying on ApiKeyHeader');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[HeaderController] No auth & no API key — showing ApiKeyHeader');
|
console.log('[HeaderController] No auth & no API key — showing ApiKeyHeader');
|
||||||
this.transitionToApiKeyHeader();
|
this.transitionToApiKeyHeader();
|
||||||
@ -185,7 +229,6 @@ class HeaderTransitionManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
notifyHeaderState(stateOverride) {
|
notifyHeaderState(stateOverride) {
|
||||||
const state = stateOverride || this.currentHeaderType || 'apikey';
|
const state = stateOverride || this.currentHeaderType || 'apikey';
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
@ -193,33 +236,46 @@ class HeaderTransitionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _bootstrap() {
|
async _bootstrap() {
|
||||||
let storedKey = null;
|
let storedKey = null;
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
try {
|
try {
|
||||||
storedKey = await window
|
storedKey = await window
|
||||||
.require('electron')
|
.require('electron')
|
||||||
.ipcRenderer.invoke('get-current-api-key');
|
.ipcRenderer.invoke('get-current-api-key');
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
this.hasApiKey = !!storedKey;
|
this.hasApiKey = !!storedKey;
|
||||||
|
|
||||||
const user = await new Promise(resolve => {
|
|
||||||
const unsubscribe = onAuthStateChanged(auth, u => {
|
|
||||||
unsubscribe();
|
|
||||||
resolve(u);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (user || this.hasApiKey) {
|
|
||||||
await this._resizeForApp();
|
|
||||||
this.ensureHeader('app');
|
|
||||||
} else {
|
|
||||||
await this._resizeForApiKey();
|
|
||||||
this.ensureHeader('apikey');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const user = await new Promise(resolve => {
|
||||||
|
const unsubscribe = onAuthStateChanged(auth, u => {
|
||||||
|
unsubscribe();
|
||||||
|
resolve(u);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user || this.hasApiKey) {
|
||||||
|
const permissionResult = await this.checkPermissions();
|
||||||
|
|
||||||
|
if (permissionResult.success) {
|
||||||
|
await this._resizeForApp();
|
||||||
|
this.ensureHeader('app');
|
||||||
|
} else {
|
||||||
|
await this._resizeForApiKey();
|
||||||
|
this.ensureHeader('apikey');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.apiKeyHeader) {
|
||||||
|
this.apiKeyHeader.errorMessage = permissionResult.error || 'Permission setup required';
|
||||||
|
this.apiKeyHeader.requestUpdate();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await this._resizeForApiKey();
|
||||||
|
this.ensureHeader('apikey');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async transitionToAppHeader(animate = true) {
|
async transitionToAppHeader(animate = true) {
|
||||||
if (this.currentHeaderType === 'app') {
|
if (this.currentHeaderType === 'app') {
|
||||||
@ -249,23 +305,69 @@ class HeaderTransitionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_resizeForApp() {
|
_resizeForApp() {
|
||||||
if (!window.require) return;
|
if (!window.require) return;
|
||||||
return window
|
return window
|
||||||
.require('electron')
|
.require('electron')
|
||||||
.ipcRenderer.invoke('resize-header-window', { width: 353, height: 60 })
|
.ipcRenderer.invoke('resize-header-window', { width: 353, height: 60 })
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
async _resizeForApiKey() {
|
||||||
|
if (!window.require) return;
|
||||||
|
return window
|
||||||
|
.require('electron')
|
||||||
|
.ipcRenderer.invoke('resize-header-window', { width: 285, height: 220 })
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
async transitionToApiKeyHeader() {
|
||||||
|
await this._resizeForApiKey();
|
||||||
|
|
||||||
|
if (this.currentHeaderType !== 'apikey') {
|
||||||
|
this.ensureHeader('apikey');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.apiKeyHeader) this.apiKeyHeader.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkPermissions() {
|
||||||
|
if (!window.require) {
|
||||||
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
async transitionToApiKeyHeader() {
|
const { ipcRenderer } = window.require('electron');
|
||||||
await window.require('electron')
|
|
||||||
.ipcRenderer.invoke('resize-header-window', { width: 285, height: 220 });
|
try {
|
||||||
|
// Check permission status
|
||||||
|
const permissions = await ipcRenderer.invoke('check-system-permissions');
|
||||||
|
console.log('[HeaderController] Current permissions:', permissions);
|
||||||
|
|
||||||
if (this.currentHeaderType !== 'apikey') {
|
if (!permissions.needsSetup) {
|
||||||
this.ensureHeader('apikey');
|
return { success: true };
|
||||||
}
|
|
||||||
|
|
||||||
if (this.apiKeyHeader) this.apiKeyHeader.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If permissions are not set up, return false
|
||||||
|
let errorMessage = '';
|
||||||
|
if (!permissions.microphone && !permissions.screen) {
|
||||||
|
errorMessage = 'Microphone and screen recording access required';
|
||||||
|
} else if (!permissions.microphone) {
|
||||||
|
errorMessage = 'Microphone access required';
|
||||||
|
} else if (!permissions.screen) {
|
||||||
|
errorMessage = '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', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
File diff suppressed because it is too large
Load Diff
12
src/index.js
12
src/index.js
@ -1,9 +1,9 @@
|
|||||||
try {
|
// try {
|
||||||
const reloader = require('electron-reloader');
|
// const reloader = require('electron-reloader');
|
||||||
reloader(module, {
|
// reloader(module, {
|
||||||
});
|
// });
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
}
|
// }
|
||||||
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user