directory back up (parent) button + drag entry into parent to move

This commit is contained in:
2025-07-30 17:25:10 +02:00
parent 2c834eb42b
commit 3b141cc7cd
18 changed files with 243 additions and 95 deletions

View File

@@ -15,8 +15,8 @@ use crate::{
models::{
file::{
AbsoluteFilePath, CatError, CatRequest, File, FileMimeType, FileName, FilePath,
FileStream, FileType, LsError, LsRequest, MkdirError, MkdirRequest, MvError,
MvRequest, RelativeFilePath, RmError, RmRequest, SaveError, SaveRequest,
FileStream, FileType, LsError, LsRequest, LsResponse, MkdirError, MkdirRequest,
MvError, MvRequest, RelativeFilePath, RmError, RmRequest, SaveError, SaveRequest,
SaveResponse, TouchError, TouchRequest,
},
warren::UploadFileStream,
@@ -75,13 +75,38 @@ impl FileSystem {
self.base_directory.join(&path.as_relative())
}
async fn get_all_files(&self, absolute_path: &AbsoluteFilePath) -> anyhow::Result<Vec<File>> {
let directory_path = self.get_target_path(absolute_path);
let mut dir = fs::read_dir(&directory_path).await?;
async fn get_all_files(
&self,
absolute_path: &AbsoluteFilePath,
include_parent: bool,
) -> anyhow::Result<LsResponse> {
let dir_path = self.get_target_path(absolute_path).as_ref().to_path_buf();
let mut files = Vec::new();
let parent = if include_parent {
let dir_name = FileName::new(
&dir_path
.file_name()
.context("Failed to get directory name")?
.to_owned()
.into_string()
.ok()
.context("Failed to get directory name")?,
)?;
Some(File::new(
dir_name,
FileType::Directory,
None,
get_btime(&dir_path),
))
} else {
None
};
let mut dir = fs::read_dir(&dir_path).await?;
while let Ok(Some(entry)) = dir.next_entry().await {
let name = entry
.file_name()
@@ -100,18 +125,7 @@ impl FileSystem {
}
};
// TODO: Use `DirEntry::metadata` once `target=x86_64-unknown-linux-musl` updates from musl 1.2.3 to 1.2.5
// https://github.com/rust-lang/rust/pull/142682
let created_at = unsafe {
statx(
std::os::fd::BorrowedFd::borrow_raw(-100),
entry.path(),
rustix::fs::AtFlags::empty(),
rustix::fs::StatxFlags::BTIME,
)
}
.ok()
.map(|statx| statx.stx_btime.tv_sec as u64);
let created_at = get_btime(entry.path());
let mime_type = match file_type {
FileType::File => FileMimeType::from_name(&name),
@@ -126,7 +140,7 @@ impl FileSystem {
));
}
Ok(files)
Ok(LsResponse::new(files, parent))
}
/// Actually created a directory in the underlying file system
@@ -233,13 +247,16 @@ impl FileSystem {
}
impl FileSystemRepository for FileSystem {
async fn ls(&self, request: LsRequest) -> Result<Vec<File>, LsError> {
let files = self.get_all_files(request.path()).await.map_err(|err| {
anyhow!(err).context(format!(
"Failed to get the files at path: {}",
request.path()
))
})?;
async fn ls(&self, request: LsRequest) -> Result<LsResponse, LsError> {
let files = self
.get_all_files(request.path(), request.include_parent())
.await
.map_err(|err| {
anyhow!(err).context(format!(
"Failed to get the files at path: {}",
request.path()
))
})?;
Ok(files)
}
@@ -297,3 +314,21 @@ impl FileSystemRepository for FileSystem {
Ok(self.save(&path, &mut stream).await.map(SaveResponse::new)?)
}
}
// TODO: Use `DirEntry::metadata` once `target=x86_64-unknown-linux-musl` updates from musl 1.2.3 to 1.2.5
// https://github.com/rust-lang/rust/pull/142682
fn get_btime<P>(path: P) -> Option<u64>
where
P: rustix::path::Arg,
{
unsafe {
statx(
std::os::fd::BorrowedFd::borrow_raw(-100),
path,
rustix::fs::AtFlags::empty(),
rustix::fs::StatxFlags::BTIME,
)
}
.ok()
.map(|statx| statx.stx_btime.tv_sec as u64)
}

View File

@@ -3,7 +3,7 @@ use uuid::Uuid;
use crate::domain::warren::{
models::{
auth_session::requests::FetchAuthSessionResponse,
file::{AbsoluteFilePath, File},
file::{AbsoluteFilePath, LsResponse},
user::{ListAllUsersAndWarrensResponse, LoginUserResponse, User},
user_warren::UserWarren,
warren::{
@@ -57,7 +57,7 @@ impl WarrenNotifier for NotifierDebugLogger {
async fn warren_ls(&self, response: &WarrenLsResponse) {
tracing::debug!(
"[Notifier] Listed {} file(s) in warren {}",
response.files().len(),
response.base().files().len(),
response.warren().name()
);
}
@@ -101,8 +101,8 @@ impl WarrenNotifier for NotifierDebugLogger {
}
impl FileSystemNotifier for NotifierDebugLogger {
async fn ls(&self, files: &Vec<File>) {
tracing::debug!("[Notifier] Listed {} file(s)", files.len());
async fn ls(&self, response: &LsResponse) {
tracing::debug!("[Notifier] Listed {} file(s)", response.files().len());
}
async fn cat(&self, path: &AbsoluteFilePath) {
@@ -279,7 +279,7 @@ impl AuthNotifier for NotifierDebugLogger {
async fn auth_warren_ls(&self, user: &User, response: &WarrenLsResponse) {
tracing::debug!(
"[Notifier] Listed {} file(s) in warren {} for authenticated user {}",
response.files().len(),
response.base().files().len(),
response.warren().name(),
user.id()
);