record/ select your own video
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
.electronDrag {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.electronNoDrag {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.folderButton {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.folderButton:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import { Button } from "../ui/button";
|
||||
import { BsRecordCircle } from "react-icons/bs";
|
||||
import { FaRegStopCircle } from "react-icons/fa";
|
||||
import { MdMonitor } from "react-icons/md";
|
||||
import { RxDragHandleDots2 } from "react-icons/rx";
|
||||
import { FaFolderMinus } from "react-icons/fa6";
|
||||
|
||||
export function LaunchWindow() {
|
||||
const { recording, toggleRecording } = useScreenRecorder();
|
||||
@@ -42,10 +44,23 @@ export function LaunchWindow() {
|
||||
}
|
||||
};
|
||||
|
||||
const openVideoFile = async () => {
|
||||
const result = await window.electronAPI.openVideoFilePicker();
|
||||
|
||||
if (result.cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.success && result.path) {
|
||||
await window.electronAPI.setCurrentVideoPath(result.path);
|
||||
await window.electronAPI.switchToEditor();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex items-center bg-transparent">
|
||||
<div
|
||||
className={`w-full max-w-2xl mx-auto flex items-center justify-between px-3 py-1.5 ${styles.electronDrag}`}
|
||||
className={`w-full max-w-3xl mx-auto flex items-center justify-between px-3 py-1.5 ${styles.electronDrag}`}
|
||||
style={{
|
||||
borderRadius: 14,
|
||||
background: 'linear-gradient(135deg, rgba(30,30,40,0.85) 0%, rgba(20,20,30,0.75) 100%)',
|
||||
@@ -56,6 +71,10 @@ export function LaunchWindow() {
|
||||
minHeight: 36,
|
||||
}}
|
||||
>
|
||||
<div className={`flex items-center gap-1 ${styles.electronDrag}`}>
|
||||
<RxDragHandleDots2 size={16} className="text-white/40" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
@@ -63,7 +82,7 @@ export function LaunchWindow() {
|
||||
onClick={openSourceSelector}
|
||||
>
|
||||
<MdMonitor size={13} className="text-white" />
|
||||
{truncateText(selectedSource)}
|
||||
{truncateText(selectedSource, 6)}
|
||||
</Button>
|
||||
|
||||
<div className="w-px h-5 bg-white/30" />
|
||||
@@ -73,7 +92,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-right text-xs ${styles.electronNoDrag}`}
|
||||
className={`gap-1 bg-transparent hover:bg-transparent px-0 flex-1 text-center text-xs ${styles.electronNoDrag}`}
|
||||
>
|
||||
{recording ? (
|
||||
<>
|
||||
@@ -87,6 +106,17 @@ export function LaunchWindow() {
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<div className="w-px h-5 bg-white/30" />
|
||||
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
onClick={openVideoFile}
|
||||
className={`gap-1 bg-transparent hover:bg-transparent px-0 flex-1 text-right text-xs ${styles.electronNoDrag} folderButton`}
|
||||
>
|
||||
<FaFolderMinus size={13} className="text-white" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,8 @@ import { Button } from "@/components/ui/button";
|
||||
import { useState } from "react";
|
||||
import Colorful from '@uiw/react-color-colorful';
|
||||
import { hsvaToHex } from '@uiw/color-convert';
|
||||
import { Trash2, Download, Crop, X, Bug, Upload, Coffee } from "lucide-react";
|
||||
import { Trash2, Download, Crop, X, Bug, Upload } from "lucide-react";
|
||||
import { GiHearts } from "react-icons/gi";
|
||||
import { toast } from "sonner";
|
||||
import type { ZoomDepth, CropRegion } from "./types";
|
||||
import { CropControl } from "./CropControl";
|
||||
@@ -415,9 +416,9 @@ export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth,
|
||||
onClick={() => {
|
||||
window.electronAPI?.openExternalUrl('https://github.com/siddharthvaddem/openscreen/issues/new');
|
||||
}}
|
||||
className="flex-1 flex items-center justify-center gap-2 text-xs text-slate-500 hover:text-slate-300 transition-colors py-2 group"
|
||||
className="flex-1 flex items-center justify-center gap-2 text-xs py-2"
|
||||
>
|
||||
<Bug className="w-3 h-3 group-hover:text-[#34B27B] transition-colors" />
|
||||
<Bug className="w-3 h-3 text-[#34B27B]" />
|
||||
<span>Report a Bug</span>
|
||||
</button>
|
||||
<button
|
||||
@@ -425,10 +426,10 @@ export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth,
|
||||
onClick={() => {
|
||||
window.electronAPI?.openExternalUrl('https://buymeacoffee.com/siddharthvaddem');
|
||||
}}
|
||||
className="flex-1 flex items-center justify-center gap-2 text-xs text-slate-500 hover:text-slate-300 transition-colors py-2 group"
|
||||
className="flex-1 flex items-center justify-center gap-2 text-xs"
|
||||
>
|
||||
<Coffee className="w-3 h-3 group-hover:text-[#FFDD00] transition-colors" />
|
||||
<span>Buy me a Coffee</span>
|
||||
<GiHearts className="w-3 h-3 text-red-500" />
|
||||
<span>Support my work</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -66,13 +66,13 @@ export default function VideoEditor() {
|
||||
useEffect(() => {
|
||||
async function loadVideo() {
|
||||
try {
|
||||
const result = await window.electronAPI.getRecordedVideoPath();
|
||||
const result = await window.electronAPI.getCurrentVideoPath();
|
||||
|
||||
if (result.success && result.path) {
|
||||
const videoUrl = toFileUrl(result.path);
|
||||
setVideoPath(videoUrl);
|
||||
} else {
|
||||
setError(result.message || 'Failed to load video');
|
||||
setError('No video to load. Please record or select a video.');
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Error loading video: ' + String(err));
|
||||
|
||||
@@ -665,7 +665,13 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(({
|
||||
video.pause();
|
||||
allowPlaybackRef.current = false;
|
||||
currentTimeRef.current = 0;
|
||||
setVideoReady(true);
|
||||
|
||||
// hacky fix: To ensure video is fully ready for PixiJS
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
setVideoReady(true);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const [resolvedWallpaper, setResolvedWallpaper] = useState<string | null>(null);
|
||||
|
||||
Reference in New Issue
Block a user