diff --git a/src-tauri/src/api_server.rs b/src-tauri/src/api_server.rs index 2a35e1d..2d2b1b3 100644 --- a/src-tauri/src/api_server.rs +++ b/src-tauri/src/api_server.rs @@ -4,7 +4,7 @@ use crate::profile::manager::ProfileManager; use crate::proxy_manager::PROXY_MANAGER; use crate::tag_manager::TAG_MANAGER; use axum::{ - extract::{Path, Query, State}, + extract::{Path, State}, http::{HeaderMap, StatusCode}, middleware::{self, Next}, response::{Json, Response}, @@ -13,7 +13,6 @@ use axum::{ }; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; use std::sync::Arc; use tauri::Emitter; use tokio::net::TcpListener; @@ -141,6 +140,17 @@ struct RunProfileResponse { headless: bool, } +#[derive(Debug, Deserialize)] +struct RunProfileRequest { + url: Option, + headless: Option, +} + +#[derive(Debug, Deserialize)] +struct OpenUrlRequest { + url: String, +} + pub struct ApiServer { port: Option, shutdown_tx: Option>, @@ -205,6 +215,8 @@ impl ApiServer { .route("/profiles/{id}", put(update_profile)) .route("/profiles/{id}", delete(delete_profile)) .route("/profiles/{id}/run", post(run_profile)) + .route("/profiles/{id}/open-url", post(open_url_in_profile)) + .route("/profiles/{id}/kill", post(kill_profile)) .route("/groups", get(get_groups).post(create_group)) .route( "/groups/{id}", @@ -785,13 +797,11 @@ async fn delete_proxy( // API Handler - Run Profile with Remote Debugging async fn run_profile( Path(id): Path, - Query(params): Query>, State(state): State, + Json(request): Json, ) -> Result, StatusCode> { - let headless = params - .get("headless") - .and_then(|v| v.parse::().ok()) - .unwrap_or(false); + let headless = request.headless.unwrap_or(false); + let url = request.url; let profile_manager = ProfileManager::instance(); let profiles = profile_manager @@ -810,7 +820,7 @@ async fn run_profile( match crate::browser_runner::launch_browser_profile_with_debugging( state.app_handle.clone(), profile.clone(), - None, + url, Some(remote_debugging_port), headless, ) @@ -825,6 +835,46 @@ async fn run_profile( } } +// API Handler - Open URL in existing browser +async fn open_url_in_profile( + Path(id): Path, + State(state): State, + Json(request): Json, +) -> Result { + let browser_runner = crate::browser_runner::BrowserRunner::instance(); + + browser_runner + .open_url_with_profile(state.app_handle.clone(), id, request.url) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + Ok(StatusCode::OK) +} + +// API Handler - Kill browser process +async fn kill_profile( + Path(id): Path, + State(state): State, +) -> Result { + let profile_manager = ProfileManager::instance(); + let profiles = profile_manager + .list_profiles() + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + let profile = profiles + .iter() + .find(|p| p.id.to_string() == id) + .ok_or(StatusCode::NOT_FOUND)?; + + let browser_runner = crate::browser_runner::BrowserRunner::instance(); + browser_runner + .kill_browser_process(state.app_handle.clone(), profile) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + Ok(StatusCode::NO_CONTENT) +} + // API Handler - Download Browser async fn download_browser_api( State(state): State, diff --git a/src/components/settings-dialog.tsx b/src/components/settings-dialog.tsx index 76d1a7a..dfe64c5 100644 --- a/src/components/settings-dialog.tsx +++ b/src/components/settings-dialog.tsx @@ -911,9 +911,27 @@ export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) {
  • - POST /profiles/{"{"}id{"}"}/run?headless=true|false + POST /profiles/{"{"}id{"}"}/run {" "} — launch with remote debugging + + (body: {"{"}url?, headless?{"}"}) + +
  • +
  • + + POST /profiles/{"{"}id{"}"}/open-url + {" "} + — open URL in running profile + + (body: {"{"}url{"}"}) + +
  • +
  • + + POST /profiles/{"{"}id{"}"}/kill + {" "} + — stop browser process