From a10cc77dfb1943d4557669bf32d8df040224cbb0 Mon Sep 17 00:00:00 2001 From: sanio Date: Fri, 11 Jul 2025 17:30:54 +0900 Subject: [PATCH] liquid glass ui beta --- src/app/ApiKeyHeader.js | 27 +++- src/app/MainHeader.js | 52 ++++++- src/app/PermissionHeader.js | 27 +++- src/app/content.html | 5 - src/app/header.html | 5 - src/electron/windowManager.js | 40 ++---- src/features/ask/AskView.js | 36 +++++ src/features/listen/AssistantView.js | 128 ++++++++++++++++++ src/features/settings/ShortCutSettingsView.js | 22 ++- 9 files changed, 292 insertions(+), 50 deletions(-) diff --git a/src/app/ApiKeyHeader.js b/src/app/ApiKeyHeader.js index 8b6a12b..1f0b938 100644 --- a/src/app/ApiKeyHeader.js +++ b/src/app/ApiKeyHeader.js @@ -78,7 +78,6 @@ export class ApiKeyHeader extends LitElement { } .close-button { - -webkit-app-region: no-drag; position: absolute; top: 10px; right: 10px; @@ -158,7 +157,6 @@ export class ApiKeyHeader extends LitElement { } .api-input { - -webkit-app-region: no-drag; width: 100%; height: 34px; background: rgba(255, 255, 255, 0.1); @@ -186,7 +184,6 @@ 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; @@ -213,7 +210,6 @@ export class ApiKeyHeader extends LitElement { .action-button { - -webkit-app-region: no-drag; width: 100%; height: 34px; background: rgba(255, 255, 255, 0.2); @@ -259,6 +255,29 @@ 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() { diff --git a/src/app/MainHeader.js b/src/app/MainHeader.js index 24b2d3d..4fe49f6 100644 --- a/src/app/MainHeader.js +++ b/src/app/MainHeader.js @@ -82,7 +82,6 @@ export class MainHeader extends LitElement { } .listen-button { - -webkit-app-region: no-drag; height: 26px; padding: 0 13px; background: transparent; @@ -190,7 +189,6 @@ export class MainHeader extends LitElement { } .header-actions { - -webkit-app-region: no-drag; height: 26px; box-sizing: border-box; justify-content: flex-start; @@ -262,7 +260,6 @@ export class MainHeader extends LitElement { } .settings-button { - -webkit-app-region: no-drag; padding: 5px; border-radius: 50%; background: transparent; @@ -290,6 +287,55 @@ 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() { diff --git a/src/app/PermissionHeader.js b/src/app/PermissionHeader.js index 15d86d2..ad24999 100644 --- a/src/app/PermissionHeader.js +++ b/src/app/PermissionHeader.js @@ -56,7 +56,6 @@ export class PermissionHeader extends LitElement { } .close-button { - -webkit-app-region: no-drag; position: absolute; top: 10px; right: 10px; @@ -147,7 +146,6 @@ export class PermissionHeader extends LitElement { } .action-button { - -webkit-app-region: no-drag; width: 100%; height: 34px; background: rgba(255, 255, 255, 0.2); @@ -189,7 +187,6 @@ export class PermissionHeader extends LitElement { } .continue-button { - -webkit-app-region: no-drag; width: 100%; height: 34px; background: rgba(34, 197, 94, 0.8); @@ -229,6 +226,30 @@ 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 = { diff --git a/src/app/content.html b/src/app/content.html index fa88046..9615f39 100644 --- a/src/app/content.html +++ b/src/app/content.html @@ -304,11 +304,6 @@ 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); } diff --git a/src/app/header.html b/src/app/header.html index 341b84b..46ea2d7 100644 --- a/src/app/header.html +++ b/src/app/header.html @@ -22,11 +22,6 @@ 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); } diff --git a/src/electron/windowManager.js b/src/electron/windowManager.js index a0384fb..e8a11c0 100644 --- a/src/electron/windowManager.js +++ b/src/electron/windowManager.js @@ -37,7 +37,7 @@ const isLiquidGlassSupported = () => { } const majorVersion = parseInt(os.release().split('.')[0], 10); // return majorVersion >= 25; // macOS 26+ (Darwin 25+) - return majorVersion >= 26; // See you soon! + return majorVersion >= 25; // See you soon! }; let shouldUseLiquidGlass = isLiquidGlassSupported(); if (shouldUseLiquidGlass) { @@ -116,13 +116,9 @@ function createFeatureWindows(header, namesToCreate) { listenLoadOptions.query.glass = 'true'; listen.loadFile(path.join(__dirname, '../app/content.html'), listenLoadOptions); listen.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(listen.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); + const viewId = liquidGlass.addView(listen.getNativeWindowHandle()); if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); + liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles); // liquidGlass.unstable_setScrim(viewId, 1); // liquidGlass.unstable_setSubdued(viewId, 1); } @@ -148,13 +144,9 @@ function createFeatureWindows(header, namesToCreate) { askLoadOptions.query.glass = 'true'; ask.loadFile(path.join(__dirname, '../app/content.html'), askLoadOptions); ask.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(ask.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); + const viewId = liquidGlass.addView(ask.getNativeWindowHandle()); if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); + liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles); // liquidGlass.unstable_setScrim(viewId, 1); // liquidGlass.unstable_setSubdued(viewId, 1); } @@ -189,13 +181,9 @@ function createFeatureWindows(header, namesToCreate) { settings.loadFile(path.join(__dirname,'../app/content.html'), settingsLoadOptions) .catch(console.error); settings.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(settings.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); + const viewId = liquidGlass.addView(settings.getNativeWindowHandle()); if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); + liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles); // liquidGlass.unstable_setScrim(viewId, 1); // liquidGlass.unstable_setSubdued(viewId, 1); } @@ -254,11 +242,9 @@ function createFeatureWindows(header, namesToCreate) { loadOptions.query.glass = 'true'; shortcutEditor.loadFile(path.join(__dirname, '../app/content.html'), loadOptions); shortcutEditor.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(shortcutEditor.getNativeWindowHandle(), { - cornerRadius: 12, tintColor: '#FF00001A', opaque: false, - }); + const viewId = liquidGlass.addView(shortcutEditor.getNativeWindowHandle()); if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); + liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles); } }); } @@ -408,13 +394,9 @@ function createWindows() { headerLoadOptions.query = { glass: 'true' }; header.loadFile(path.join(__dirname, '../app/header.html'), headerLoadOptions); header.webContents.once('did-finish-load', () => { - const viewId = liquidGlass.addView(header.getNativeWindowHandle(), { - cornerRadius: 12, - tintColor: '#FF00001A', // Red tint - opaque: false, - }); + const viewId = liquidGlass.addView(header.getNativeWindowHandle()); if (viewId !== -1) { - liquidGlass.unstable_setVariant(viewId, 2); + liquidGlass.unstable_setVariant(viewId, liquidGlass.GlassMaterialVariant.bubbles); // liquidGlass.unstable_setScrim(viewId, 1); // liquidGlass.unstable_setSubdued(viewId, 1); } diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index b871d3a..f2c81d7 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -519,6 +519,42 @@ 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() { diff --git a/src/features/listen/AssistantView.js b/src/features/listen/AssistantView.js index e47523e..c6d7861 100644 --- a/src/features/listen/AssistantView.js +++ b/src/features/listen/AssistantView.js @@ -288,6 +288,134 @@ 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 = { diff --git a/src/features/settings/ShortCutSettingsView.js b/src/features/settings/ShortCutSettingsView.js index aac45e4..404e446 100644 --- a/src/features/settings/ShortCutSettingsView.js +++ b/src/features/settings/ShortCutSettingsView.js @@ -66,7 +66,27 @@ export class ShortcutSettingsView extends LitElement { .settings-button.primary:hover{background:rgba(0,122,255,.35);} .settings-button.danger{background:rgba(255,59,48,.1);border-color:rgba(255,59,48,.3); color:rgba(255,59,48,.9);} - .settings-button.danger:hover{background:rgba(255,59,48,.15);} + .settings-button.danger:hover{background:rgba(255,59,48,.15); + } + + /* ────────────────[ 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; + } `; static properties = {