Merge pull request #60 from cjpais/overlay-cancel
add cancel to overlay
This commit is contained in:
commit
200d1bdfc2
3 changed files with 101 additions and 33 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue