-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add deeplink support for pause, resume, mic and camera switching (#1540) #2051
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
332beac
8e9fb90
691fe87
cb0ea6d
2479097
2c45cd1
1a5b943
5509218
bf82662
d1230f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,15 +46,14 @@ pub enum DeepLinkAction { | |
| mode: RecordingMode, | ||
| }, | ||
| StopRecording, | ||
| #[cfg(debug_assertions)] | ||
| PauseRecording, | ||
| #[cfg(debug_assertions)] | ||
| ResumeRecording, | ||
| #[cfg(debug_assertions)] | ||
| SwitchMicrophone { | ||
| mic_label: Option<String>, | ||
| }, | ||
| OpenCamera { | ||
| camera: DeviceOrModelID, | ||
| }, | ||
| #[cfg(debug_assertions)] | ||
| SetCameraPreviewState { | ||
| state: CameraPreviewState, | ||
|
BMNTR marked this conversation as resolved.
Outdated
|
||
| }, | ||
|
|
@@ -165,20 +164,46 @@ impl TryFrom<&Url> for DeepLinkAction { | |
| } | ||
|
|
||
| match url.domain() { | ||
|
BMNTR marked this conversation as resolved.
Outdated
|
||
| Some("action") => {} | ||
| Some(_) => return Err(ActionParseFromUrlError::NotAction), | ||
| None => return Err(ActionParseFromUrlError::Invalid), | ||
| Some("action") => { | ||
| let params = url | ||
| .query_pairs() | ||
| .collect::<std::collections::HashMap<_, _>>(); | ||
| let json_value = params | ||
| .get("value") | ||
| .ok_or(ActionParseFromUrlError::Invalid)?; | ||
| let action: Self = serde_json::from_str(json_value) | ||
| .map_err(|e| ActionParseFromUrlError::ParseFailed(e.to_string()))?; | ||
| Ok(action) | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Sensitive recording controls exposed in production via unauthenticated deep links Sensitive recording controls now exposed via unauthenticated deep links in production builds. Add authorization checks or user confirmation before executing sensitive controls via deep links. AI prompt |
||
| Some("stop" | "stop-recording") => Ok(Self::StopRecording), | ||
| Some("pause" | "pause-recording") => Ok(Self::PauseRecording), | ||
| Some("resume" | "resume-recording") => Ok(Self::ResumeRecording), | ||
| Some("switch-mic" | "switch-microphone") => { | ||
| let params = url | ||
| .query_pairs() | ||
| .collect::<std::collections::HashMap<_, _>>(); | ||
| let mic_label = params | ||
|
BMNTR marked this conversation as resolved.
|
||
| .get("mic_label") | ||
| .or_else(|| params.get("label")) | ||
| .map(|s| s.to_string()); | ||
| Ok(Self::SwitchMicrophone { mic_label }) | ||
| } | ||
| Some("open-camera" | "switch-camera") => { | ||
| let params = url | ||
| .query_pairs() | ||
| .collect::<std::collections::HashMap<_, _>>(); | ||
| let device_id = params | ||
|
BMNTR marked this conversation as resolved.
|
||
| .get("id") | ||
| .or_else(|| params.get("camera")) | ||
|
BMNTR marked this conversation as resolved.
|
||
| .map(|s| s.to_string()) | ||
| .ok_or(ActionParseFromUrlError::Invalid)?; | ||
| Ok(Self::OpenCamera { | ||
| camera: DeviceOrModelID::DeviceID(device_id), | ||
| }) | ||
| } | ||
|
Comment on lines
+182
to
+207
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Raycast invokes a documented direct URL such as Knowledge Base Used: Desktop Tauri App (Rust Backend) Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/desktop/src-tauri/src/deeplink_actions.rs
Line: 178-203
Comment:
**Direct-link scheme is unregistered**
When Raycast invokes a documented direct URL such as `cap://pause` or `cap://switch-mic?label=...`, the operating system cannot route it to Cap because the application registers only the `cap-desktop` scheme, so none of these new action handlers executes.
**Knowledge Base Used:** [Desktop Tauri App (Rust Backend)](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/desktop-tauri-app.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
BMNTR marked this conversation as resolved.
|
||
| Some(_) => Err(ActionParseFromUrlError::NotAction), | ||
| None => Err(ActionParseFromUrlError::Invalid), | ||
| } | ||
|
BMNTR marked this conversation as resolved.
|
||
|
|
||
| let params = url | ||
| .query_pairs() | ||
| .collect::<std::collections::HashMap<_, _>>(); | ||
| let json_value = params | ||
| .get("value") | ||
| .ok_or(ActionParseFromUrlError::Invalid)?; | ||
| let action: Self = serde_json::from_str(json_value) | ||
| .map_err(|e| ActionParseFromUrlError::ParseFailed(e.to_string()))?; | ||
| Ok(action) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -244,15 +269,18 @@ impl DeepLinkAction { | |
| DeepLinkAction::StopRecording => { | ||
| crate::recording::stop_recording(app.clone(), app.state()).await | ||
| } | ||
| #[cfg(debug_assertions)] | ||
| DeepLinkAction::PauseRecording => { | ||
| crate::recording::pause_recording(app.clone(), app.state()).await | ||
| } | ||
| #[cfg(debug_assertions)] | ||
| DeepLinkAction::ResumeRecording => { | ||
| crate::recording::resume_recording(app.clone(), app.state()).await | ||
| } | ||
| #[cfg(debug_assertions)] | ||
| DeepLinkAction::SwitchMicrophone { mic_label } => { | ||
| let state = app.state::<ArcLock<App>>(); | ||
| crate::set_mic_input(state, mic_label) | ||
| .await | ||
| .map_err(|e| e.to_string()) | ||
| } | ||
| DeepLinkAction::OpenCamera { camera } => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this arm is no longer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since |
||
| crate::set_camera_input( | ||
| app.clone(), | ||
|
|
@@ -282,7 +310,6 @@ impl DeepLinkAction { | |
|
|
||
| Ok(()) | ||
| } | ||
| #[cfg(debug_assertions)] | ||
| DeepLinkAction::SetCameraPreviewState { state } => { | ||
| crate::set_camera_preview_state(app.state(), state).await | ||
| } | ||
|
|
@@ -358,7 +385,6 @@ mod tests { | |
| ); | ||
| } | ||
|
|
||
| #[cfg(debug_assertions)] | ||
| #[test] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the new public contract is the direct host routes (e.g. |
||
| fn parses_pause_and_resume_action_urls() { | ||
| let pause_url = Url::parse("cap-desktop://action?value=%22pause_recording%22").unwrap(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
impl TryFrom<&Url> for DeepLinkActionlooks accidentally corrupted right now (multiple nestedfn try_from(...)declarations + strayreturn Err(...)blocks). As-is it won’t compile.I’d collapse it back to a single
fn try_from(url: &Url) -> Result<...>body (keeping the macOSfile://early return) and then keep the scheme/host routing logic inside that one function.