centralized keyframe
This commit is contained in:
parent
ae24d49fe5
commit
186f0a9839
@ -15,15 +15,14 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
transform: translate3d(0, 0, 0);
|
transition: opacity 0.3s ease-in, transform 0.3s ease-in;
|
||||||
backface-visibility: hidden;
|
will-change: opacity, transform;
|
||||||
transition: opacity 0.25s ease-out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.sliding-out) {
|
:host(.sliding-out) {
|
||||||
animation: slideOutUp 0.3s ease-in forwards;
|
opacity: 0;
|
||||||
will-change: opacity, transform;
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.hidden) {
|
:host(.hidden) {
|
||||||
@ -31,17 +30,6 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
pointer-events: none;
|
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;
|
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -50,6 +38,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
-webkit-app-region: drag;
|
||||||
width: 350px;
|
width: 350px;
|
||||||
min-height: 260px;
|
min-height: 260px;
|
||||||
padding: 18px 20px;
|
padding: 18px 20px;
|
||||||
@ -79,6 +68,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
@ -135,6 +125,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.api-input {
|
.api-input {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
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-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; }
|
.provider-label { color: rgba(255, 255, 255, 0.7); font-size: 11px; font-weight: 500; margin-bottom: 6px; }
|
||||||
.api-input, .provider-select {
|
.api-input, .provider-select {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -188,6 +180,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
|
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
@ -233,37 +226,10 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
font-weight: 500; /* Medium */
|
font-weight: 500; /* Medium */
|
||||||
margin: 10px 0;
|
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() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.dragState = null
|
|
||||||
this.wasJustDragged = false
|
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
this.errorMessage = ""
|
this.errorMessage = ""
|
||||||
//////// after_modelStateService ////////
|
//////// after_modelStateService ////////
|
||||||
@ -275,8 +241,6 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
this.loadProviderConfig();
|
this.loadProviderConfig();
|
||||||
//////// after_modelStateService ////////
|
//////// after_modelStateService ////////
|
||||||
|
|
||||||
this.handleMouseMove = this.handleMouseMove.bind(this)
|
|
||||||
this.handleMouseUp = this.handleMouseUp.bind(this)
|
|
||||||
this.handleKeyPress = this.handleKeyPress.bind(this)
|
this.handleKeyPress = this.handleKeyPress.bind(this)
|
||||||
this.handleSubmit = this.handleSubmit.bind(this)
|
this.handleSubmit = this.handleSubmit.bind(this)
|
||||||
this.handleInput = this.handleInput.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;
|
if (sttProviders.length > 0) this.sttProvider = sttProviders[0].id;
|
||||||
|
|
||||||
this.requestUpdate();
|
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) {
|
handleInput(e) {
|
||||||
@ -473,7 +382,6 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
|
|
||||||
handleUsePicklesKey(e) {
|
handleUsePicklesKey(e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (this.wasJustDragged) return
|
|
||||||
|
|
||||||
console.log("Requesting Firebase authentication from main process...")
|
console.log("Requesting Firebase authentication from main process...")
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
@ -515,7 +423,7 @@ export class ApiKeyHeader extends LitElement {
|
|||||||
const isButtonDisabled = this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim();
|
const isButtonDisabled = this.isLoading || !this.llmApiKey.trim() || !this.sttApiKey.trim();
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="container" @mousedown=${this.handleMouseDown}>
|
<div class="container">
|
||||||
<h1 class="title">Enter Your API Keys</h1>
|
<h1 class="title">Enter Your API Keys</h1>
|
||||||
|
|
||||||
<div class="providers-container">
|
<div class="providers-container">
|
||||||
|
@ -9,10 +9,7 @@ export class MainHeader extends LitElement {
|
|||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
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;
|
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) {
|
||||||
@ -33,65 +30,6 @@ export class MainHeader extends LitElement {
|
|||||||
pointer-events: none;
|
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;
|
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
@ -100,6 +38,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
-webkit-app-region: drag;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
height: 47px;
|
height: 47px;
|
||||||
padding: 2px 10px 2px 13px;
|
padding: 2px 10px 2px 13px;
|
||||||
@ -141,6 +80,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.listen-button {
|
.listen-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
padding: 0 13px;
|
padding: 0 13px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@ -193,6 +133,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-actions {
|
.header-actions {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
@ -264,6 +205,7 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-button {
|
.settings-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@ -291,125 +233,20 @@ export class MainHeader extends LitElement {
|
|||||||
width: 16px;
|
width: 16px;
|
||||||
height: 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() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.shortcuts = {};
|
this.shortcuts = {};
|
||||||
this.dragState = null;
|
|
||||||
this.wasJustDragged = false;
|
|
||||||
this.isVisible = true;
|
this.isVisible = true;
|
||||||
this.isAnimating = false;
|
this.isAnimating = false;
|
||||||
this.hasSlidIn = false;
|
this.hasSlidIn = false;
|
||||||
this.settingsHideTimer = null;
|
this.settingsHideTimer = null;
|
||||||
this.isSessionActive = false;
|
this.isSessionActive = false;
|
||||||
this.animationEndTimer = null;
|
this.animationEndTimer = null;
|
||||||
this.handleMouseMove = this.handleMouseMove.bind(this);
|
|
||||||
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
||||||
this.handleAnimationEnd = this.handleAnimationEnd.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() {
|
toggleVisibility() {
|
||||||
if (this.isAnimating) {
|
if (this.isAnimating) {
|
||||||
console.log('[MainHeader] Animation already in progress, ignoring toggle');
|
console.log('[MainHeader] Animation already in progress, ignoring toggle');
|
||||||
@ -431,58 +268,29 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
this.classList.remove('showing', 'hidden');
|
this.classList.remove('showing');
|
||||||
this.classList.add('hiding');
|
this.classList.add('hiding');
|
||||||
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.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')) {
|
||||||
this.classList.remove('hiding');
|
|
||||||
this.classList.add('hidden');
|
this.classList.add('hidden');
|
||||||
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
window.require('electron').ipcRenderer.send('header-animation-finished', 'hidden');
|
||||||
ipcRenderer.send('header-animation-complete', 'hidden');
|
|
||||||
}
|
}
|
||||||
} else if (this.classList.contains('showing')) {
|
} else if (this.classList.contains('showing')) {
|
||||||
this.classList.remove('showing');
|
|
||||||
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
window.require('electron').ipcRenderer.send('header-animation-finished', 'visible');
|
||||||
ipcRenderer.send('header-animation-complete', '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) {
|
invoke(channel, ...args) {
|
||||||
if (this.wasJustDragged) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
window.require('electron').ipcRenderer.invoke(channel, ...args);
|
window.require('electron').ipcRenderer.invoke(channel, ...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showWindow(name, element) {
|
showWindow(name, element) {
|
||||||
if (this.wasJustDragged) return;
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
console.log(`[MainHeader] showWindow('${name}') called at ${Date.now()}`);
|
console.log(`[MainHeader] showWindow('${name}') called at ${Date.now()}`);
|
||||||
@ -564,7 +368,6 @@ export class MainHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hideWindow(name) {
|
hideWindow(name) {
|
||||||
if (this.wasJustDragged) return;
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
console.log(`[MainHeader] hideWindow('${name}') called at ${Date.now()}`);
|
console.log(`[MainHeader] hideWindow('${name}') called at ${Date.now()}`);
|
||||||
window.require('electron').ipcRenderer.send('hide-window', name);
|
window.require('electron').ipcRenderer.send('hide-window', name);
|
||||||
@ -600,7 +403,7 @@ export class MainHeader extends LitElement {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="header" @mousedown=${this.handleMouseDown}>
|
<div class="header">
|
||||||
<button
|
<button
|
||||||
class="listen-button ${this.isSessionActive ? 'active' : ''}"
|
class="listen-button ${this.isSessionActive ? 'active' : ''}"
|
||||||
@click=${() => this.invoke(this.isSessionActive ? 'close-session' : 'toggle-feature', 'listen')}
|
@click=${() => this.invoke(this.isSessionActive ? 'close-session' : 'toggle-feature', 'listen')}
|
||||||
|
@ -4,14 +4,13 @@ export class PermissionHeader extends LitElement {
|
|||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
transform: translate3d(0, 0, 0);
|
transition: opacity 0.3s ease-in, transform 0.3s ease-in;
|
||||||
backface-visibility: hidden;
|
will-change: opacity, transform;
|
||||||
transition: opacity 0.25s ease-out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.sliding-out) {
|
:host(.sliding-out) {
|
||||||
animation: slideOutUp 0.3s ease-in forwards;
|
opacity: 0;
|
||||||
will-change: opacity, transform;
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.hidden) {
|
:host(.hidden) {
|
||||||
@ -19,17 +18,6 @@ export class PermissionHeader extends LitElement {
|
|||||||
pointer-events: none;
|
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;
|
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
@ -38,6 +26,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
-webkit-app-region: drag;
|
||||||
width: 285px;
|
width: 285px;
|
||||||
height: 220px;
|
height: 220px;
|
||||||
padding: 18px 20px;
|
padding: 18px 20px;
|
||||||
@ -67,6 +56,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
@ -157,6 +147,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
@ -198,6 +189,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.continue-button {
|
.continue-button {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
background: rgba(34, 197, 94, 0.8);
|
background: rgba(34, 197, 94, 0.8);
|
||||||
@ -237,30 +229,6 @@ export class PermissionHeader extends LitElement {
|
|||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ────────────────[ GLASS BYPASS ]─────────────── */
|
|
||||||
:host-context(body.has-glass) .container,
|
|
||||||
:host-context(body.has-glass) .action-button,
|
|
||||||
:host-context(body.has-glass) .continue-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,
|
|
||||||
:host-context(body.has-glass) .continue-button::after {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .action-button:hover,
|
|
||||||
:host-context(body.has-glass) .continue-button:hover,
|
|
||||||
:host-context(body.has-glass) .close-button:hover {
|
|
||||||
background: transparent !important;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
static properties = {
|
static properties = {
|
||||||
@ -276,9 +244,6 @@ export class PermissionHeader extends LitElement {
|
|||||||
this.screenGranted = 'unknown';
|
this.screenGranted = 'unknown';
|
||||||
this.isChecking = false;
|
this.isChecking = false;
|
||||||
this.continueCallback = null;
|
this.continueCallback = null;
|
||||||
|
|
||||||
this.handleMouseMove = this.handleMouseMove.bind(this);
|
|
||||||
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectedCallback() {
|
async connectedCallback() {
|
||||||
@ -298,61 +263,6 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleMouseDown(e) {
|
|
||||||
if (e.target.tagName === 'BUTTON') {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async checkPermissions() {
|
async checkPermissions() {
|
||||||
if (!window.require || this.isChecking) return;
|
if (!window.require || this.isChecking) return;
|
||||||
|
|
||||||
@ -390,7 +300,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleMicrophoneClick() {
|
async handleMicrophoneClick() {
|
||||||
if (!window.require || this.microphoneGranted === 'granted' || this.wasJustDragged) return;
|
if (!window.require || this.microphoneGranted === 'granted') return;
|
||||||
|
|
||||||
console.log('[PermissionHeader] Requesting microphone permission...');
|
console.log('[PermissionHeader] Requesting microphone permission...');
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
@ -423,7 +333,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleScreenClick() {
|
async handleScreenClick() {
|
||||||
if (!window.require || this.screenGranted === 'granted' || this.wasJustDragged) return;
|
if (!window.require || this.screenGranted === 'granted') return;
|
||||||
|
|
||||||
console.log('[PermissionHeader] Checking screen recording permission...');
|
console.log('[PermissionHeader] Checking screen recording permission...');
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
@ -453,8 +363,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
async handleContinue() {
|
async handleContinue() {
|
||||||
if (this.continueCallback &&
|
if (this.continueCallback &&
|
||||||
this.microphoneGranted === 'granted' &&
|
this.microphoneGranted === 'granted' &&
|
||||||
this.screenGranted === 'granted' &&
|
this.screenGranted === 'granted') {
|
||||||
!this.wasJustDragged) {
|
|
||||||
// Mark permissions as completed
|
// Mark permissions as completed
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
@ -481,7 +390,7 @@ export class PermissionHeader extends LitElement {
|
|||||||
const allGranted = this.microphoneGranted === 'granted' && this.screenGranted === 'granted';
|
const allGranted = this.microphoneGranted === 'granted' && this.screenGranted === 'granted';
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="container" @mousedown=${this.handleMouseDown}>
|
<div class="container">
|
||||||
<button class="close-button" @click=${this.handleClose} title="Close application">
|
<button class="close-button" @click=${this.handleClose} title="Close application">
|
||||||
<svg width="8" height="8" viewBox="0 0 10 10" fill="currentColor">
|
<svg width="8" height="8" viewBox="0 0 10 10" fill="currentColor">
|
||||||
<path d="M1 1L9 9M9 1L1 9" stroke="currentColor" stroke-width="1.2" />
|
<path d="M1 1L9 9M9 1L1 9" stroke="currentColor" stroke-width="1.2" />
|
||||||
|
@ -237,63 +237,62 @@
|
|||||||
<script>
|
<script>
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
const app = document.getElementById('pickle-glass');
|
const app = document.getElementById('pickle-glass');
|
||||||
let animationTimeout = null;
|
|
||||||
|
|
||||||
if (window.require) {
|
if (window.require) {
|
||||||
const { ipcRenderer } = window.require('electron');
|
const { ipcRenderer } = window.require('electron');
|
||||||
|
|
||||||
|
// --- REFACTORED: Event-driven animation handling ---
|
||||||
|
app.addEventListener('animationend', (event) => {
|
||||||
|
// 숨김 애니메이션이 끝나면 main 프로세스에 알려 창을 실제로 숨깁니다.
|
||||||
|
if (event.animationName === 'slideUpToHeader' || event.animationName === 'settingsCollapseToButton') {
|
||||||
|
console.log(`Animation finished: ${event.animationName}. Notifying main process.`);
|
||||||
|
ipcRenderer.send('animation-finished');
|
||||||
|
|
||||||
|
// 완료 후 애니메이션 클래스 정리
|
||||||
|
app.classList.remove('window-sliding-up', 'settings-window-hide');
|
||||||
|
app.classList.add('window-hidden');
|
||||||
|
} else if (event.animationName === 'slideDownFromHeader' || event.animationName === 'settingsPopFromButton') {
|
||||||
|
// 보이기 애니메이션 완료 후 클래스 정리
|
||||||
|
app.classList.remove('window-sliding-down', 'settings-window-show');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ipcRenderer.on('window-show-animation', () => {
|
ipcRenderer.on('window-show-animation', () => {
|
||||||
console.log('Starting window show animation');
|
console.log('Starting window show animation');
|
||||||
app.classList.remove('window-hidden', 'window-sliding-up', 'settings-window-hide');
|
app.classList.remove('window-hidden', 'window-sliding-up', 'settings-window-hide');
|
||||||
app.classList.add('window-sliding-down');
|
app.classList.add('window-sliding-down');
|
||||||
|
|
||||||
if (animationTimeout) clearTimeout(animationTimeout);
|
|
||||||
animationTimeout = setTimeout(() => {
|
|
||||||
app.classList.remove('window-sliding-down');
|
|
||||||
}, 120);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('window-hide-animation', () => {
|
ipcRenderer.on('window-hide-animation', () => {
|
||||||
console.log('Starting window hide animation');
|
console.log('Starting window hide animation');
|
||||||
app.classList.remove('window-sliding-down', 'settings-window-show');
|
app.classList.remove('window-sliding-down', 'settings-window-show');
|
||||||
app.classList.add('window-sliding-up');
|
app.classList.add('window-sliding-up');
|
||||||
|
|
||||||
if (animationTimeout) clearTimeout(animationTimeout);
|
|
||||||
animationTimeout = setTimeout(() => {
|
|
||||||
app.classList.remove('window-sliding-up');
|
|
||||||
app.classList.add('window-hidden');
|
|
||||||
}, 100);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('settings-window-hide-animation', () => {
|
ipcRenderer.on('settings-window-hide-animation', () => {
|
||||||
console.log('Starting settings window hide animation');
|
console.log('Starting settings window hide animation');
|
||||||
app.classList.remove('window-sliding-down', 'settings-window-show');
|
app.classList.remove('window-sliding-down', 'settings-window-show');
|
||||||
app.classList.add('settings-window-hide');
|
app.classList.add('settings-window-hide');
|
||||||
|
|
||||||
if (animationTimeout) clearTimeout(animationTimeout);
|
|
||||||
animationTimeout = setTimeout(() => {
|
|
||||||
app.classList.remove('settings-window-hide');
|
|
||||||
app.classList.add('window-hidden');
|
|
||||||
}, 100);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- UNCHANGED: Existing logic for listen window movement ---
|
||||||
ipcRenderer.on('listen-window-move-to-center', () => {
|
ipcRenderer.on('listen-window-move-to-center', () => {
|
||||||
console.log('Moving listen window to center');
|
console.log('Moving listen window to center');
|
||||||
app.classList.add('listen-window-moving');
|
app.classList.add('listen-window-moving');
|
||||||
app.classList.remove('listen-window-left');
|
app.classList.remove('listen-window-left');
|
||||||
app.classList.add('listen-window-center');
|
app.classList.add('listen-window-center');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.classList.remove('listen-window-moving');
|
app.classList.remove('listen-window-moving');
|
||||||
}, 350);
|
}, 350);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('listen-window-move-to-left', () => {
|
ipcRenderer.on('listen-window-move-to-left', () => {
|
||||||
console.log('Moving listen window to left');
|
console.log('Moving listen window to left');
|
||||||
app.classList.add('listen-window-moving');
|
app.classList.add('listen-window-moving');
|
||||||
app.classList.remove('listen-window-center');
|
app.classList.remove('listen-window-center');
|
||||||
app.classList.add('listen-window-left');
|
app.classList.add('listen-window-left');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
app.classList.remove('listen-window-moving');
|
app.classList.remove('listen-window-moving');
|
||||||
}, 350);
|
}, 350);
|
||||||
@ -305,6 +304,11 @@
|
|||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
if (params.get('glass') === 'true') {
|
if (params.get('glass') === 'true') {
|
||||||
document.body.classList.add('has-glass');
|
document.body.classList.add('has-glass');
|
||||||
|
// --- ADDED: Link to centralized glass-bypass styles ---
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = '../common/styles/glass-bypass.css';
|
||||||
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
if (params.get('glass') === 'true') {
|
if (params.get('glass') === 'true') {
|
||||||
document.body.classList.add('has-glass');
|
document.body.classList.add('has-glass');
|
||||||
|
// --- ADDED: Link to centralized glass-bypass styles ---
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = '../common/styles/glass-bypass.css';
|
||||||
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
12
src/common/styles/glass-bypass.css
Normal file
12
src/common/styles/glass-bypass.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
이 파일은 body.has-glass 클래스가 적용되었을 때 모든 애니메이션, 트랜지션,
|
||||||
|
배경, 테두리 등을 비활성화하여 깨끗한 투명 효과(Glass)를 보장합니다.
|
||||||
|
*/
|
||||||
|
body.has-glass * {
|
||||||
|
animation: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
background: transparent !important;
|
||||||
|
border: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
backdrop-filter: none !important;
|
||||||
|
}
|
@ -359,12 +359,6 @@ function toggleAllWindowsVisibility(movementManager) {
|
|||||||
if (win.isVisible()) {
|
if (win.isVisible()) {
|
||||||
lastVisibleWindows.add(name);
|
lastVisibleWindows.add(name);
|
||||||
if (name !== 'header') {
|
if (name !== 'header') {
|
||||||
// win.webContents.send('window-hide-animation');
|
|
||||||
// setTimeout(() => {
|
|
||||||
// if (!win.isDestroyed()) {
|
|
||||||
// win.hide();
|
|
||||||
// }
|
|
||||||
// }, 200);
|
|
||||||
win.hide();
|
win.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -460,6 +454,7 @@ function createWindows() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
windowPool.set('header', header);
|
windowPool.set('header', header);
|
||||||
|
header.on('moved', updateLayout);
|
||||||
layoutManager = new WindowLayoutManager(windowPool);
|
layoutManager = new WindowLayoutManager(windowPool);
|
||||||
|
|
||||||
header.webContents.once('dom-ready', () => {
|
header.webContents.once('dom-ready', () => {
|
||||||
@ -586,13 +581,6 @@ function createWindows() {
|
|||||||
} else {
|
} else {
|
||||||
console.log('[WindowManager] No response found, closing window');
|
console.log('[WindowManager] No response found, closing window');
|
||||||
askWindow.webContents.send('window-hide-animation');
|
askWindow.webContents.send('window-hide-animation');
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!askWindow.isDestroyed()) {
|
|
||||||
askWindow.hide();
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
}, 250);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[WindowManager] Error checking Ask window state:', error);
|
console.error('[WindowManager] Error checking Ask window state:', error);
|
||||||
@ -621,13 +609,6 @@ function createWindows() {
|
|||||||
} else {
|
} else {
|
||||||
windowToToggle.webContents.send('window-hide-animation');
|
windowToToggle.webContents.send('window-hide-animation');
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!windowToToggle.isDestroyed()) {
|
|
||||||
windowToToggle.hide();
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
}, 250);
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
windowToToggle.show();
|
windowToToggle.show();
|
||||||
@ -763,6 +744,14 @@ function setupIpcHandlers(movementManager) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on('animation-finished', (event) => {
|
||||||
|
const win = BrowserWindow.fromWebContents(event.sender);
|
||||||
|
if (win && !win.isDestroyed()) {
|
||||||
|
console.log(`[WindowManager] Hiding window after animation.`);
|
||||||
|
win.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on('show-window', (event, args) => {
|
ipcMain.on('show-window', (event, args) => {
|
||||||
const { name, bounds } = typeof args === 'object' && args !== null ? args : { name: args, bounds: null };
|
const { name, bounds } = typeof args === 'object' && args !== null ? args : { name: args, bounds: null };
|
||||||
const win = windowPool.get(name);
|
const win = windowPool.get(name);
|
||||||
@ -811,8 +800,6 @@ function setupIpcHandlers(movementManager) {
|
|||||||
clearTimeout(settingsHideTimer);
|
clearTimeout(settingsHideTimer);
|
||||||
}
|
}
|
||||||
settingsHideTimer = setTimeout(() => {
|
settingsHideTimer = setTimeout(() => {
|
||||||
// window.setAlwaysOnTop(false);
|
|
||||||
// window.hide();
|
|
||||||
if (window && !window.isDestroyed()) {
|
if (window && !window.isDestroyed()) {
|
||||||
window.setAlwaysOnTop(false);
|
window.setAlwaysOnTop(false);
|
||||||
window.hide();
|
window.hide();
|
||||||
@ -1014,74 +1001,20 @@ function setupIpcHandlers(movementManager) {
|
|||||||
return { success: false, error: 'Header window not found' };
|
return { success: false, error: 'Header window not found' };
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('header-animation-complete', (event, state) => {
|
ipcMain.on('header-animation-finished', (event, state) => {
|
||||||
const header = windowPool.get('header');
|
const header = windowPool.get('header');
|
||||||
if (!header) return;
|
if (!header || header.isDestroyed()) return;
|
||||||
|
|
||||||
if (state === 'hidden') {
|
if (state === 'hidden') {
|
||||||
header.hide();
|
header.hide();
|
||||||
|
console.log('[WindowManager] Header hidden after animation.');
|
||||||
} else if (state === 'visible') {
|
} else if (state === 'visible') {
|
||||||
lastVisibleWindows.forEach(name => {
|
// 자식 창들을 다시 보여주는 로직은 toggleAllWindowsVisibility에 이미 있으므로 여기서는 중복 작업을 피합니다.
|
||||||
if (name === 'header') return;
|
console.log('[WindowManager] Header shown after animation.');
|
||||||
const win = windowPool.get(name);
|
|
||||||
if (win) win.show();
|
|
||||||
});
|
|
||||||
|
|
||||||
setImmediate(updateLayout);
|
|
||||||
setTimeout(updateLayout, 120);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.handle('get-header-position', () => {
|
|
||||||
const header = windowPool.get('header');
|
|
||||||
if (header) {
|
|
||||||
const [x, y] = header.getPosition();
|
|
||||||
return { x, y };
|
|
||||||
}
|
|
||||||
return { x: 0, y: 0 };
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.handle('move-header', (event, newX, newY) => {
|
|
||||||
const header = windowPool.get('header');
|
|
||||||
if (header) {
|
|
||||||
const currentY = newY !== undefined ? newY : header.getBounds().y;
|
|
||||||
header.setPosition(newX, currentY, false);
|
|
||||||
|
|
||||||
updateLayout();
|
updateLayout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('move-header-to', (event, newX, newY) => {
|
|
||||||
const header = windowPool.get('header');
|
|
||||||
if (header) {
|
|
||||||
const targetDisplay = screen.getDisplayNearestPoint({ x: newX, y: newY });
|
|
||||||
const { x: workAreaX, y: workAreaY, width, height } = targetDisplay.workArea;
|
|
||||||
const headerBounds = header.getBounds();
|
|
||||||
|
|
||||||
// Only clamp if the new position would actually go out of bounds
|
|
||||||
// This prevents progressive restriction of movement
|
|
||||||
let clampedX = newX;
|
|
||||||
let clampedY = newY;
|
|
||||||
|
|
||||||
// Check if we need to clamp X position
|
|
||||||
if (newX < workAreaX) {
|
|
||||||
clampedX = workAreaX;
|
|
||||||
} else if (newX + headerBounds.width > workAreaX + width) {
|
|
||||||
clampedX = workAreaX + width - headerBounds.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we need to clamp Y position
|
|
||||||
if (newY < workAreaY) {
|
|
||||||
clampedY = workAreaY;
|
|
||||||
} else if (newY + headerBounds.height > workAreaY + height) {
|
|
||||||
clampedY = workAreaY + height - headerBounds.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.setPosition(clampedX, clampedY, false);
|
|
||||||
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.handle('move-window-step', (event, direction) => {
|
ipcMain.handle('move-window-step', (event, direction) => {
|
||||||
if (movementManager) {
|
if (movementManager) {
|
||||||
@ -1095,13 +1028,6 @@ function setupIpcHandlers(movementManager) {
|
|||||||
console.log(`[WindowManager] Force closing window: ${windowName}`);
|
console.log(`[WindowManager] Force closing window: ${windowName}`);
|
||||||
|
|
||||||
window.webContents.send('window-hide-animation');
|
window.webContents.send('window-hide-animation');
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!window.isDestroyed()) {
|
|
||||||
window.hide();
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
}, 250);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,56 +41,6 @@ export class AskView extends LitElement {
|
|||||||
pointer-events: none;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
@ -252,20 +202,6 @@ export class AskView extends LitElement {
|
|||||||
animation: fadeInOut 0.3s ease-in-out;
|
animation: fadeInOut 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeInOut {
|
|
||||||
0% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-10px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-right {
|
.header-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -422,19 +358,6 @@ export class AskView extends LitElement {
|
|||||||
animation-delay: 0.4s;
|
animation-delay: 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0%,
|
|
||||||
80%,
|
|
||||||
100% {
|
|
||||||
opacity: 0.3;
|
|
||||||
transform: scale(0.8);
|
|
||||||
}
|
|
||||||
40% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: scale(1.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.response-line {
|
.response-line {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 2px 0;
|
padding: 2px 0;
|
||||||
@ -596,42 +519,6 @@ export class AskView extends LitElement {
|
|||||||
color: rgba(255, 255, 255, 0.5);
|
color: rgba(255, 255, 255, 0.5);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ────────────────[ GLASS BYPASS ]─────────────── */
|
|
||||||
:host-context(body.has-glass) .ask-container,
|
|
||||||
:host-context(body.has-glass) .response-header,
|
|
||||||
:host-context(body.has-glass) .response-icon,
|
|
||||||
:host-context(body.has-glass) .copy-button,
|
|
||||||
:host-context(body.has-glass) .close-button,
|
|
||||||
:host-context(body.has-glass) .line-copy-button,
|
|
||||||
:host-context(body.has-glass) .text-input-container,
|
|
||||||
:host-context(body.has-glass) .response-container pre,
|
|
||||||
:host-context(body.has-glass) .response-container p code,
|
|
||||||
:host-context(body.has-glass) .response-container pre code {
|
|
||||||
background: transparent !important;
|
|
||||||
border: none !important;
|
|
||||||
outline: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .ask-container::before {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .copy-button:hover,
|
|
||||||
:host-context(body.has-glass) .close-button:hover,
|
|
||||||
:host-context(body.has-glass) .line-copy-button,
|
|
||||||
:host-context(body.has-glass) .line-copy-button:hover,
|
|
||||||
:host-context(body.has-glass) .response-line:hover {
|
|
||||||
background: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .response-container::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) .response-container::-webkit-scrollbar-thumb {
|
|
||||||
background: transparent !important;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -27,56 +27,6 @@ export class AssistantView extends LitElement {
|
|||||||
pointer-events: none;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
font-family: 'Helvetica Neue', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
@ -245,17 +195,6 @@ export class AssistantView extends LitElement {
|
|||||||
animation: slideIn 0.3s ease forwards;
|
animation: slideIn 0.3s ease forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
transform: translateX(10%);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateX(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-controls {
|
.bar-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
@ -349,134 +288,6 @@ export class AssistantView extends LitElement {
|
|||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
color: rgba(255, 255, 255, 0.7);
|
color: rgba(255, 255, 255, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ────────────────[ GLASS BYPASS ]─────────────── */
|
|
||||||
:host-context(body.has-glass) .assistant-container,
|
|
||||||
:host-context(body.has-glass) .top-bar,
|
|
||||||
:host-context(body.has-glass) .toggle-button,
|
|
||||||
:host-context(body.has-glass) .copy-button,
|
|
||||||
:host-context(body.has-glass) .transcription-container,
|
|
||||||
:host-context(body.has-glass) .insights-container,
|
|
||||||
:host-context(body.has-glass) .stt-message,
|
|
||||||
:host-context(body.has-glass) .outline-item,
|
|
||||||
:host-context(body.has-glass) .request-item,
|
|
||||||
:host-context(body.has-glass) .markdown-content,
|
|
||||||
:host-context(body.has-glass) .insights-container pre,
|
|
||||||
:host-context(body.has-glass) .insights-container p code,
|
|
||||||
:host-context(body.has-glass) .insights-container pre code {
|
|
||||||
background: transparent !important;
|
|
||||||
border: none !important;
|
|
||||||
outline: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .assistant-container::before,
|
|
||||||
:host-context(body.has-glass) .assistant-container::after {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .toggle-button:hover,
|
|
||||||
:host-context(body.has-glass) .copy-button:hover,
|
|
||||||
:host-context(body.has-glass) .outline-item:hover,
|
|
||||||
:host-context(body.has-glass) .request-item.clickable:hover,
|
|
||||||
:host-context(body.has-glass) .markdown-content:hover {
|
|
||||||
background: transparent !important;
|
|
||||||
transform: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .transcription-container::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) .transcription-container::-webkit-scrollbar-thumb,
|
|
||||||
:host-context(body.has-glass) .insights-container::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) .insights-container::-webkit-scrollbar-thumb {
|
|
||||||
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) .assistant-container,
|
|
||||||
:host-context(body.has-glass) .stt-message,
|
|
||||||
:host-context(body.has-glass) .toggle-button,
|
|
||||||
:host-context(body.has-glass) .copy-button {
|
|
||||||
border-radius: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) ::-webkit-scrollbar,
|
|
||||||
:host-context(body.has-glass) ::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) ::-webkit-scrollbar-thumb {
|
|
||||||
background: transparent !important;
|
|
||||||
width: 0 !important; /* 스크롤바 자체 숨기기 */
|
|
||||||
}
|
|
||||||
:host-context(body.has-glass) .assistant-container,
|
|
||||||
:host-context(body.has-glass) .top-bar,
|
|
||||||
:host-context(body.has-glass) .toggle-button,
|
|
||||||
:host-context(body.has-glass) .copy-button,
|
|
||||||
:host-context(body.has-glass) .transcription-container,
|
|
||||||
:host-context(body.has-glass) .insights-container,
|
|
||||||
:host-context(body.has-glass) .stt-message,
|
|
||||||
:host-context(body.has-glass) .outline-item,
|
|
||||||
:host-context(body.has-glass) .request-item,
|
|
||||||
:host-context(body.has-glass) .markdown-content,
|
|
||||||
:host-context(body.has-glass) .insights-container pre,
|
|
||||||
:host-context(body.has-glass) .insights-container p code,
|
|
||||||
:host-context(body.has-glass) .insights-container pre code {
|
|
||||||
background: transparent !important;
|
|
||||||
border: none !important;
|
|
||||||
outline: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .assistant-container::before,
|
|
||||||
:host-context(body.has-glass) .assistant-container::after {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .toggle-button:hover,
|
|
||||||
:host-context(body.has-glass) .copy-button:hover,
|
|
||||||
:host-context(body.has-glass) .outline-item:hover,
|
|
||||||
:host-context(body.has-glass) .request-item.clickable:hover,
|
|
||||||
:host-context(body.has-glass) .markdown-content:hover {
|
|
||||||
background: transparent !important;
|
|
||||||
transform: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .transcription-container::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) .transcription-container::-webkit-scrollbar-thumb,
|
|
||||||
:host-context(body.has-glass) .insights-container::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) .insights-container::-webkit-scrollbar-thumb {
|
|
||||||
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) .assistant-container,
|
|
||||||
:host-context(body.has-glass) .stt-message,
|
|
||||||
:host-context(body.has-glass) .toggle-button,
|
|
||||||
:host-context(body.has-glass) .copy-button {
|
|
||||||
border-radius: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) ::-webkit-scrollbar,
|
|
||||||
:host-context(body.has-glass) ::-webkit-scrollbar-track,
|
|
||||||
:host-context(body.has-glass) ::-webkit-scrollbar-thumb {
|
|
||||||
background: transparent !important;
|
|
||||||
width: 0 !important;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
static properties = {
|
static properties = {
|
||||||
|
@ -366,11 +366,6 @@ export class SettingsView extends LitElement {
|
|||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% { transform: rotate(0deg); }
|
|
||||||
100% { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -410,30 +405,7 @@ export class SettingsView extends LitElement {
|
|||||||
}
|
}
|
||||||
.model-item { padding: 5px 8px; font-size: 11px; border-radius: 3px; cursor: pointer; transition: background-color 0.15s; }
|
.model-item { padding: 5px 8px; font-size: 11px; border-radius: 3px; cursor: pointer; transition: background-color 0.15s; }
|
||||||
.model-item:hover { background-color: rgba(255,255,255,0.1); }
|
.model-item:hover { background-color: rgba(255,255,255,0.1); }
|
||||||
.model-item.selected { background-color: rgba(0, 122, 255, 0.4); font-weight: 500; }
|
.model-item.selected { background-color: rgba(0, 122, 255, 0.4); font-weight: 500;
|
||||||
|
|
||||||
/* ────────────────[ GLASS BYPASS ]─────────────── */
|
|
||||||
:host-context(body.has-glass) {
|
|
||||||
animation: none !important;
|
|
||||||
transition: none !important;
|
|
||||||
transform: none !important;
|
|
||||||
will-change: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) * {
|
|
||||||
background: transparent !important;
|
|
||||||
filter: none !important;
|
|
||||||
backdrop-filter: none !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
outline: none !important;
|
|
||||||
border: none !important;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
transition: none !important;
|
|
||||||
animation: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host-context(body.has-glass) .settings-container::before {
|
|
||||||
display: none !important;
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user