Files
RadioPlayer/layout2_plan.md
2025-12-30 15:12:26 +01:00

5.5 KiB
Raw Permalink Blame History

Beautify “Connect to Device” Popup (Tauri + HTML)

Goal

Redesign the Connect to Device popup/modal to match the apps glassmorphism + neon purple style:

  • Frosted glass modal
  • Blurred/dimmed overlay background
  • Clean device list with hover + selected states
  • Premium rounded corners and soft glow
  • Works smoothly inside Tauri WebView (desktop)

Requirements

Functional

  • Modal opens/closes via existing app logic (do not change behavior).

  • Device list supports:

    • Hover highlight
    • Single selected device (one at a time)
    • Click selects device (and triggers existing handler)
  • “Cancel” button closes modal (existing handler).

  • Include “This Computer (Local Playback)” option at top.

Visual

  • Overlay blur + dark tint behind modal.
  • Modal background: semi-transparent glass with blur.
  • No harsh borders; use subtle border + soft shadow.
  • Selected device: gradient accent + glow.
  • Smooth animation on open (scale + fade).
  • Desktop-friendly sizing (320420px wide).

Tauri Safety / Performance

  • Keep CSS lightweight.
  • Avoid heavy SVG masks or expensive filters beyond backdrop-filter: blur(...).
  • Ensure modal area is -webkit-app-region: no-drag if you use draggable window headers.

Target Structure

HTML (keep semantic + simple)

Use or adapt this structure in the renderer HTML:

<div id="deviceOverlay" class="overlay hidden" aria-hidden="true">
  <div class="modal" role="dialog" aria-modal="true" aria-labelledby="deviceTitle">
    <h2 id="deviceTitle">Connect to Device</h2>

    <ul id="deviceList" class="device-list">
      <!-- Render device items here -->
      <!-- Example item:
      <li class="device local selected" data-device="local">
        <div class="device-main">This Computer</div>
        <div class="device-sub">Local Playback</div>
      </li>
      -->
    </ul>

    <button id="deviceCancelBtn" class="btn cancel" type="button">Cancel</button>
  </div>
</div>

Notes:

  • Use hidden class to toggle visibility.
  • Each <li> must have data-device="<name-or-id>" for click handling.
  • Selected item uses .selected.

CSS (Glassmorphism Modal)

Add/merge this CSS into your stylesheet:

/* Overlay */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 10, 35, 0.45);
  backdrop-filter: blur(14px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.hidden { display: none !important; }

/* Modal */
.modal {
  width: min(420px, calc(100vw - 48px));
  padding: 22px;
  border-radius: 22px;
  background: rgba(30, 30, 40, 0.82);
  border: 1px solid rgba(255,255,255,0.12);
  box-shadow: 0 30px 80px rgba(0,0,0,0.6);
  color: #fff;
  animation: pop 0.22s ease;
  -webkit-app-region: no-drag;
}

@keyframes pop {
  from { transform: scale(0.94); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.modal h2 {
  margin: 0 0 14px;
  text-align: center;
  font-size: 20px;
}

/* Device list */
.device-list {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  max-height: 360px;
  overflow: auto;
}

/* Device row */
.device {
  padding: 12px 14px;
  border-radius: 14px;
  margin-bottom: 8px;
  cursor: pointer;
  background: rgba(255,255,255,0.05);
  transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.device:hover {
  background: rgba(255,255,255,0.10);
  transform: translateY(-1px);
}

.device .device-main {
  font-size: 15px;
}

.device .device-sub {
  margin-top: 3px;
  font-size: 12px;
  opacity: 0.7;
}

/* Selected device */
.device.selected {
  background: linear-gradient(135deg, #c77dff, #8b5cf6);
  box-shadow: 0 0 18px rgba(199,125,255,0.65);
  color: #111;
}

.device.selected .device-sub {
  opacity: 0.85;
}

/* Optional: disabled group devices */
.device.disabled {
  opacity: 0.45;
  pointer-events: none;
}

/* Cancel button */
.btn.cancel {
  width: 100%;
  padding: 12px;
  border-radius: 999px;
  border: none;
  background: #d16b7d;
  color: #fff;
  font-size: 15px;
  cursor: pointer;
  transition: transform 0.15s ease;
}

.btn.cancel:hover {
  transform: scale(1.02);
}

JavaScript Behavior (Minimal)

Selection logic

  • When a device row is clicked:

    1. Remove .selected from all device <li>
    2. Add .selected to clicked <li>
    3. Call existing “connect/cast to device” handler with data-device

Pseudo-code (adapt to existing app code):

deviceList.addEventListener("click", (e) => {
  const item = e.target.closest(".device");
  if (!item) return;

  deviceList.querySelectorAll(".device.selected")
    .forEach(el => el.classList.remove("selected"));

  item.classList.add("selected");

  const deviceName = item.dataset.device;
  // call existing connect logic:
  // connectToDevice(deviceName);
});

Close modal

  • Cancel button closes modal (existing function):
deviceCancelBtn.addEventListener("click", closeDeviceModal);

Optional: close on overlay click

  • Only if app UX allows:
deviceOverlay.addEventListener("click", (e) => {
  if (e.target === deviceOverlay) closeDeviceModal();
});

Acceptance Criteria

  • Popup visually matches glassmorphism theme.
  • Overlay dims and blurs background.
  • Device list has hover + selected glow.
  • Exactly one device can be selected.
  • Cancel closes modal.
  • Runs smoothly in Tauri WebView without lag.

Notes / Future Enhancements (Optional)

  • Mark “Speaker Groups” as .disabled if casting library cant support them.
  • Add small icons per device type (local vs cast).
  • Remember last selected device and preselect it on open.