mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-21 21:31:12 +02:00
fix(x): meeting popup window is the card — kills the grey backing slab
macOS NSPanel windows don't honor transparent: true (nor a #00000000 backgroundColor); the transparent margins around the card rendered as an opaque grey slab. Drop transparency entirely: size the window to the card (376×48), paint the card color on the window, use native rounded corners + shadow. The hover × slides in over the card's left edge instead of overhanging a corner.
This commit is contained in:
parent
9ee332e21b
commit
786382c840
2 changed files with 32 additions and 31 deletions
|
|
@ -13,9 +13,11 @@ import type { DetectedMeeting } from "@x/core/dist/meetings/detector.js";
|
|||
* window's existing take-meeting-notes flow.
|
||||
*/
|
||||
|
||||
// Lean bar + margins for the overhanging × and the CSS drop shadow.
|
||||
const POPUP_WIDTH = 400;
|
||||
const POPUP_HEIGHT = 76;
|
||||
// The window IS the card: exact card dimensions, card background, native
|
||||
// rounded corners + shadow. No transparency — macOS panels don't honor
|
||||
// `transparent: true` reliably and paint a grey backing slab instead.
|
||||
const POPUP_WIDTH = 376;
|
||||
const POPUP_HEIGHT = 48;
|
||||
const AUTO_DISMISS_MS = 45_000;
|
||||
|
||||
// Display names, Granola-style ("Chrome", not "Google Chrome").
|
||||
|
|
@ -109,10 +111,8 @@ export function showMeetingPopup(meeting: DetectedMeeting): void {
|
|||
alwaysOnTop: true,
|
||||
skipTaskbar: true,
|
||||
show: false,
|
||||
// Transparent window: the rounded card + overhanging × render inside;
|
||||
// the shadow is CSS (native shadows artifact on transparent windows).
|
||||
transparent: true,
|
||||
hasShadow: false,
|
||||
backgroundColor: "#1d1d1d",
|
||||
hasShadow: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
|
|
|
|||
|
|
@ -58,43 +58,44 @@ export function MeetingDetectedPopup() {
|
|||
void window.ipc.invoke('meetingDetect:action', { action }).catch(() => {})
|
||||
}
|
||||
|
||||
// In the browser preview, reproduce the real popup window's exact size
|
||||
// (448×96) on a desktop-ish backdrop; in Electron the window IS that size.
|
||||
// The Electron window IS the card (376×48, card background, native macOS
|
||||
// rounded corners + shadow — no transparency, which panels don't honor).
|
||||
// The preview emulates that frame with its own rounding/shadow.
|
||||
// No drag region: draggable areas swallow mouse events, which would keep
|
||||
// the hover-revealed × from ever showing while over the card body.
|
||||
const popup = (
|
||||
<div
|
||||
className={`group ${isPreview ? 'relative' : 'h-screen w-screen relative bg-transparent'}`}
|
||||
style={isPreview ? { width: 400, height: 76 } : undefined}
|
||||
className={`group relative flex items-center gap-3 pl-4 pr-2 bg-[#1d1d1d] overflow-hidden ${
|
||||
isPreview ? 'rounded-xl shadow-[0_8px_28px_rgba(0,0,0,0.45)]' : 'h-screen w-screen'
|
||||
}`}
|
||||
style={isPreview ? { width: 376, height: 48 } : undefined}
|
||||
>
|
||||
{/* Close — floats over the card's top-left corner, revealed on hover */}
|
||||
{/* Close — slides in over the left edge on hover */}
|
||||
<button
|
||||
onClick={() => act('dismiss')}
|
||||
className="absolute left-0.5 top-0.5 z-10 flex size-6 items-center justify-center rounded-full bg-neutral-800 border border-neutral-600 text-neutral-200 shadow-md hover:bg-neutral-700 opacity-0 group-hover:opacity-100 transition-opacity" aria-label="Dismiss"
|
||||
className="absolute left-1.5 top-1/2 -translate-y-1/2 z-10 flex size-6 items-center justify-center rounded-full bg-neutral-800 border border-neutral-600 text-neutral-200 shadow-md hover:bg-neutral-700 opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<X className="size-3.5" strokeWidth={2.5} />
|
||||
</button>
|
||||
|
||||
{/* Card */}
|
||||
<div className="absolute left-3 right-3 top-3 h-12 rounded-2xl bg-[#1d1d1d] shadow-[0_8px_28px_rgba(0,0,0,0.55)] flex items-center gap-3 pl-4 pr-2">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-sm font-semibold text-white leading-tight truncate">
|
||||
{payload?.title ?? 'Meeting detected'}
|
||||
</div>
|
||||
<div className="text-[13px] text-neutral-400 leading-tight truncate mt-0.5">
|
||||
{payload?.message ?? ''}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0 transition-[padding] group-hover:pl-6">
|
||||
<div className="text-sm font-semibold text-white leading-tight truncate">
|
||||
{payload?.title ?? 'Meeting detected'}
|
||||
</div>
|
||||
<div className="text-[13px] text-neutral-400 leading-tight truncate mt-0.5">
|
||||
{payload?.message ?? ''}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => act('take-notes')}
|
||||
className="flex h-8.5 shrink-0 items-center gap-1.5 rounded-lg bg-neutral-800/90 border border-neutral-700 pl-1.5 pr-2.5 hover:bg-neutral-700 transition-colors"
|
||||
>
|
||||
<span className="flex size-6 items-center justify-center">
|
||||
<img src={SAIL_ICON} alt="" className="size-4.5 invert" />
|
||||
</span>
|
||||
<span className="text-[13px] font-semibold text-white">Take notes</span>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => act('take-notes')}
|
||||
className="flex h-8.5 shrink-0 items-center gap-1.5 rounded-lg bg-neutral-800/90 border border-neutral-700 pl-1.5 pr-2.5 hover:bg-neutral-700 transition-colors"
|
||||
>
|
||||
<span className="flex size-6 items-center justify-center">
|
||||
<img src={SAIL_ICON} alt="" className="size-4.5 invert" />
|
||||
</span>
|
||||
<span className="text-[13px] font-semibold text-white">Take notes</span>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue