feat(ui): permit drag&drop to the operating system
a drop outside of the browser will: - upload the file if only 1 file selected - upload a .zip of the directory or multiple selection (browsers do not permit multiple upload yet) note: I had to create a new handler because a post request to /api/batch/download is possible via JS but it will create a memory blob in the browser, during the drag action. This may exhaust the browser's memory if heavy files This will initiate zip creation from the server even if drop is canceled The best approach is to add a handler supporting GET calls, this call will be triggered by the browser on drop action outside of it's window
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use axum::{
|
||||
extract::{Json, State},
|
||||
extract::{Json, Query, State},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
@@ -12,6 +12,7 @@ use crate::application::dtos::folder_dto::FolderDto;
|
||||
use crate::application::services::batch_operations::{
|
||||
BatchOperationService, BatchResult, BatchStats,
|
||||
};
|
||||
use crate::interfaces::api::deserializer;
|
||||
use crate::interfaces::api::handlers::ApiResult;
|
||||
use crate::interfaces::middleware::auth::AuthUser;
|
||||
|
||||
@@ -646,6 +647,24 @@ pub struct BatchDownloadRequest {
|
||||
pub folder_ids: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct BatchDownloadQuery {
|
||||
#[serde(default, deserialize_with = "deserializer::deserialize_csv")]
|
||||
pub file_ids: Vec<String>, // will deserialize query string "1,2,3" into Vec<String>
|
||||
#[serde(default, deserialize_with = "deserializer::deserialize_csv")]
|
||||
pub folder_ids: Vec<String>, // will deserialize query string "1,2,3" into Vec<String>
|
||||
}
|
||||
|
||||
// convert BatchDownloadQuery into BatchDownloadRequest
|
||||
impl From<BatchDownloadQuery> for BatchDownloadRequest {
|
||||
fn from(q: BatchDownloadQuery) -> Self {
|
||||
Self {
|
||||
file_ids: q.file_ids,
|
||||
folder_ids: q.folder_ids,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for moving multiple files and folders to trash in batch
|
||||
#[utoipa::path(
|
||||
post,
|
||||
@@ -832,6 +851,14 @@ pub async fn move_folders_batch(
|
||||
Ok((status_code, Json(response)).into_response())
|
||||
}
|
||||
|
||||
// Hander as a workarround for drag & drop (does not support POST requests)
|
||||
pub async fn download_batch_querystring(
|
||||
State(state): State<BatchHandlerState>,
|
||||
auth_user: AuthUser,
|
||||
Query(params): Query<BatchDownloadQuery>,
|
||||
) -> Result<Response, (StatusCode, String)> {
|
||||
process_download_batch(state, auth_user, params.into()).await
|
||||
}
|
||||
/// Handler for downloading multiple files and folders as a single ZIP.
|
||||
///
|
||||
/// The ZIP is written to a temporary file and streamed to the client,
|
||||
@@ -847,10 +874,18 @@ pub async fn move_folders_batch(
|
||||
),
|
||||
tag = "batch"
|
||||
)]
|
||||
pub async fn download_batch(
|
||||
pub async fn download_batch_post(
|
||||
State(state): State<BatchHandlerState>,
|
||||
auth_user: AuthUser,
|
||||
Json(request): Json<BatchDownloadRequest>,
|
||||
) -> Result<Response, (StatusCode, String)> {
|
||||
process_download_batch(state, auth_user, request).await
|
||||
}
|
||||
|
||||
async fn process_download_batch(
|
||||
state: BatchHandlerState,
|
||||
auth_user: AuthUser,
|
||||
request: BatchDownloadRequest,
|
||||
) -> Result<Response, (StatusCode, String)> {
|
||||
if request.file_ids.is_empty() && request.folder_ids.is_empty() {
|
||||
return Err((
|
||||
|
||||
Reference in New Issue
Block a user