This commit is contained in:
samtiz 2025-07-10 04:51:08 +09:00
commit 2a1edb6ed8
14 changed files with 221 additions and 956 deletions

35
package-lock.json generated
View File

@ -4172,6 +4172,28 @@
"node": ">= 8"
}
},
"node_modules/fs-temp": {
"version": "1.2.1",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"random-path": "^0.1.0"
}
},
"node_modules/fs-xattr": {
"version": "0.3.1",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"!win32"
],
"engines": {
"node": ">=8.6.0"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"dev": true,
@ -5136,6 +5158,19 @@
"lru-cache": "6.0.0"
}
},
"node_modules/macos-alias": {
"version": "0.2.12",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"dependencies": {
"nan": "^2.4.0"
}
},
"node_modules/make-fetch-happen": {
"version": "10.2.1",
"dev": true,

View File

@ -25,15 +25,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) {
@ -41,17 +40,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;
@ -60,6 +48,7 @@ export class ApiKeyHeader extends LitElement {
}
.container {
-webkit-app-region: drag;
width: 350px;
min-height: 260px;
padding: 18px 20px;
@ -89,6 +78,7 @@ export class ApiKeyHeader extends LitElement {
}
.close-button {
-webkit-app-region: no-drag;
position: absolute;
top: 10px;
right: 10px;
@ -168,6 +158,7 @@ export class ApiKeyHeader extends LitElement {
}
.api-input {
-webkit-app-region: no-drag;
width: 100%;
height: 34px;
background: rgba(255, 255, 255, 0.1);
@ -195,6 +186,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;
@ -221,6 +213,7 @@ export class ApiKeyHeader extends LitElement {
.action-button {
-webkit-app-region: no-drag;
width: 100%;
height: 34px;
background: rgba(255, 255, 255, 0.2);
@ -266,37 +259,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 = ""
this.successMessage = ""
@ -358,8 +324,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)
@ -1533,7 +1497,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) {

View File

@ -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,50 +338,37 @@ 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;
showSettingsWindow(element) {
if (window.require) {
const { ipcRenderer } = window.require('electron');
console.log(`[MainHeader] showWindow('${name}') called at ${Date.now()}`);
console.log(`[MainHeader] showSettingsWindow called at ${Date.now()}`);
ipcRenderer.send('cancel-hide-window', name);
ipcRenderer.send('cancel-hide-settings-window');
if (name === 'settings' && element) {
const rect = element.getBoundingClientRect();
ipcRenderer.send('show-window', {
name: 'settings',
bounds: {
x: rect.left,
y: rect.top,
width: rect.width,
height: rect.height
}
if (element) {
const { left, top, width, height } = element.getBoundingClientRect();
ipcRenderer.send('show-settings-window', {
x: left,
y: top,
width,
height,
});
} else {
ipcRenderer.send('show-window', name);
}
}
}
hideWindow(name) {
if (this.wasJustDragged) return;
hideSettingsWindow() {
if (window.require) {
console.log(`[MainHeader] hideWindow('${name}') called at ${Date.now()}`);
window.require('electron').ipcRenderer.send('hide-window', name);
console.log(`[MainHeader] hideSettingsWindow called at ${Date.now()}`);
window.require('electron').ipcRenderer.send('hide-settings-window');
}
}
cancelHideWindow(name) {
}
renderShortcut(accelerator) {
if (!accelerator) return html``;
@ -600,7 +395,7 @@ export class MainHeader extends LitElement {
render() {
return html`
<div class="header" @mousedown=${this.handleMouseDown}>
<div class="header">
<button
class="listen-button ${this.isSessionActive ? 'active' : ''}"
@click=${() => this.invoke(this.isSessionActive ? 'close-session' : 'toggle-feature', 'listen')}
@ -646,8 +441,8 @@ export class MainHeader extends LitElement {
<button
class="settings-button"
@mouseenter=${(e) => this.showWindow('settings', e.currentTarget)}
@mouseleave=${() => this.hideWindow('settings')}
@mouseenter=${(e) => this.showSettingsWindow(e.currentTarget)}
@mouseleave=${() => this.hideSettingsWindow()}
>
<div class="settings-icon">
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">

View File

@ -4,14 +4,13 @@ export class PermissionHeader extends LitElement {
static styles = css`
:host {
display: block;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
transition: opacity 0.25s ease-out;
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) {
@ -19,17 +18,6 @@ export class PermissionHeader 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;
@ -38,6 +26,7 @@ export class PermissionHeader extends LitElement {
}
.container {
-webkit-app-region: drag;
width: 285px;
height: 220px;
padding: 18px 20px;
@ -67,6 +56,7 @@ export class PermissionHeader extends LitElement {
}
.close-button {
-webkit-app-region: no-drag;
position: absolute;
top: 10px;
right: 10px;
@ -157,6 +147,7 @@ export class PermissionHeader extends LitElement {
}
.action-button {
-webkit-app-region: no-drag;
width: 100%;
height: 34px;
background: rgba(255, 255, 255, 0.2);
@ -198,6 +189,7 @@ export class PermissionHeader extends LitElement {
}
.continue-button {
-webkit-app-region: no-drag;
width: 100%;
height: 34px;
background: rgba(34, 197, 94, 0.8);
@ -237,30 +229,6 @@ export class PermissionHeader extends LitElement {
background: rgba(255, 255, 255, 0.2);
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 = {
@ -276,9 +244,6 @@ export class PermissionHeader extends LitElement {
this.screenGranted = 'unknown';
this.isChecking = false;
this.continueCallback = null;
this.handleMouseMove = this.handleMouseMove.bind(this);
this.handleMouseUp = this.handleMouseUp.bind(this);
}
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() {
if (!window.require || this.isChecking) return;
@ -390,7 +300,7 @@ export class PermissionHeader extends LitElement {
}
async handleMicrophoneClick() {
if (!window.require || this.microphoneGranted === 'granted' || this.wasJustDragged) return;
if (!window.require || this.microphoneGranted === 'granted') return;
console.log('[PermissionHeader] Requesting microphone permission...');
const { ipcRenderer } = window.require('electron');
@ -423,7 +333,7 @@ export class PermissionHeader extends LitElement {
}
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...');
const { ipcRenderer } = window.require('electron');
@ -453,8 +363,7 @@ export class PermissionHeader extends LitElement {
async handleContinue() {
if (this.continueCallback &&
this.microphoneGranted === 'granted' &&
this.screenGranted === 'granted' &&
!this.wasJustDragged) {
this.screenGranted === 'granted') {
// Mark permissions as completed
if (window.require) {
const { ipcRenderer } = window.require('electron');
@ -481,7 +390,7 @@ export class PermissionHeader extends LitElement {
const allGranted = this.microphoneGranted === 'granted' && this.screenGranted === 'granted';
return html`
<div class="container" @mousedown=${this.handleMouseDown}>
<div class="container">
<button class="close-button" @click=${this.handleClose} title="Close application">
<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" />

View File

@ -136,16 +136,6 @@ export class PickleGlassApp extends LitElement {
}
}
requestWindowResize() {
if (window.require) {
const { ipcRenderer } = window.require('electron');
ipcRenderer.invoke('resize-window', {
isMainViewVisible: this.isMainViewVisible,
view: this.currentView,
});
}
}
setStatus(text) {
this.statusText = text;
}

View File

@ -237,63 +237,62 @@
<script>
window.addEventListener('DOMContentLoaded', () => {
const app = document.getElementById('pickle-glass');
let animationTimeout = null;
if (window.require) {
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', () => {
console.log('Starting window show animation');
app.classList.remove('window-hidden', 'window-sliding-up', 'settings-window-hide');
app.classList.add('window-sliding-down');
if (animationTimeout) clearTimeout(animationTimeout);
animationTimeout = setTimeout(() => {
app.classList.remove('window-sliding-down');
}, 120);
});
ipcRenderer.on('window-hide-animation', () => {
console.log('Starting window hide animation');
app.classList.remove('window-sliding-down', 'settings-window-show');
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', () => {
console.log('Starting settings window hide animation');
app.classList.remove('window-sliding-down', 'settings-window-show');
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', () => {
console.log('Moving listen window to center');
app.classList.add('listen-window-moving');
app.classList.remove('listen-window-left');
app.classList.add('listen-window-center');
setTimeout(() => {
app.classList.remove('listen-window-moving');
}, 350);
});
ipcRenderer.on('listen-window-move-to-left', () => {
console.log('Moving listen window to left');
app.classList.add('listen-window-moving');
app.classList.remove('listen-window-center');
app.classList.add('listen-window-left');
setTimeout(() => {
app.classList.remove('listen-window-moving');
}, 350);
@ -305,6 +304,11 @@
const params = new URLSearchParams(window.location.search);
if (params.get('glass') === 'true') {
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>
</body>

View File

@ -22,6 +22,11 @@
const params = new URLSearchParams(window.location.search);
if (params.get('glass') === 'true') {
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>
</body>

View File

@ -213,13 +213,21 @@ class ModelStateService {
const llmModels = PROVIDERS['openai-glass']?.llmModels;
const sttModels = PROVIDERS['openai-glass']?.sttModels;
if (!this.state.selectedModels.llm && llmModels?.length > 0) {
// When logging in with Pickle, prioritize Pickle's models over existing selections
if (virtualKey && llmModels?.length > 0) {
this.state.selectedModels.llm = llmModels[0].id;
console.log(`[ModelStateService] Prioritized Pickle LLM model: ${llmModels[0].id}`);
}
if (!this.state.selectedModels.stt && sttModels?.length > 0) {
if (virtualKey && sttModels?.length > 0) {
this.state.selectedModels.stt = sttModels[0].id;
console.log(`[ModelStateService] Prioritized Pickle STT model: ${sttModels[0].id}`);
}
this._autoSelectAvailableModels();
// If logging out (virtualKey is null), run auto-selection to find alternatives
if (!virtualKey) {
this._autoSelectAvailableModels();
}
this._saveState();
this._logCurrentSelection();
}

View 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;
}

View File

@ -78,13 +78,6 @@ function updateLayout() {
let movementManager = null;
const featureWindows = ['listen','ask','settings'];
// const featureWindows = ['listen','ask','settings','shortcut-settings'];
function isAllowed(name) {
if (name === 'header') return true;
return featureWindows.includes(name) && currentHeaderState === 'main';
}
function createFeatureWindows(header, namesToCreate) {
// if (windowPool.has('listen')) return;
@ -305,6 +298,7 @@ function createFeatureWindows(header, namesToCreate) {
}
function destroyFeatureWindows() {
const featureWindows = ['listen','ask','settings','shortcut-settings'];
if (settingsHideTimer) {
clearTimeout(settingsHideTimer);
settingsHideTimer = null;
@ -337,78 +331,35 @@ function getDisplayById(displayId) {
function toggleAllWindowsVisibility(movementManager) {
function toggleAllWindowsVisibility() {
const header = windowPool.get('header');
if (!header) return;
if (header.isVisible()) {
console.log('[Visibility] Smart hiding - calculating nearest edge');
const headerBounds = header.getBounds();
const display = screen.getPrimaryDisplay();
const { width: screenWidth, height: screenHeight } = display.workAreaSize;
const centerX = headerBounds.x + headerBounds.width / 2;
const centerY = headerBounds.y + headerBounds.height / 2;
const distances = {
top: centerY,
bottom: screenHeight - centerY,
left: centerX,
right: screenWidth - centerX,
};
const nearestEdge = Object.keys(distances).reduce((nearest, edge) => (distances[edge] < distances[nearest] ? edge : nearest));
console.log(`[Visibility] Nearest edge: ${nearestEdge} (distance: ${distances[nearestEdge].toFixed(1)}px)`);
lastVisibleWindows.clear();
lastVisibleWindows.add('header');
windowPool.forEach((win, name) => {
if (win.isVisible()) {
lastVisibleWindows.add(name);
if (name !== 'header') {
// win.webContents.send('window-hide-animation');
// setTimeout(() => {
// if (!win.isDestroyed()) {
// win.hide();
// }
// }, 200);
win.hide();
}
}
});
console.log('[Visibility] Visible windows before hide:', Array.from(lastVisibleWindows));
movementManager.hideToEdge(nearestEdge, () => {
header.hide();
console.log('[Visibility] Smart hide completed');
}, { instant: true });
} else {
console.log('[Visibility] Smart showing from hidden position');
console.log('[Visibility] Restoring windows:', Array.from(lastVisibleWindows));
header.show();
movementManager.showFromEdge(() => {
lastVisibleWindows.forEach(name => {
if (name === 'header') return;
const win = windowPool.get(name);
if (win && !win.isDestroyed()) {
win.show();
win.webContents.send('window-show-animation');
}
});
setImmediate(updateLayout);
setTimeout(updateLayout, 120);
console.log('[Visibility] Smart show completed');
});
lastVisibleWindows.clear();
windowPool.forEach((win, name) => {
if (win && !win.isDestroyed() && win.isVisible()) {
lastVisibleWindows.add(name);
}
});
lastVisibleWindows.forEach(name => {
if (name === 'header') return;
const win = windowPool.get(name);
if (win && !win.isDestroyed()) win.hide();
});
header.hide();
return;
}
}
lastVisibleWindows.forEach(name => {
const win = windowPool.get(name);
if (win && !win.isDestroyed())
win.show();
});
}
function createWindows() {
@ -470,6 +421,7 @@ function createWindows() {
});
}
windowPool.set('header', header);
header.on('moved', updateLayout);
layoutManager = new WindowLayoutManager(windowPool);
header.webContents.once('dom-ready', () => {
@ -513,7 +465,7 @@ function createWindows() {
updateLayout();
});
ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility(movementManager));
ipcMain.handle('toggle-all-windows-visibility', () => toggleAllWindowsVisibility());
ipcMain.handle('toggle-feature', async (event, featureName) => {
if (!windowPool.get(featureName) && currentHeaderState === 'main') {
@ -596,13 +548,6 @@ function createWindows() {
} else {
console.log('[WindowManager] No response found, closing window');
askWindow.webContents.send('window-hide-animation');
setTimeout(() => {
if (!askWindow.isDestroyed()) {
askWindow.hide();
updateLayout();
}
}, 250);
}
} catch (error) {
console.error('[WindowManager] Error checking Ask window state:', error);
@ -631,13 +576,6 @@ function createWindows() {
} else {
windowToToggle.webContents.send('window-hide-animation');
}
setTimeout(() => {
if (!windowToToggle.isDestroyed()) {
windowToToggle.hide();
updateLayout();
}
}, 250);
} else {
try {
windowToToggle.show();
@ -773,9 +711,17 @@ function setupIpcHandlers(movementManager) {
}
});
ipcMain.on('show-window', (event, args) => {
const { name, bounds } = typeof args === 'object' && args !== null ? args : { name: args, bounds: null };
const win = windowPool.get(name);
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-settings-window', (event, bounds) => {
if (!bounds) return;
const win = windowPool.get('settings');
if (win && !win.isDestroyed()) {
if (settingsHideTimer) {
@ -783,78 +729,60 @@ function setupIpcHandlers(movementManager) {
settingsHideTimer = null;
}
if (name === 'settings') {
// Adjust position based on button bounds
const header = windowPool.get('header');
const headerBounds = header?.getBounds() ?? { x: 0, y: 0 };
const settingsBounds = win.getBounds();
// Adjust position based on button bounds
const header = windowPool.get('header');
const headerBounds = header?.getBounds() ?? { x: 0, y: 0 };
const settingsBounds = win.getBounds();
const disp = getCurrentDisplay(header);
const { x: waX, y: waY, width: waW, height: waH } = disp.workArea;
const disp = getCurrentDisplay(header);
const { x: waX, y: waY, width: waW, height: waH } = disp.workArea;
let x = Math.round(headerBounds.x + (bounds?.x ?? 0) + (bounds?.width ?? 0) / 2 - settingsBounds.width / 2);
let y = Math.round(headerBounds.y + (bounds?.y ?? 0) + (bounds?.height ?? 0) + 31);
let x = Math.round(headerBounds.x + (bounds?.x ?? 0) + (bounds?.width ?? 0) / 2 - settingsBounds.width / 2);
let y = Math.round(headerBounds.y + (bounds?.y ?? 0) + (bounds?.height ?? 0) + 31);
x = Math.max(waX + 10, Math.min(waX + waW - settingsBounds.width - 10, x));
y = Math.max(waY + 10, Math.min(waY + waH - settingsBounds.height - 10, y));
win.setBounds({ x, y });
win.__lockedByButton = true;
console.log(`[WindowManager] Positioning settings window at (${x}, ${y}) based on button bounds.`);
}
x = Math.max(waX + 10, Math.min(waX + waW - settingsBounds.width - 10, x));
y = Math.max(waY + 10, Math.min(waY + waH - settingsBounds.height - 10, y));
win.setBounds({ x, y });
win.__lockedByButton = true;
console.log(`[WindowManager] Positioning settings window at (${x}, ${y}) based on button bounds.`);
win.show();
win.moveTop();
if (name === 'settings') {
win.setAlwaysOnTop(true);
}
// updateLayout();
win.setAlwaysOnTop(true);
}
});
ipcMain.on('hide-window', (event, name) => {
const window = windowPool.get(name);
ipcMain.on('hide-settings-window', (event) => {
const window = windowPool.get("settings");
if (window && !window.isDestroyed()) {
if (name === 'settings') {
if (settingsHideTimer) {
clearTimeout(settingsHideTimer);
}
settingsHideTimer = setTimeout(() => {
// window.setAlwaysOnTop(false);
// window.hide();
if (window && !window.isDestroyed()) {
window.setAlwaysOnTop(false);
window.hide();
}
settingsHideTimer = null;
}, 200);
} else {
window.hide();
if (settingsHideTimer) {
clearTimeout(settingsHideTimer);
}
settingsHideTimer = setTimeout(() => {
if (window && !window.isDestroyed()) {
window.setAlwaysOnTop(false);
window.hide();
}
settingsHideTimer = null;
}, 200);
window.__lockedByButton = false;
}
});
ipcMain.on('cancel-hide-window', (event, name) => {
if (name === 'settings' && settingsHideTimer) {
ipcMain.on('cancel-hide-settings-window', (event) => {
if (settingsHideTimer) {
clearTimeout(settingsHideTimer);
settingsHideTimer = null;
}
});
ipcMain.handle('hide-all', () => {
windowPool.forEach(win => {
if (win.isFocused()) return;
win.hide();
});
});
ipcMain.handle('quit-application', () => {
app.quit();
});
ipcMain.handle('is-window-visible', (event, windowName) => {
ipcMain.handle('is-ask-window-visible', (event, windowName) => {
const window = windowPool.get(windowName);
if (window && !window.isDestroyed()) {
return window.isVisible();
@ -888,15 +816,6 @@ function setupIpcHandlers(movementManager) {
destroyFeatureWindows();
}
loadAndRegisterShortcuts(movementManager);
for (const [name, win] of windowPool) {
if (!isAllowed(name) && !win.isDestroyed()) {
win.hide();
}
if (isAllowed(name) && win.isVisible()) {
win.show();
}
}
});
ipcMain.on('update-keybinds', (event, newKeybinds) => {
@ -969,9 +888,6 @@ function setupIpcHandlers(movementManager) {
setupApiKeyIPC();
ipcMain.handle('resize-window', () => {});
ipcMain.handle('resize-for-view', () => {});
ipcMain.handle('resize-header-window', (event, { width, height }) => {
const header = windowPool.get('header');
@ -1024,74 +940,19 @@ function setupIpcHandlers(movementManager) {
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');
if (!header) return;
if (!header || header.isDestroyed()) return;
if (state === 'hidden') {
header.hide();
console.log('[WindowManager] Header hidden after animation.');
} else if (state === 'visible') {
lastVisibleWindows.forEach(name => {
if (name === 'header') return;
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);
console.log('[WindowManager] Header shown after animation.');
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) => {
if (movementManager) {
@ -1105,13 +966,6 @@ function setupIpcHandlers(movementManager) {
console.log(`[WindowManager] Force closing window: ${windowName}`);
window.webContents.send('window-hide-animation');
setTimeout(() => {
if (!window.isDestroyed()) {
window.hide();
updateLayout();
}
}, 250);
}
});
@ -1405,7 +1259,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan
if (state === 'apikey') {
if (keybinds.toggleVisibility) {
try {
globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility(movementManager));
globalShortcut.register(keybinds.toggleVisibility, () => toggleAllWindowsVisibility());
} catch (error) {
console.error(`Failed to register toggleVisibility (${keybinds.toggleVisibility}):`, error);
}
@ -1441,7 +1295,7 @@ function updateGlobalShortcuts(keybinds, mainWindow, sendToRenderer, movementMan
let callback;
switch(action) {
case 'toggleVisibility':
callback = () => toggleAllWindowsVisibility(movementManager);
callback = () => toggleAllWindowsVisibility();
break;
case 'nextStep':
callback = () => {
@ -1611,9 +1465,6 @@ module.exports = {
createWindows,
windowPool,
fixedYPosition,
//////// before_modelStateService ////////
// setApiKey,
//////// before_modelStateService ////////
getStoredApiKey,
getStoredProvider,
getCurrentModelInfo,

View File

@ -41,56 +41,6 @@ export class AskView 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);
}
}
* {
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;
}
@keyframes fadeInOut {
0% {
opacity: 1;
transform: translateY(0);
}
50% {
opacity: 0;
transform: translateY(-10px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.header-right {
display: flex;
@ -422,19 +358,6 @@ export class AskView extends LitElement {
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 {
position: relative;
padding: 2px 0;
@ -596,42 +519,6 @@ export class AskView extends LitElement {
color: rgba(255, 255, 255, 0.5);
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() {

View File

@ -27,56 +27,6 @@ export class AssistantView 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);
}
}
* {
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;
}
@keyframes slideIn {
from {
transform: translateX(10%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.bar-controls {
display: flex;
gap: 4px;
@ -349,134 +288,6 @@ export class AssistantView extends LitElement {
font-size: 10px;
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 = {

View File

@ -412,7 +412,7 @@ export class SummaryView extends LitElement {
const { ipcRenderer } = window.require('electron');
try {
const isAskViewVisible = await ipcRenderer.invoke('is-window-visible', 'ask');
const isAskViewVisible = await ipcRenderer.invoke('is-ask-window-visible', 'ask');
if (!isAskViewVisible) {
await ipcRenderer.invoke('toggle-feature', 'ask');

View File

@ -367,11 +367,6 @@ export class SettingsView extends LitElement {
margin-right: 6px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.hidden {
display: none;
}
@ -1030,14 +1025,14 @@ export class SettingsView extends LitElement {
handleMouseEnter = () => {
if (window.require) {
const { ipcRenderer } = window.require('electron');
ipcRenderer.send('cancel-hide-window', 'settings');
ipcRenderer.send('cancel-hide-settings-window');
}
}
handleMouseLeave = () => {
if (window.require) {
const { ipcRenderer } = window.require('electron');
ipcRenderer.send('hide-window', 'settings');
ipcRenderer.send('hide-settings-window');
}
}