Merge pull request #60 from cjpais/overlay-cancel

add cancel to overlay
This commit is contained in:
CJ Pais 2025-08-01 16:04:08 -07:00 committed by GitHub
commit 200d1bdfc2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 101 additions and 33 deletions

View file

@ -326,7 +326,7 @@ pub fn create_recording_overlay(app_handle: &AppHandle) {
let screen_height = (size.height as f64 / scale) as i32; let screen_height = (size.height as f64 / scale) as i32;
// Position at bottom center, 30px from bottom // Position at bottom center, 30px from bottom
let x = (screen_width - 150) / 2; let x = (screen_width - 160) / 2;
let y = screen_height - 30 - 30; let y = screen_height - 30 - 30;
match WebviewWindowBuilder::new( match WebviewWindowBuilder::new(
@ -340,6 +340,7 @@ pub fn create_recording_overlay(app_handle: &AppHandle) {
.maximizable(false) .maximizable(false)
.minimizable(false) .minimizable(false)
.closable(false) .closable(false)
.accept_first_mouse(true)
.decorations(false) .decorations(false)
.always_on_top(true) .always_on_top(true)
.skip_taskbar(true) .skip_taskbar(true)

View file

@ -1,18 +1,34 @@
.recording-overlay { .recording-overlay {
height: 40px; height: 40px;
/*width: min-content;*/ width: 160px;
width: 120px; display: grid;
display: flex; grid-template-columns: auto 1fr auto;
gap: 12px;
align-items: center; align-items: center;
padding-left: 6px; padding-left: 6px;
padding-right: 24px; padding-right: 6px;
background: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.6);
border-radius: 24px; border-radius: 24px;
opacity: 0; opacity: 0;
transition: opacity 300ms ease-out; transition: opacity 300ms ease-out;
} }
.overlay-left {
display: flex;
align-items: center;
}
.overlay-middle {
display: flex;
align-items: center;
justify-content: center;
}
.overlay-right {
display: flex;
align-items: center;
justify-content: flex-end;
}
.bars-container { .bars-container {
display: flex; display: flex;
align-items: end; align-items: end;
@ -37,7 +53,7 @@
.transcribing-text { .transcribing-text {
color: #faa2ca; color: #faa2ca;
font-size: 12px; font-size: 14px;
font-weight: 600; font-weight: 600;
font-family: font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
@ -53,3 +69,27 @@
opacity: 1; opacity: 1;
} }
} }
.cancel-button {
width: 28px;
height: 28px;
border-radius: 50%;
background: #e53e3e;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition:
background-color 150ms ease-out,
transform 100ms ease-out;
flex-shrink: 0;
}
.cancel-button:hover {
background: #c53030;
transform: scale(1.05);
}
.cancel-button:active {
transform: scale(0.95);
}

View file

@ -1,6 +1,7 @@
import React, { useEffect, useState, useRef } from "react"; import React, { useEffect, useState, useRef } from "react";
import "./RecordingOverlay.css"; import "./RecordingOverlay.css";
import { listen } from "@tauri-apps/api/event"; import { listen } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/core";
type OverlayState = "recording" | "transcribing"; type OverlayState = "recording" | "transcribing";
@ -36,7 +37,7 @@ const RecordingOverlay: React.FC = () => {
smoothedLevelsRef.current = smoothed; smoothedLevelsRef.current = smoothed;
console.log(smoothed.length); console.log(smoothed.length);
setLevels(smoothed.slice(0, 10)); setLevels(smoothed.slice(0, 9));
}); });
// Cleanup function // Cleanup function
@ -62,31 +63,57 @@ const RecordingOverlay: React.FC = () => {
return ( return (
<div className={`recording-overlay ${isVisible ? "fade-in" : ""}`}> <div className={`recording-overlay ${isVisible ? "fade-in" : ""}`}>
<img <div className="overlay-left">
width="28" <img
height="28" width="28"
src={getIconPath()} height="28"
alt={getIconAlt()} src={getIconPath()}
style={{}} alt={getIconAlt()}
/> style={{}}
{state === "recording" && ( />
<div className="bars-container"> </div>
{levels.map((v, i) => (
<div <div className="overlay-middle">
key={i} {state === "recording" && (
className="bar" <div className="bars-container">
style={{ {levels.map((v, i) => (
height: `${4 + Math.pow(v, 0.7) * 32}px`, // Slight curve for better visual <div
transition: "height 60ms ease-out", key={i}
opacity: Math.max(0.4, v * 1.7), // Minimum opacity for visibility className="bar"
}} style={{
/> height: `${4 + Math.pow(v, 0.7) * 32}px`, // Slight curve for better visual
))} transition: "height 60ms ease-out",
</div> opacity: Math.max(0.4, v * 1.7), // Minimum opacity for visibility
)} }}
{state === "transcribing" && ( />
<div className="transcribing-text">Transcribing...</div> ))}
)} </div>
)}
{state === "transcribing" && (
<div className="transcribing-text">Transcribing...</div>
)}
</div>
<div className="overlay-right">
{state === "recording" && (
<div
className="cancel-button"
onClick={() => {
invoke("cancel_operation");
}}
>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none">
<path
d="M9 3L3 9M3 3L9 9"
stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</div>
)}
</div>
</div> </div>
); );
}; };