feat: add MIME-aware file icons - #28
Conversation
|
Warning Rate limit exceeded@Athemis has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 35 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThese changes add a MIME-based icon utility and integrate thumbnail loading state into the attachments UI: thumbnails are tracked as in-flight, cached or failed thumbnails influence rendering, and MIME-appropriate placeholder icons are shown in a dedicated thumbnail rect when needed. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/ui/components/attachments.rs (1)
259-272: Acknowledged. The thumbnail rendering logic is sound.The implementation correctly handles three scenarios: cached thumbnails, pending image loads, and non-image placeholders. The allocated space ensures consistent layout.
One consideration for future refinement: images awaiting their first thumbnail load display blank space until the texture arrives. Showing a temporary placeholder icon during initial load would provide more immediate visual feedback. However, the current approach is acceptable and allows the thumbnail to appear without a distracting icon swap.
src/utils/file_icons.rs (2)
31-140: A thorough and methodical implementation, Commander.The icon selection logic comprehensively covers media types, document formats, and programming languages. The cascading checks prioritize MIME types while providing extension-based fallbacks, and the case-insensitive matching prevents user frustration.
One minor observation: OpenDocument formats (ODS, ODP) return
FILE_TEXTrather than spreadsheet or presentation icons. If more specific icons are available in the Phosphor set, considerFILE_XLSfor ODS andFILE_PPTfor ODP to better convey their purpose. However, the current choice is acceptable.The Rust compiler will verify all Phosphor icon constants at build time, providing assurance that no typos will reach production.
142-163: A capable archive detection routine, but documentation would serve us well.The function correctly identifies archive formats through MIME types, extensions, and composite suffixes like
.tar.gz. The composite extension checking is particularly valuable sincePath::extension()would miss these.Consider adding a rustdoc comment explaining the rationale for checking filename suffixes, as this aids maintainability. For example:
/// Detect archive files by MIME, extension, and composite suffixes. /// /// Composite suffixes like `.tar.gz` are checked via filename since /// `Path::extension()` would only detect `gz`. fn is_archive_mime(mime: &str, ext: &str, fname: &str) -> bool {Additionally, for defensive robustness against MIME detection failures, consider adding extension checks for common formats already covered by MIME:
|| ext == "rar" || ext == "7z" + || ext == "zip" + || ext == "tar" + || ext == "gz" || ext == "xz" || ext == "zst" || ext == "bz2"This provides a fallback path when MIME detection is unavailable or incorrect.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/ui/components/attachments.rs(3 hunks)src/utils/file_icons.rs(1 hunks)src/utils/mod.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: Entry point atsrc/main.rswhich callsapp::run()to start eframe/egui. Add SPDX headers on all source files:SPDX-License-Identifier: MITplus one or moreSPDX-FileCopyrightTextlines naming actual authors.
Commands (PickFiles,HashFile,LoadThumbnail,SaveArchive) perform side-effects viarun_commandand emit follow-up messages back into the update loop for re-rendering.
Follow rustfmt defaults with 4-space indent and trailing commas where appropriate; runcargo fmtbefore committing.
Usesnake_casefor functions, variables, and filenames; useCamelCasefor types; keep module files small and focused.
Use English language within the codebase.
Use code comments sparingly to explain intent, invariants, or non-obvious control flow; avoid restating what the code already makes clear.
Use rustdoc with///for public items and//!for module-level docs; start with one-line summary ending with period; structure details with#headings (e.g.,# Examples,# Errors,# Panics,# Safety,# Performance).
Include small, runnable examples markedno_run/ignorein rustdoc when side effects exist; keep examples minimal and dependency-free.
In rustdoc, explain invariants, panics, and error cases explicitly; prefer present tense and describe behavior, not intent.
Use intra-doc links in rustdoc like[`TypeName`]or[`module::function`]; disambiguate with full paths when needed.
Document private helpers in rustdoc when it aids maintainers; keep explanations concise.
Files:
src/utils/file_icons.rssrc/utils/mod.rssrc/ui/components/attachments.rs
{**/*.rs,tests/**/*.rs}
📄 CodeRabbit inference engine (AGENTS.md)
Use
cargo testfor unit and integration coverage; colocate simple unit tests with modules and broader scenarios undertests/. Name tests after behavior (e.g.,submits_trimmed_input) and keep them deterministic.
Files:
src/utils/file_icons.rssrc/utils/mod.rssrc/ui/components/attachments.rs
{src/ui/**/*.rs,src/ui/components/**/*.rs}
📄 CodeRabbit inference engine (AGENTS.md)
{src/ui/**/*.rs,src/ui/components/**/*.rs}: UI components insrc/ui/andsrc/ui/components/*must remain side-effect free and emit messages only; all validation and state transitions belong insrc/mvu/or model/logic modules; IO happens only in commands executed byrun_command.
Use Phosphor icons viaegui_phosphor::regular::NAME(withRichTextor button labels) instead of embedding SVGs. The font is registered insrc/main.rs. Keep icon+text buttons short usingformat!("{} Label", icon)and reuse existing helpers insrc/ui.rs.
Files:
src/ui/components/attachments.rs
src/ui/components/attachments.rs
📄 CodeRabbit inference engine (AGENTS.md)
src/ui/components/attachments.rsimplements attachments panel with list, thumbnails, inline filename editing; computessanitized_nameusingsanitize_component; shows WARNING icon on sanitized mismatch; emits commands for file picking/hashing/thumbnails; sanitizes and dedupes edited names.
Files:
src/ui/components/attachments.rs
{src/ui/**/*.rs,src/app/**/*.rs}
📄 CodeRabbit inference engine (AGENTS.md)
No external assets are fetched at runtime; all UI is generated by egui at runtime.
Files:
src/ui/components/attachments.rs
{src/mvu/**/*.rs,src/ui/**/*.rs}
📄 CodeRabbit inference engine (AGENTS.md)
File dialog operations use
rfdcrate for cross-platform native dialogs.
Files:
src/ui/components/attachments.rs
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to src/ui/components/attachments.rs : `src/ui/components/attachments.rs` implements attachments panel with list, thumbnails, inline filename editing; computes `sanitized_name` using `sanitize_component`; shows WARNING icon on sanitized mismatch; emits commands for file picking/hashing/thumbnails; sanitizes and dedupes edited names.
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to {src/ui/**/*.rs,src/ui/components/**/*.rs} : Use Phosphor icons via `egui_phosphor::regular::NAME` (with `RichText` or button labels) instead of embedding SVGs. The font is registered in `src/main.rs`. Keep icon+text buttons short using `format!("{} Label", icon)` and reuse existing helpers in `src/ui.rs`.
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to {src/ui/**/*.rs,src/ui/components/**/*.rs} : Use Phosphor icons via `egui_phosphor::regular::NAME` (with `RichText` or button labels) instead of embedding SVGs. The font is registered in `src/main.rs`. Keep icon+text buttons short using `format!("{} Label", icon)` and reuse existing helpers in `src/ui.rs`.
Applied to files:
src/utils/file_icons.rssrc/utils/mod.rssrc/ui/components/attachments.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to {src/mvu/**/*.rs,src/ui/**/*.rs} : File dialog operations use `rfd` crate for cross-platform native dialogs.
Applied to files:
src/utils/file_icons.rssrc/utils/mod.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to src/ui/components/attachments.rs : `src/ui/components/attachments.rs` implements attachments panel with list, thumbnails, inline filename editing; computes `sanitized_name` using `sanitize_component`; shows WARNING icon on sanitized mismatch; emits commands for file picking/hashing/thumbnails; sanitizes and dedupes edited names.
Applied to files:
src/utils/file_icons.rssrc/utils/mod.rssrc/ui/components/attachments.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to src/logic/eln.rs : `src/logic/eln.rs` builds and writes ELN RO-Crate metadata, generates suggested archive names, and conforms to RO-Crate 1.2 and ELN File Format specification; uses pre-sanitized names from attachments; has no UI dependencies.
Applied to files:
src/utils/file_icons.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to **/*.rs : Use rustdoc with `///` for public items and `//!` for module-level docs; start with one-line summary ending with period; structure details with `#` headings (e.g., `# Examples`, `# Errors`, `# Panics`, `# Safety`, `# Performance`).
Applied to files:
src/utils/file_icons.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Organize code: Pure data in `src/models/`; business/format logic in `src/logic/eln.rs`; MVU kernel in `src/mvu/`; UI composition in `src/ui/`; components in `src/ui/components/`; utilities in `src/utils/`.
Applied to files:
src/utils/mod.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to {src/logic/**/*.rs,tests/**/*.rs} : Test business logic in `src/logic/eln.rs` independently of UI; mock file system operations where appropriate.
Applied to files:
src/utils/mod.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to {src/ui.rs,src/logic/eln.rs} : Separate UI concerns in `src/ui.rs` from business logic in `src/logic/eln.rs` for maintainability and testability.
Applied to files:
src/utils/mod.rs
📚 Learning: 2025-12-03T16:16:45.376Z
Learnt from: CR
Repo: Athemis/ELNPack PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T16:16:45.376Z
Learning: Applies to src/ui.rs : UI strings live directly in `src/ui.rs` within the egui code; prefer short, actionable labels.
Applied to files:
src/ui/components/attachments.rs
🧬 Code graph analysis (2)
src/utils/mod.rs (2)
src/utils/sanitize_component.rs (1)
sanitize_component(26-119)src/utils/file_icons.rs (1)
icon_for(13-140)
src/ui/components/attachments.rs (2)
src/utils/file_icons.rs (1)
icon_for(13-140)src/utils/sanitize_component.rs (1)
sanitize_component(26-119)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (rust)
🔇 Additional comments (7)
src/utils/mod.rs (2)
6-6: Engage. The new module integration proceeds smoothly.The public module declaration and re-export are properly structured. The documentation, while brief, adequately conveys the function's purpose in the manner befitting a utility module index.
Also applies to: 10-11
15-15: Make it so. The sanitize_component re-export is correctly positioned.The public re-export maintains consistency with the module's API structure.
src/ui/components/attachments.rs (3)
14-14: Proceed. The import statement is properly configured.The addition of
icon_forto the existing utility imports is logically sound and maintains module cohesion.
251-252: Excellent work. The icon determination is logically positioned.Computing the icon once per attachment and storing it for subsequent use demonstrates sound engineering practice.
523-543: Well done, Number One. The placeholder rendering function is exemplary.The implementation achieves visual clarity through centered icon text with appropriate scaling and a subtle outline. The color and styling choices integrate seamlessly with egui's theme system.
src/utils/file_icons.rs (2)
1-9: Engage. The module header and documentation meet Starfleet standards.The SPDX headers are properly declared, and the module documentation clearly articulates the utility's purpose and design philosophy. The UI-agnostic approach demonstrates sound architectural thinking.
12-29: Proceed. The parameter extraction is executed with precision.The MIME type normalization properly handles charset parameters, and the extension and filename extraction employ robust null-safe patterns. The case-insensitive matching prevents subtle errors.
Summary
Testing
cargo fmtcargo clippy --all-targets --all-featurescargo testcargo doc --no-depsPlatforms exercised (mark all that apply):
Screenshots (if UI changes)
Docs/metadata
Notes for reviewers
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.