Add standalone media and remote downloads

This commit is contained in:
burnintuna 2026-07-21 21:18:36 +09:00
parent 8a213462e0
commit 5f9b5d9796
14 changed files with 683 additions and 86 deletions

View file

@ -6,6 +6,15 @@ use std::time::SystemTime;
pub enum EntryKind {
Directory,
ZipArchive,
Image,
Video,
OtherFile,
}
impl EntryKind {
pub fn is_viewable(self) -> bool {
matches!(self, Self::ZipArchive | Self::Image | Self::Video)
}
}
#[derive(Debug, Clone)]
@ -34,9 +43,12 @@ pub enum SortDirection {
pub fn sort_entries(entries: &mut [BrowserEntry], field: SortField, direction: SortDirection) {
entries.sort_by(|left, right| {
let kind_order = match (left.kind, right.kind) {
(EntryKind::Directory, EntryKind::ZipArchive) => Ordering::Less,
(EntryKind::ZipArchive, EntryKind::Directory) => Ordering::Greater,
let kind_order = match (
left.kind == EntryKind::Directory,
right.kind == EntryKind::Directory,
) {
(true, false) => Ordering::Less,
(false, true) => Ordering::Greater,
_ => Ordering::Equal,
};
if kind_order != Ordering::Equal {
@ -73,10 +85,19 @@ fn apply_direction(order: Ordering, direction: SortDirection) -> Ordering {
}
}
pub fn is_zip_path(path: &Path) -> bool {
path.extension()
pub fn classify_file(path: &Path) -> EntryKind {
let extension = path
.extension()
.and_then(|extension| extension.to_str())
.is_some_and(|extension| extension.eq_ignore_ascii_case("zip"))
.map(str::to_ascii_lowercase);
match extension.as_deref() {
Some("zip") => EntryKind::ZipArchive,
Some("jpg" | "jpeg" | "png" | "webp" | "gif" | "bmp" | "avif") => EntryKind::Image,
Some("mp4" | "m4v" | "mkv" | "webm" | "mov" | "avi" | "mpeg" | "mpg" | "ogv") => {
EntryKind::Video
}
_ => EntryKind::OtherFile,
}
}
pub fn natural_cmp(left: &str, right: &str) -> Ordering {
@ -162,8 +183,17 @@ mod tests {
#[test]
fn zip_extension_is_case_insensitive() {
assert!(is_zip_path(Path::new("comic.ZIP")));
assert!(!is_zip_path(Path::new("comic.cbz")));
assert_eq!(classify_file(Path::new("comic.ZIP")), EntryKind::ZipArchive);
assert_ne!(classify_file(Path::new("comic.cbz")), EntryKind::ZipArchive);
}
#[test]
fn classifies_common_media_extensions_case_insensitively() {
assert_eq!(classify_file(Path::new("photo.JPG")), EntryKind::Image);
assert_eq!(classify_file(Path::new("animation.webp")), EntryKind::Image);
assert_eq!(classify_file(Path::new("movie.MP4")), EntryKind::Video);
assert_eq!(classify_file(Path::new("movie.mkv")), EntryKind::Video);
assert_eq!(classify_file(Path::new("notes.txt")), EntryKind::OtherFile);
}
#[test]