Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ jobs:
with:
submodules: recursive

- name: Install system dependencies (macOS only)
run: brew install ffmpeg

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
Expand Down Expand Up @@ -98,7 +101,30 @@ jobs:

- name: Install system dependencies (Linux only)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavfilter-dev libavdevice-dev pkg-config

- name: Install system dependencies (macOS only)
if: runner.os == 'macOS'
run: brew install ffmpeg

- name: Cache vcpkg (Windows only)
if: runner.os == 'Windows'
uses: actions/cache@v4
with:
path: C:\vcpkg
key: ${{ runner.os }}-vcpkg-ffmpeg-v3
restore-keys: |
${{ runner.os }}-vcpkg-ffmpeg-

- name: Install system dependencies (Windows only)
if: runner.os == 'Windows'
run: |
if (-not (Test-Path "C:\vcpkg")) {
git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
}
C:\vcpkg\vcpkg.exe install ffmpeg:x64-windows
echo "VCPKG_ROOT=C:\vcpkg" >> $env:GITHUB_ENV

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
Expand All @@ -108,12 +134,16 @@ jobs:

- name: Run tests (Linux)
if: runner.os == 'Linux'
env:
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
run: mold -run cargo test
- name: Run tests (macOS)
if: runner.os == 'macOS'
run: cargo test
- name: Run tests (Windows)
if: runner.os == 'Windows'
env:
VCPKG_ROOT: C:\vcpkg
# disable terminal on windows
run: cargo test --no-default-features

Expand All @@ -131,12 +161,14 @@ jobs:
uses: dtolnay/rust-toolchain@stable

- name: Install system dependencies (Linux only)
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavfilter-dev libavdevice-dev pkg-config

- name: Cache dependencies
uses: Swatinem/rust-cache@v2

- name: Build release binary
env:
PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig
run: |
mold -run cargo build --release
cd target/release
Expand Down Expand Up @@ -168,6 +200,9 @@ jobs:
with:
submodules: recursive

- name: Install system dependencies (macOS only)
run: brew install ffmpeg

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

Expand Down Expand Up @@ -263,13 +298,33 @@ jobs:
with:
submodules: recursive

- name: Cache vcpkg (Windows only)
if: runner.os == 'Windows'
uses: actions/cache@v4
with:
path: C:\vcpkg
key: ${{ runner.os }}-vcpkg-ffmpeg-v3
restore-keys: |
${{ runner.os }}-vcpkg-ffmpeg-

- name: Install system dependencies (Windows only)
run: |
if (-not (Test-Path "C:\vcpkg")) {
git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
}
C:\vcpkg\vcpkg.exe install ffmpeg:x64-windows
echo "VCPKG_ROOT=C:\vcpkg" >> $env:GITHUB_ENV

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Cache dependencies
uses: Swatinem/rust-cache@v2

- name: Build release binary
env:
VCPKG_ROOT: C:\vcpkg
run: |
cargo build --no-default-features --release
cd target\release
Expand Down
80 changes: 80 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ bzip2 = "0.6"
image = { version = "0" }
kamadak-exif = "0"

# video handling
ffmpeg-next = "7.1.0"

# for pdf rendering
pdf_render = { git = "https://github.com/houqp/pdf_render.git", rev = "00b907936e45d904f958197fa6039320d0ac098d", features = [
"embed",
Expand Down
44 changes: 44 additions & 0 deletions src/models/preview_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,34 @@ impl std::fmt::Debug for ImageMeta {
}
}

/// Metadata for video files
#[derive(Clone)]
pub struct VideoMeta {
/// Video title (usually filename)
pub title: String,
/// Video metadata (key-value pairs)
pub metadata: HashMap<String, String>,
/// Video thumbnail image
pub thumbnail: egui::widgets::ImageSource<'static>,
/// Keep the texture handle alive to prevent GPU texture from being freed
pub _texture_handle: Option<egui::TextureHandle>,
}

// Manual implementation of Debug for VideoMeta since TextureHandle doesn't implement Debug
impl std::fmt::Debug for VideoMeta {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("VideoMeta")
.field("title", &self.title)
.field("metadata", &self.metadata)
.field("thumbnail", &"ImageSource")
.field(
"_texture_handle",
&self._texture_handle.as_ref().map(|_| "TextureHandle"),
)
.finish()
}
}

/// Represents different types of preview content that can be displayed in the right panel
#[derive(Clone, Debug)]
pub enum PreviewContent {
Expand All @@ -97,6 +125,8 @@ pub enum PreviewContent {
},
/// Image content with metadata
Image(ImageMeta),
/// Video content with metadata and thumbnail
Video(VideoMeta),
/// Zip file content with a list of entries
Zip(Vec<ZipEntry>),
/// Tar file content with a list of entries (supports both compressed and uncompressed)
Expand Down Expand Up @@ -182,6 +212,20 @@ impl PreviewContent {
})
}

/// Creates a new video preview content with a texture handle for thumbnail
pub fn video(
title: impl Into<String>,
metadata: HashMap<String, String>,
texture: egui::TextureHandle,
) -> Self {
Self::Video(VideoMeta {
title: title.into(),
metadata,
thumbnail: egui::widgets::ImageSource::from(&texture),
_texture_handle: Some(texture),
})
}

/// Creates a new zip preview content from a list of entries
#[must_use]
pub const fn zip(entries: Vec<ZipEntry>) -> Self {
Expand Down
15 changes: 15 additions & 0 deletions src/ui/popup/preview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use egui::Context;

pub mod doc;
pub mod image;
pub mod video;

/// Handle the `ShowFilePreview` shortcut action
/// This function was extracted from input.rs to reduce complexity
Expand Down Expand Up @@ -97,6 +98,10 @@ pub fn handle_show_file_preview(app: &mut Kiorg, _ctx: &egui::Context) {
// Show preview popup for image files
app.show_popup = Some(PopupType::Preview);
}
crate::ui::preview::video_extensions!() => {
// Show preview popup for video files
app.show_popup = Some(PopupType::Preview);
}
v => {
if let Some(syntax) = crate::ui::preview::text::find_syntax_from_path(path) {
match crate::ui::preview::text::load_full_text(path, Some(syntax.name.as_str())) {
Expand Down Expand Up @@ -186,6 +191,16 @@ pub fn show_preview_popup(ctx: &Context, app: &mut Kiorg) {
available_height,
);
}
PreviewContent::Video(video_meta) => {
// Use specialized popup video renderer
video::render_popup(
ui,
video_meta,
&app.colors,
available_width,
available_height,
);
}
PreviewContent::Pdf(pdf_meta) => {
// Use specialized PDF popup renderer with navigation
if let Some(path) = &selected_path {
Expand Down
Loading
Loading