diff --git a/src/components/launch/LaunchWindow.tsx b/src/components/launch/LaunchWindow.tsx
index 963e07f..f82ae6c 100644
--- a/src/components/launch/LaunchWindow.tsx
+++ b/src/components/launch/LaunchWindow.tsx
@@ -8,6 +8,7 @@ import { MdMonitor } from "react-icons/md";
import { RxDragHandleDots2 } from "react-icons/rx";
import { FaFolderMinus } from "react-icons/fa6";
import { FiMinus, FiX } from "react-icons/fi";
+import { ContentClamp } from "../ui/content-clamp";
export function LaunchWindow() {
const { recording, toggleRecording } = useScreenRecorder();
@@ -61,11 +62,6 @@ export function LaunchWindow() {
return () => clearInterval(interval);
}, []);
- const truncateText = (text: string, maxLength: number = 6) => {
- if (text.length <= maxLength) return text;
- return text.substring(0, maxLength) + "...";
- };
-
const openSourceSelector = () => {
if (window.electronAPI) {
window.electronAPI.openSourceSelector();
@@ -121,7 +117,7 @@ export function LaunchWindow() {
disabled={recording}
>
- {truncateText(selectedSource, 6)}
+ {selectedSource}
@@ -131,7 +127,7 @@ export function LaunchWindow() {
size="sm"
onClick={hasSelectedSource ? toggleRecording : openSourceSelector}
disabled={!hasSelectedSource && !recording}
- className={`gap-1 bg-transparent hover:bg-transparent px-0 flex-1 text-center text-xs ${styles.electronNoDrag}`}
+ className={`gap-1 text-white bg-transparent hover:bg-transparent px-0 flex-1 text-center text-xs ${styles.electronNoDrag}`}
>
{recording ? (
<>
diff --git a/src/components/ui/content-clamp.tsx b/src/components/ui/content-clamp.tsx
new file mode 100644
index 0000000..1597f1b
--- /dev/null
+++ b/src/components/ui/content-clamp.tsx
@@ -0,0 +1,86 @@
+"use client"
+
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+import { Popover, PopoverArrow, PopoverContent, PopoverTrigger } from "./popover"
+
+interface ContentClampProps extends React.HTMLAttributes {
+ children: React.ReactNode
+ truncateLength?: number
+}
+
+function ContentClamp({
+ children,
+ className,
+ truncateLength = 50,
+ ...props
+}: ContentClampProps) {
+ const text = typeof children === "string" ? children : String(children ?? "")
+ const isTruncated = text.length > truncateLength
+
+ const [open, setOpen] = React.useState(false)
+ const timeoutRef = React.useRef(null)
+
+ const handleMouseEnter = () => {
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current)
+ timeoutRef.current = null
+ }
+ setOpen(true)
+ }
+
+ const handleMouseLeave = () => {
+ timeoutRef.current = setTimeout(() => {
+ setOpen(false)
+ }, 100)
+ }
+
+ React.useEffect(() => {
+ return () => {
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current)
+ }
+ }
+ }, [])
+
+ if (!isTruncated) {
+ return (
+
+ {children}
+
+ )
+ }
+
+ const truncatedText = text.slice(0, truncateLength) + "..."
+
+ return (
+
+
+ e.preventDefault()}
+ {...props}
+ >
+ {truncatedText}
+
+
+ e.preventDefault()}
+ onClick={(e) => e.stopPropagation()}
+ >
+
+ {children}
+
+
+ )
+}
+
+export { ContentClamp }
diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx
index 01e468b..2f36cd6 100644
--- a/src/components/ui/popover.tsx
+++ b/src/components/ui/popover.tsx
@@ -21,8 +21,11 @@ function PopoverContent({
className,
align = "center",
sideOffset = 4,
+ animated = true,
...props
-}: React.ComponentProps) {
+}: React.ComponentProps & {
+ animated?: boolean
+}) {
return (
}
-export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
+function PopoverArrow({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverArrow }