diff --git a/src/app/ApiKeyHeader.js b/src/app/ApiKeyHeader.js index 92962c8..76abf21 100644 --- a/src/app/ApiKeyHeader.js +++ b/src/app/ApiKeyHeader.js @@ -15,15 +15,14 @@ export class ApiKeyHeader extends LitElement { static styles = css` :host { - display: block; - transform: translate3d(0, 0, 0); - backface-visibility: hidden; - transition: opacity 0.25s ease-out; + display: block; + transition: opacity 0.3s ease-in, transform 0.3s ease-in; + will-change: opacity, transform; } :host(.sliding-out) { - animation: slideOutUp 0.3s ease-in forwards; - will-change: opacity, transform; + opacity: 0; + transform: translateY(-20px); } :host(.hidden) { @@ -31,17 +30,6 @@ export class ApiKeyHeader extends LitElement { pointer-events: none; } - @keyframes slideOutUp { - from { - opacity: 1; - transform: translateY(0); - } - to { - opacity: 0; - transform: translateY(-20px); - } - } - * { font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; cursor: default; @@ -50,6 +38,7 @@ export class ApiKeyHeader extends LitElement { } .container { + -webkit-app-region: drag; width: 350px; min-height: 260px; padding: 18px 20px; @@ -79,6 +68,7 @@ export class ApiKeyHeader extends LitElement { } .close-button { + -webkit-app-region: no-drag; position: absolute; top: 10px; right: 10px; @@ -135,6 +125,7 @@ export class ApiKeyHeader extends LitElement { } .api-input { + -webkit-app-region: no-drag; width: 100%; height: 34px; background: rgba(255, 255, 255, 0.1); @@ -162,6 +153,7 @@ export class ApiKeyHeader extends LitElement { .provider-column { flex: 1; display: flex; flex-direction: column; align-items: center; } .provider-label { color: rgba(255, 255, 255, 0.7); font-size: 11px; font-weight: 500; margin-bottom: 6px; } .api-input, .provider-select { + -webkit-app-region: no-drag; width: 100%; height: 34px; text-align: center; @@ -188,6 +180,7 @@ export class ApiKeyHeader extends LitElement { .action-button { + -webkit-app-region: no-drag; width: 100%; height: 34px; background: rgba(255, 255, 255, 0.2); @@ -233,37 +226,10 @@ export class ApiKeyHeader extends LitElement { font-weight: 500; /* Medium */ margin: 10px 0; } - - - /* ────────────────[ GLASS BYPASS ]─────────────── */ - :host-context(body.has-glass) .container, - :host-context(body.has-glass) .api-input, - :host-context(body.has-glass) .provider-select, - :host-context(body.has-glass) .action-button, - :host-context(body.has-glass) .close-button { - background: transparent !important; - border: none !important; - box-shadow: none !important; - filter: none !important; - backdrop-filter: none !important; - } - - :host-context(body.has-glass) .container::after, - :host-context(body.has-glass) .action-button::after { - display: none !important; - } - - :host-context(body.has-glass) .action-button:hover, - :host-context(body.has-glass) .provider-select:hover, - :host-context(body.has-glass) .close-button:hover { - background: transparent !important; - } ` constructor() { super() - this.dragState = null - this.wasJustDragged = false this.isLoading = false this.errorMessage = "" //////// after_modelStateService //////// @@ -275,8 +241,6 @@ export class ApiKeyHeader extends LitElement { this.loadProviderConfig(); //////// after_modelStateService //////// - this.handleMouseMove = this.handleMouseMove.bind(this) - this.handleMouseUp = this.handleMouseUp.bind(this) this.handleKeyPress = this.handleKeyPress.bind(this) this.handleSubmit = this.handleSubmit.bind(this) this.handleInput = this.handleInput.bind(this) @@ -321,61 +285,6 @@ export class ApiKeyHeader extends LitElement { if (sttProviders.length > 0) this.sttProvider = sttProviders[0].id; this.requestUpdate(); -} - - async handleMouseDown(e) { - if (e.target.tagName === "INPUT" || e.target.tagName === "BUTTON" || e.target.tagName === "SELECT") { - return - } - - e.preventDefault() - - const { ipcRenderer } = window.require("electron") - const initialPosition = await ipcRenderer.invoke("get-header-position") - - this.dragState = { - initialMouseX: e.screenX, - initialMouseY: e.screenY, - initialWindowX: initialPosition.x, - initialWindowY: initialPosition.y, - moved: false, - } - - window.addEventListener("mousemove", this.handleMouseMove) - window.addEventListener("mouseup", this.handleMouseUp, { once: true }) - } - - handleMouseMove(e) { - if (!this.dragState) return - - const deltaX = Math.abs(e.screenX - this.dragState.initialMouseX) - const deltaY = Math.abs(e.screenY - this.dragState.initialMouseY) - - if (deltaX > 3 || deltaY > 3) { - this.dragState.moved = true - } - - const newWindowX = this.dragState.initialWindowX + (e.screenX - this.dragState.initialMouseX) - const newWindowY = this.dragState.initialWindowY + (e.screenY - this.dragState.initialMouseY) - - const { ipcRenderer } = window.require("electron") - ipcRenderer.invoke("move-header-to", newWindowX, newWindowY) - } - - handleMouseUp(e) { - if (!this.dragState) return - - const wasDragged = this.dragState.moved - - window.removeEventListener("mousemove", this.handleMouseMove) - this.dragState = null - - if (wasDragged) { - this.wasJustDragged = true - setTimeout(() => { - this.wasJustDragged = false - }, 200) - } } handleInput(e) { @@ -473,7 +382,6 @@ export class ApiKeyHeader extends LitElement { handleUsePicklesKey(e) { e.preventDefault() - if (this.wasJustDragged) return console.log("Requesting Firebase authentication from main process...") if (window.require) { @@ -515,7 +423,7 @@ export class ApiKeyHeader extends LitElement { const isButtonDisabled = this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim(); return html` -
+

Enter Your API Keys

diff --git a/src/app/MainHeader.js b/src/app/MainHeader.js index 7c92f7c..e8b85b1 100644 --- a/src/app/MainHeader.js +++ b/src/app/MainHeader.js @@ -9,10 +9,7 @@ export class MainHeader extends LitElement { static styles = css` :host { display: flex; - transform: translate3d(0, 0, 0); - backface-visibility: hidden; transition: transform 0.2s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.2s ease-out; - will-change: transform, opacity; } :host(.hiding) { @@ -33,65 +30,6 @@ export class MainHeader extends LitElement { pointer-events: none; } - @keyframes slideUp { - 0% { - opacity: 1; - transform: translateY(0) scale(1); - filter: blur(0px); - } - 30% { - opacity: 0.7; - transform: translateY(-20%) scale(0.98); - filter: blur(0.5px); - } - 70% { - opacity: 0.3; - transform: translateY(-80%) scale(0.92); - filter: blur(1.5px); - } - 100% { - opacity: 0; - transform: translateY(-150%) scale(0.85); - filter: blur(2px); - } - } - - @keyframes slideDown { - 0% { - opacity: 0; - transform: translateY(-150%) scale(0.85); - filter: blur(2px); - } - 30% { - opacity: 0.5; - transform: translateY(-50%) scale(0.92); - filter: blur(1px); - } - 65% { - opacity: 0.9; - transform: translateY(-5%) scale(0.99); - filter: blur(0.2px); - } - 85% { - opacity: 0.98; - transform: translateY(2%) scale(1.005); - filter: blur(0px); - } - 100% { - opacity: 1; - transform: translateY(0) scale(1); - filter: blur(0px); - } - } - - @keyframes fadeIn { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } - } * { font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; @@ -100,6 +38,7 @@ export class MainHeader extends LitElement { } .header { + -webkit-app-region: drag; width: max-content; height: 47px; padding: 2px 10px 2px 13px; @@ -141,6 +80,7 @@ export class MainHeader extends LitElement { } .listen-button { + -webkit-app-region: no-drag; height: 26px; padding: 0 13px; background: transparent; @@ -193,6 +133,7 @@ export class MainHeader extends LitElement { } .header-actions { + -webkit-app-region: no-drag; height: 26px; box-sizing: border-box; justify-content: flex-start; @@ -264,6 +205,7 @@ export class MainHeader extends LitElement { } .settings-button { + -webkit-app-region: no-drag; padding: 5px; border-radius: 50%; background: transparent; @@ -291,125 +233,20 @@ export class MainHeader extends LitElement { width: 16px; height: 16px; } - - /* ────────────────[ GLASS BYPASS ]─────────────── */ - :host-context(body.has-glass) .header, - :host-context(body.has-glass) .listen-button, - :host-context(body.has-glass) .header-actions, - :host-context(body.has-glass) .settings-button { - background: transparent !important; - filter: none !important; - box-shadow: none !important; - backdrop-filter: none !important; - } - :host-context(body.has-glass) .icon-box { - background: transparent !important; - border: none !important; - } - - :host-context(body.has-glass) .header::before, - :host-context(body.has-glass) .header::after, - :host-context(body.has-glass) .listen-button::before, - :host-context(body.has-glass) .listen-button::after { - display: none !important; - } - - :host-context(body.has-glass) .header-actions:hover, - :host-context(body.has-glass) .settings-button:hover, - :host-context(body.has-glass) .listen-button:hover::before { - background: transparent !important; - } - :host-context(body.has-glass) * { - animation: none !important; - transition: none !important; - transform: none !important; - filter: none !important; - backdrop-filter: none !important; - box-shadow: none !important; - } - - :host-context(body.has-glass) .header, - :host-context(body.has-glass) .listen-button, - :host-context(body.has-glass) .header-actions, - :host-context(body.has-glass) .settings-button, - :host-context(body.has-glass) .icon-box { - border-radius: 0 !important; - } - :host-context(body.has-glass) { - animation: none !important; - transition: none !important; - transform: none !important; - will-change: auto !important; - } `; constructor() { super(); this.shortcuts = {}; - this.dragState = null; - this.wasJustDragged = false; this.isVisible = true; this.isAnimating = false; this.hasSlidIn = false; this.settingsHideTimer = null; this.isSessionActive = false; this.animationEndTimer = null; - this.handleMouseMove = this.handleMouseMove.bind(this); - this.handleMouseUp = this.handleMouseUp.bind(this); this.handleAnimationEnd = this.handleAnimationEnd.bind(this); } - async handleMouseDown(e) { - e.preventDefault(); - - const { ipcRenderer } = window.require('electron'); - const initialPosition = await ipcRenderer.invoke('get-header-position'); - - this.dragState = { - initialMouseX: e.screenX, - initialMouseY: e.screenY, - initialWindowX: initialPosition.x, - initialWindowY: initialPosition.y, - moved: false, - }; - - window.addEventListener('mousemove', this.handleMouseMove, { capture: true }); - window.addEventListener('mouseup', this.handleMouseUp, { once: true, capture: true }); - } - - handleMouseMove(e) { - if (!this.dragState) return; - - const deltaX = Math.abs(e.screenX - this.dragState.initialMouseX); - const deltaY = Math.abs(e.screenY - this.dragState.initialMouseY); - - if (deltaX > 3 || deltaY > 3) { - this.dragState.moved = true; - } - - const newWindowX = this.dragState.initialWindowX + (e.screenX - this.dragState.initialMouseX); - const newWindowY = this.dragState.initialWindowY + (e.screenY - this.dragState.initialMouseY); - - const { ipcRenderer } = window.require('electron'); - ipcRenderer.invoke('move-header-to', newWindowX, newWindowY); - } - - handleMouseUp(e) { - if (!this.dragState) return; - - const wasDragged = this.dragState.moved; - - window.removeEventListener('mousemove', this.handleMouseMove, { capture: true }); - this.dragState = null; - - if (wasDragged) { - this.wasJustDragged = true; - setTimeout(() => { - this.wasJustDragged = false; - }, 0); - } - } - toggleVisibility() { if (this.isAnimating) { console.log('[MainHeader] Animation already in progress, ignoring toggle'); @@ -431,58 +268,29 @@ export class MainHeader extends LitElement { } hide() { - this.classList.remove('showing', 'hidden'); + this.classList.remove('showing'); this.classList.add('hiding'); - this.isVisible = false; - - this.animationEndTimer = setTimeout(() => { - if (this.classList.contains('hiding')) { - this.handleAnimationEnd({ target: this }); - } - }, 350); } - + show() { this.classList.remove('hiding', 'hidden'); this.classList.add('showing'); - this.isVisible = true; - - this.animationEndTimer = setTimeout(() => { - if (this.classList.contains('showing')) { - this.handleAnimationEnd({ target: this }); - } - }, 400); } - + handleAnimationEnd(e) { if (e.target !== this) return; - - if (this.animationEndTimer) { - clearTimeout(this.animationEndTimer); - this.animationEndTimer = null; - } - + this.isAnimating = false; - + if (this.classList.contains('hiding')) { - this.classList.remove('hiding'); this.classList.add('hidden'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('header-animation-complete', 'hidden'); + window.require('electron').ipcRenderer.send('header-animation-finished', 'hidden'); } } else if (this.classList.contains('showing')) { - this.classList.remove('showing'); - if (window.require) { - const { ipcRenderer } = window.require('electron'); - ipcRenderer.send('header-animation-complete', 'visible'); + window.require('electron').ipcRenderer.send('header-animation-finished', 'visible'); } - } else if (this.classList.contains('sliding-in')) { - this.classList.remove('sliding-in'); - this.hasSlidIn = true; - console.log('[MainHeader] Slide-in animation completed'); } } @@ -530,16 +338,12 @@ export class MainHeader extends LitElement { } invoke(channel, ...args) { - if (this.wasJustDragged) { - return; - } if (window.require) { window.require('electron').ipcRenderer.invoke(channel, ...args); } } showWindow(name, element) { - if (this.wasJustDragged) return; if (window.require) { const { ipcRenderer } = window.require('electron'); console.log(`[MainHeader] showWindow('${name}') called at ${Date.now()}`); @@ -564,7 +368,6 @@ export class MainHeader extends LitElement { } hideWindow(name) { - if (this.wasJustDragged) return; if (window.require) { console.log(`[MainHeader] hideWindow('${name}') called at ${Date.now()}`); window.require('electron').ipcRenderer.send('hide-window', name); @@ -600,7 +403,7 @@ export class MainHeader extends LitElement { render() { return html` -
+