Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 34 additions & 26 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,47 @@ logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-electron
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
release/**
*.kiro/
# npx electron-builder --mac --win
.tmp/
.history/
*.tsbuildinfo
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-electron
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
release/**
*.kiro/
# npx electron-builder --mac --win
.tmp/
.history/
*.tsbuildinfo
vite.config.js
vite.config.d.ts

# Native capture build artifacts
electron/native/wgc-capture/build/
electron/native/cursor-monitor/build/

# Local build tools and caches
.cache/
.cmake_ext/
ebcache/
docs/
recordly_dev/
.agent/

# Local debug helpers
tmp-*.ps1
.tmp-*.ps1
Binary file modified electron/native/bin/win32-x64/cursor-monitor.exe
Binary file not shown.
8 changes: 4 additions & 4 deletions electron/native/bin/win32-x64/helpers-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
"helpers": {
"wgc-capture": {
"binaryName": "wgc-capture.exe",
"binarySha256": "5f364b07b016c597288f90a9b61c581e6559d6d32b79ffadceb37859bbea8dd2",
"binarySha256": "c01e731bb255096ba8add9bf293d82545af29d82848d456545c2b182a17717fc",
"sourceDir": "electron/native/wgc-capture",
"sourceFingerprint": "9e9bce082266ca5968cf5f0b535b469d47c4ec3a775a93726171c0dfdbcdaa44",
"updatedAt": "2026-03-28T05:48:46.587Z"
"updatedAt": "2026-03-29T02:18:57.450Z"
},
"cursor-monitor": {
"binaryName": "cursor-monitor.exe",
"binarySha256": "916ed064c12a3b861d7721df8b9209d10ec0fdb8078564a2ba3ea8cf4f4354c4",
"binarySha256": "d81b6358021ee5b27e601c14b9cc5edd0689647abd507e3dcd8ffe12f914c50d",
"sourceDir": "electron/native/cursor-monitor",
"sourceFingerprint": "6ad1b8b50bb336f2a48937b06f5ec56d90b6ab4a3e56a4bca278cf67a5d3e52e",
"updatedAt": "2026-03-28T05:17:17.697Z"
"updatedAt": "2026-03-29T02:19:01.284Z"
}
}
}
Binary file modified electron/native/bin/win32-x64/wgc-capture.exe
Binary file not shown.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 14 additions & 3 deletions src/components/video-editor/AnnotationOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export function AnnotationOverlay({
<div
className="w-full h-full flex items-center p-2 overflow-hidden"
style={{
justifyContent: annotation.style.textAlign === 'left' ? 'flex-start' :
annotation.style.textAlign === 'right' ? 'flex-end' : 'center',
justifyContent: annotation.style.textAlign === 'left' ? 'flex-start' :
annotation.style.textAlign === 'right' ? 'flex-end' : 'center',
alignItems: 'center',
}}
>
Expand Down Expand Up @@ -111,6 +111,17 @@ export function AnnotationOverlay({
</div>
);

case 'blur':
return (
<div
className="w-full h-full rounded-lg backdrop-blur-md"
style={{
backdropFilter: `blur(${annotation.blurIntensity ?? 12}px)`,
WebkitBackdropFilter: `blur(${annotation.blurIntensity ?? 12}px)`
}}
/>
);

default:
return null;
}
Expand All @@ -127,7 +138,7 @@ export function AnnotationOverlay({
const xPercent = (d.x / containerWidth) * 100;
const yPercent = (d.y / containerHeight) * 100;
onPositionChange(annotation.id, { x: xPercent, y: yPercent });

// Reset dragging flag after a short delay to prevent click event
setTimeout(() => {
isDraggingRef.current = false;
Expand Down
49 changes: 42 additions & 7 deletions src/components/video-editor/AnnotationSettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface AnnotationSettingsPanelProps {
onTypeChange: (type: AnnotationType) => void;
onStyleChange: (style: Partial<AnnotationRegion['style']>) => void;
onFigureDataChange?: (figureData: FigureData) => void;
onBlurIntensityChange?: (intensity: number) => void;
onDelete: () => void;
}

Expand All @@ -43,6 +44,7 @@ export function AnnotationSettingsPanel({
onTypeChange,
onStyleChange,
onFigureDataChange,
onBlurIntensityChange,
onDelete,
}: AnnotationSettingsPanelProps) {
const t = useScopedT('editor');
Expand Down Expand Up @@ -128,21 +130,29 @@ export function AnnotationSettingsPanel({

{/* Type Selector */}
<Tabs value={annotation.type} onValueChange={(value) => onTypeChange(value as AnnotationType)} className="mb-6">
<TabsList className="mb-4 bg-white/5 border border-white/5 p-1 w-full grid grid-cols-3 h-auto rounded-xl">
<TabsTrigger value="text" className="data-[state=active]:bg-[#2563EB] data-[state=active]:text-white text-slate-400 py-2 rounded-lg transition-all gap-2">
<Type className="w-4 h-4" />
<TabsList className="mb-4 bg-white/[0.03] border border-white/[0.06] p-0.5 w-full grid grid-cols-4 h-10 rounded-xl backdrop-blur-sm">
<TabsTrigger value="text" className="data-[state=active]:bg-white/[0.08] data-[state=active]:text-[#3B82F6] data-[state=active]:shadow-none text-slate-400 py-1.5 rounded-lg transition-all gap-1.5 text-[11px] font-medium border border-transparent data-[state=active]:border-white/[0.05]">
<Type className="w-3.5 h-3.5" />
{t('annotations.text')}
</TabsTrigger>
<TabsTrigger value="image" className="data-[state=active]:bg-[#2563EB] data-[state=active]:text-white text-slate-400 py-2 rounded-lg transition-all gap-2">
<ImageIcon className="w-4 h-4" />
<TabsTrigger value="image" className="data-[state=active]:bg-white/[0.08] data-[state=active]:text-[#3B82F6] data-[state=active]:shadow-none text-slate-400 py-1.5 rounded-lg transition-all gap-1.5 text-[11px] font-medium border border-transparent data-[state=active]:border-white/[0.05]">
<ImageIcon className="w-3.5 h-3.5" />
{t('annotations.image')}
</TabsTrigger>
<TabsTrigger value="figure" className="data-[state=active]:bg-[#2563EB] data-[state=active]:text-white text-slate-400 py-2 rounded-lg transition-all gap-2">
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<TabsTrigger value="figure" className="data-[state=active]:bg-white/[0.08] data-[state=active]:text-[#3B82F6] data-[state=active]:shadow-none text-slate-400 py-1.5 rounded-lg transition-all gap-1.5 text-[11px] font-medium border border-transparent data-[state=active]:border-white/[0.05]">
<svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<path d="M4 12h16m0 0l-6-6m6 6l-6 6" strokeLinecap="round" strokeLinejoin="round" />
</svg>
{t('annotations.arrow')}
</TabsTrigger>
<TabsTrigger value="blur" className="data-[state=active]:bg-white/[0.08] data-[state=active]:text-[#3B82F6] data-[state=active]:shadow-none text-slate-400 py-1.5 rounded-lg transition-all gap-1.5 text-[11px] font-medium border border-transparent data-[state=active]:border-white/[0.05]">
<svg className="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="9" className="opacity-30" />
<circle cx="12" cy="12" r="5" className="opacity-60" />
<circle cx="12" cy="12" r="1.5" fill="currentColor" />
</svg>
{t('annotations.blur', 'Blur')}
</TabsTrigger>
</TabsList>

{/* Text Content */}
Expand Down Expand Up @@ -499,6 +509,31 @@ export function AnnotationSettingsPanel({
</Popover>
</div>
</TabsContent>
<TabsContent value="blur" className="mt-0 space-y-4">
<div className="bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 shadow-sm">
<div className="flex items-center justify-between mb-4">
<label className="text-xs font-semibold text-slate-200 uppercase tracking-widest opacity-80">
{t('annotations.blurIntensity', 'Intensity')}
</label>
<span className="text-xs font-mono font-bold text-[#3B82F6] bg-[#3B82F6]/10 px-2 py-0.5 rounded-md border border-[#3B82F6]/20">
{annotation.blurIntensity ?? 12}px
</span>
Comment on lines +518 to +520
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unit display may confuse users.

The intensity value is displayed with a % suffix, but based on the AI summary, the blur effect is applied as pixels (e.g., backdrop-filter: blur(12px)). Showing "12%" when it actually means "12px" blur could mislead users about the effect scale.

Consider either:

  • Removing the % suffix or replacing with px
  • Or mapping the 1-100 range to a sensible pixel range and documenting this internally
Proposed fix to remove misleading percentage
                 <span className="text-xs font-mono font-bold text-[`#3B82F6`] bg-[`#3B82F6`]/10 px-2 py-0.5 rounded-md border border-[`#3B82F6`]/20">
-                  {annotation.blurIntensity ?? 12}%
+                  {annotation.blurIntensity ?? 12}
                 </span>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<span className="text-xs font-mono font-bold text-[#3B82F6] bg-[#3B82F6]/10 px-2 py-0.5 rounded-md border border-[#3B82F6]/20">
{annotation.blurIntensity ?? 12}%
</span>
<span className="text-xs font-mono font-bold text-[`#3B82F6`] bg-[`#3B82F6`]/10 px-2 py-0.5 rounded-md border border-[`#3B82F6`]/20">
{annotation.blurIntensity ?? 12}
</span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/AnnotationSettingsPanel.tsx` around lines 518 -
520, The UI shows annotation.blurIntensity with a "%" suffix which is misleading
because the blur is applied in pixels; update the display in
AnnotationSettingsPanel (the span currently rendering {annotation.blurIntensity
?? 12}%) to show pixels (e.g., "px") or a mapped pixel value instead: either
change the suffix to "px" and ensure the blur style uses
`${annotation.blurIntensity}px`, or introduce a single helper like
mapBlurIntensityToPx(value) and use it both for the CSS blur (backdrop-filter:
blur(...)) and for the displayed label so the units and value are consistent
across AnnotationSettingsPanel and wherever blur is applied.

</div>
<Slider
value={[annotation.blurIntensity ?? 12]}
onValueChange={([value]) => {
onBlurIntensityChange?.(value);
}}
min={1}
max={100}
step={1}
className="w-full"
/>
<p className="text-[10px] text-slate-500 mt-4 leading-relaxed font-medium">
{t('annotations.blurDescription', 'Obscure sensitive information by blurring the underlying video content.')}
</p>
</div>
</TabsContent>
</Tabs>

<Button
Expand Down
15 changes: 11 additions & 4 deletions src/components/video-editor/SettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ interface SettingsPanelProps {
onAnnotationTypeChange?: (id: string, type: AnnotationType) => void;
onAnnotationStyleChange?: (id: string, style: Partial<AnnotationRegion["style"]>) => void;
onAnnotationFigureDataChange?: (id: string, figureData: FigureData) => void;
onAnnotationBlurIntensityChange?: (id: string, intensity: number) => void;
onAnnotationDelete?: (id: string) => void;
autoCaptions?: CaptionCue[];
autoCaptionSettings?: AutoCaptionSettings;
Expand Down Expand Up @@ -545,6 +546,7 @@ export function SettingsPanel({
onAnnotationTypeChange,
onAnnotationStyleChange,
onAnnotationFigureDataChange,
onAnnotationBlurIntensityChange,
onAnnotationDelete,
autoCaptions = [],
autoCaptionSettings = DEFAULT_AUTO_CAPTION_SETTINGS,
Expand Down Expand Up @@ -1171,15 +1173,20 @@ export function SettingsPanel({
return (
<AnnotationSettingsPanel
annotation={selectedAnnotation}
onContentChange={(content) => onAnnotationContentChange(selectedAnnotation.id, content)}
onTypeChange={(type) => onAnnotationTypeChange(selectedAnnotation.id, type)}
onStyleChange={(style) => onAnnotationStyleChange(selectedAnnotation.id, style)}
onContentChange={(content) => onAnnotationContentChange?.(selectedAnnotation.id, content)}
onTypeChange={(type) => onAnnotationTypeChange?.(selectedAnnotation.id, type)}
onStyleChange={(style) => onAnnotationStyleChange?.(selectedAnnotation.id, style)}
onFigureDataChange={
onAnnotationFigureDataChange
? (figureData) => onAnnotationFigureDataChange(selectedAnnotation.id, figureData)
: undefined
}
onDelete={() => onAnnotationDelete(selectedAnnotation.id)}
onBlurIntensityChange={
onAnnotationBlurIntensityChange
? (intensity) => onAnnotationBlurIntensityChange(selectedAnnotation.id, intensity)
: undefined
}
onDelete={() => onAnnotationDelete?.(selectedAnnotation.id)}
/>
);
}
Expand Down
Loading