Compare commits
2 Commits
2b29716fee
...
5c09120c23
| Author | SHA1 | Date | |
|---|---|---|---|
| 5c09120c23 | |||
| 1c4aaa7040 |
@@ -116,11 +116,19 @@ pub enum FileType {
|
||||
pub struct FileMimeType(String);
|
||||
|
||||
impl FileMimeType {
|
||||
pub fn new_raw(raw: &str) -> Self {
|
||||
Self(raw.to_owned())
|
||||
}
|
||||
|
||||
pub fn from_name(name: &str) -> Option<Self> {
|
||||
mime_guess::from_path(name)
|
||||
.first_raw()
|
||||
.map(|s| Self(s.to_owned()))
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
/// A valid file path that might start with a slash
|
||||
@@ -289,27 +297,39 @@ impl From<AbsoluteFilePath> for FilePath {
|
||||
pub type FileStreamInner =
|
||||
Box<dyn Stream<Item = Result<Bytes, std::io::Error>> + Send + Sync + Unpin + 'static>;
|
||||
|
||||
pub struct FileStream(FileType, FileStreamInner);
|
||||
pub struct FileStream {
|
||||
file_type: FileType,
|
||||
mime_type: Option<FileMimeType>,
|
||||
stream: FileStreamInner,
|
||||
}
|
||||
|
||||
impl FileStream {
|
||||
pub fn new<S>(file_type: FileType, stream: S) -> Self
|
||||
pub fn new<S>(file_type: FileType, mime_type: Option<FileMimeType>, stream: S) -> Self
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, std::io::Error>> + Send + Sync + Unpin + 'static,
|
||||
{
|
||||
Self(file_type, Box::new(stream))
|
||||
Self {
|
||||
file_type,
|
||||
mime_type,
|
||||
stream: Box::new(stream),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_type(&self) -> FileType {
|
||||
self.0
|
||||
self.file_type
|
||||
}
|
||||
|
||||
pub fn mime_type(&self) -> Option<&FileMimeType> {
|
||||
self.mime_type.as_ref()
|
||||
}
|
||||
|
||||
pub fn stream(&self) -> &FileStreamInner {
|
||||
&self.1
|
||||
&self.stream
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FileStream> for FileStreamInner {
|
||||
fn from(value: FileStream) -> Self {
|
||||
value.1
|
||||
value.stream
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,18 +76,22 @@ impl IntoResponse for FileStream {
|
||||
let mut builder = Response::builder().header(http::header::TRANSFER_ENCODING, "chunked");
|
||||
|
||||
if let Some(headers) = builder.headers_mut() {
|
||||
if self.file_type() == FileType::Directory {
|
||||
if let Some(mime_type) = self.mime_type() {
|
||||
headers.insert(
|
||||
http::header::CONTENT_TYPE,
|
||||
HeaderValue::from_str("application/zip").unwrap(),
|
||||
HeaderValue::from_str(mime_type.as_str()).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
headers.remove(http::header::CONTENT_LENGTH);
|
||||
headers.insert(
|
||||
http::header::TRANSFER_ENCODING,
|
||||
HeaderValue::from_str("chunked").unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
let inner: FileStreamInner = self.into();
|
||||
builder.body(axum::body::Body::from_stream(inner)).unwrap()
|
||||
builder
|
||||
.body(axum::body::Body::from_stream(FileStreamInner::from(self)))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,11 @@ impl FileSystem {
|
||||
}
|
||||
});
|
||||
|
||||
FileStream::new(FileType::Directory, ReceiverStream::new(rx))
|
||||
FileStream::new(
|
||||
FileType::Directory,
|
||||
Some(FileMimeType::new_raw("application/zip")),
|
||||
ReceiverStream::new(rx),
|
||||
)
|
||||
}
|
||||
|
||||
match path_request {
|
||||
@@ -293,7 +297,20 @@ impl FileSystem {
|
||||
bail!("File size exceeds configured limit");
|
||||
}
|
||||
|
||||
let stream = FileStream::new(FileType::File, ReaderStream::new(file));
|
||||
let mime_type = {
|
||||
let file_name = {
|
||||
let path = file_path.as_str();
|
||||
if let Some(last_slash_index) = path.rfind("/") {
|
||||
&path[last_slash_index + 1..]
|
||||
} else {
|
||||
path
|
||||
}
|
||||
};
|
||||
|
||||
FileMimeType::from_name(file_name)
|
||||
};
|
||||
|
||||
let stream = FileStream::new(FileType::File, mime_type, ReaderStream::new(file));
|
||||
|
||||
Ok(stream)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const useImageViewer = defineStore('image-viewer', {
|
||||
export default defineStore('image-viewer', {
|
||||
state: () => ({
|
||||
src: null as string | null,
|
||||
}),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useImageViewer } from './image';
|
||||
import { useTextEditor } from './text';
|
||||
import useImageViewer from './image';
|
||||
import useTextEditor from './text';
|
||||
|
||||
export { useImageViewer, useTextEditor };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { uploadToWarren } from '~/lib/api/warrens';
|
||||
import type { DirectoryEntry } from '~/shared/types';
|
||||
|
||||
export const useTextEditor = defineStore('text-editor', {
|
||||
export default defineStore('text-editor', {
|
||||
state: () => ({
|
||||
data: null as {
|
||||
warrenId: string;
|
||||
|
||||
Reference in New Issue
Block a user