Skip to content

Conversation

@ibex088
Copy link

@ibex088 ibex088 commented Jan 15, 2026

Summary

This PR adds a new tab-based web recorder flow. When users click the Chrome extension icon, it opens (or focuses) a dedicated recorder tab and redirects to /record, where the app can safely request camera and microphone permissions and start recording.

Screenshot 2026-01-16 at 10 48 29 AM

Why this approach

Chrome extensions can’t directly request camera/microphone access — permissions must come from a real web page.

The reason I created a new page instead of using the existing web-browser recording modal is to make it feel like a native browser extension experience. Opening it in a new page allows it to appear like an extension popup in the top-right corner, so it feels like you’re interacting with the extension itself rather than just another web modal.

What’s included

Opens or reuses a dedicated recorder tab from the extension

Full recording UI at /record with:

Recording mode selection (fullscreen, window, tab, camera-only)

Device selection & settings panel

In-progress controls (pause / resume / restart)

Persists selected devices via localStorage

Polished UI with smooth transitions and animated icons

https://cap.link/etvvdnprradt3x8

fixes #1502
fixes CAP-592

Future work

Explored an in-page iframe overlay recorder, but it introduces significant complexity (cross-origin permissions, iframe restrictions, state sync). The current tab-based approach is simpler and more robust for V1.

- Add settings panel with device memory toggle to web recorder interface
- Support callbackUrl parameter in login form for post-auth redirects
- Move AuthContextProvider to record layout for better auth state management
- Improve permission request handling with fallback for denied devices
- Show sign-in prompt when user is not authenticated on recorder page
- Add settings button to recorder header with animated panel transition
@ibex088 ibex088 changed the title feat: chrome extention feat: chrome extension Jan 15, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

12 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 86 to 94
## Permissions

The extension requires the following permissions:

- **`storage`**: Store authentication tokens and user preferences
- **`tabs`**: Access tab information for tab recording
- **`activeTab`**: Capture current tab content
- **`scripting`**: Inject content script for recording indicator
- **`offscreen`**: Create offscreen document for media capture
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: README lists permissions that aren't declared in manifest.json. The manifest only requests tabs, but this lists storage, activeTab, scripting, and offscreen. Either add these permissions to the manifest or update the README to match what's actually implemented.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/chrome-extension/README.md
Line: 86:94

Comment:
**logic:** README lists permissions that aren't declared in `manifest.json`. The manifest only requests `tabs`, but this lists `storage`, `activeTab`, `scripting`, and `offscreen`. Either add these permissions to the manifest or update the README to match what's actually implemented.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Author

Choose a reason for hiding this comment

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

Comment on lines 5 to 27
## Features

- **Multiple Recording Modes**
- Screen recording (entire screen or specific window)
- Tab recording (current browser tab)
- Camera recording (webcam only)

- **Recording Controls**
- Start/stop recording
- Pause/resume during recording
- Real-time recording timer
- On-page recording indicator

- **Audio Options**
- Optional microphone audio
- System audio capture (for tab recording)
- High-quality audio encoding

- **Seamless Integration**
- Automatic upload to Cap
- Direct link to recorded video
- Progress tracking during upload
- Multipart upload for large files
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: README claims the extension provides recording controls, audio options, and upload functionality. The actual extension code only opens a tab to /record - all these features are implemented in the web app, not the extension. Update the README to clarify that the extension is a launcher for the web-based recorder.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/chrome-extension/README.md
Line: 5:27

Comment:
**logic:** README claims the extension provides recording controls, audio options, and upload functionality. The actual extension code only opens a tab to `/record` - all these features are implemented in the web app, not the extension. Update the README to clarify that the extension is a launcher for the web-based recorder.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Author

Choose a reason for hiding this comment

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

Comment on lines 173 to 183
useEffect(() => {
console.log('Recording state:', {
canStartRecording,
isBrowserSupported,
supportCheckCompleted,
supportsDisplayRecording,
recordingMode,
organisationId,
unsupportedReason
});
}, [canStartRecording, isBrowserSupported, supportCheckCompleted, supportsDisplayRecording, recordingMode, organisationId, unsupportedReason]);
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Remove debug console.log before merging to production.

Suggested change
useEffect(() => {
console.log('Recording state:', {
canStartRecording,
isBrowserSupported,
supportCheckCompleted,
supportsDisplayRecording,
recordingMode,
organisationId,
unsupportedReason
});
}, [canStartRecording, isBrowserSupported, supportCheckCompleted, supportsDisplayRecording, recordingMode, organisationId, unsupportedReason]);
useEffect(() => {
console.log('Recording state:', {
canStartRecording,
isBrowserSupported,
supportCheckCompleted,
supportsDisplayRecording,
recordingMode,
organisationId,
unsupportedReason
});
}, [canStartRecording, isBrowserSupported, supportCheckCompleted, supportsDisplayRecording, recordingMode, organisationId, unsupportedReason]);

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/(org)/record/RecorderPageContent.tsx
Line: 173:183

Comment:
**style:** Remove debug `console.log` before merging to production.

```suggestion
	useEffect(() => {
		console.log('Recording state:', {
			canStartRecording,
			isBrowserSupported,
			supportCheckCompleted,
			supportsDisplayRecording,
			recordingMode,
			organisationId,
			unsupportedReason
		});
	}, [canStartRecording, isBrowserSupported, supportCheckCompleted, supportsDisplayRecording, recordingMode, organisationId, unsupportedReason]);
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Author

Choose a reason for hiding this comment

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

Comment on lines 197 to 201
const handleStopClick = () => {
stopRecording().catch((err: unknown) => {

});
};
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Empty catch block silently swallows errors. Handle errors properly or at least log them.

Suggested change
const handleStopClick = () => {
stopRecording().catch((err: unknown) => {
});
};
const handleStopClick = () => {
stopRecording().catch((err: unknown) => {
console.error('Failed to stop recording:', err);
});
};
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/(org)/record/RecorderPageContent.tsx
Line: 197:201

Comment:
**style:** Empty catch block silently swallows errors. Handle errors properly or at least log them.

```suggestion
	const handleStopClick = () => {
		stopRecording().catch((err: unknown) => {
			console.error('Failed to stop recording:', err);
		});
	};
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Author

Choose a reason for hiding this comment

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

Comment on lines 389 to 393
: () => {
startRecording().catch((err: unknown) => {

});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Empty catch block silently swallows errors. Handle errors properly or at least log them.

Suggested change
: () => {
startRecording().catch((err: unknown) => {
});
}
: () => {
startRecording().catch((err: unknown) => {
console.error('Failed to start recording:', err);
});
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/(org)/record/RecorderPageContent.tsx
Line: 389:393

Comment:
**style:** Empty catch block silently swallows errors. Handle errors properly or at least log them.

```suggestion
					: () => {
									startRecording().catch((err: unknown) => {
										console.error('Failed to start recording:', err);
									});
								}
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Author

Choose a reason for hiding this comment

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

…ogging

- Simplify Chrome extension README to reflect launcher-only functionality
- Remove detailed feature descriptions for recording modes and controls
- Update permissions list to only include required tabs permission
- Fix organisationId nullish coalescing to use undefined instead of null
- Remove verbose recording state debug logging from RecorderPageContent
- Add error logging to start/stop recording handlers for better debugging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improvement: browser extension + auto-record

1 participant