Files · Items: one icon map, file icon, file row and file grid

The crate had two maps from a file's name to its icon, in chat and in the
file tree, and they disagreed. One map now lives in primitives, over the
Lucide file-* icons, and chat, agent, the file tree and the directory
listing use it. FileIcon draws it for a file or a folder. FileItem is a
file's row, a ListItem with its size and when it changed. FileList is the
directory listing. FileGrid lays tiles in the order given, with a cursor
seeded from the owner's pick: arrows by tile and by row, Home, End, Enter
and a double press to open. The count of what fits a width has one home,
layout's columns_for, and fit builds on it.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-26 19:40:10 -04:00
1 parent e75171c995
commit a846e10847
36 files changed
+1024 -77

No files matched your search

+1 -2
View File
@@ -5,13 +5,12 @@ use gpui::{
Styled, Window, div, relative,
};
use super::media::file_icon;
use crate::{
buttons::{ButtonVariant, IconButton},
data_display::Tag,
documents::source,
forms::{Pick, Run},
primitives::{Icon, IconName, Image},
primitives::{Icon, IconName, Image, file_icon},
theme::{ActiveTheme, AvatarSize, ControlSize, IconSize, Radius, TextSize},
typography::{Ellipsis, format::file_size},
};
+1 -23
View File
@@ -10,7 +10,7 @@ use crate::{
buttons::{ButtonVariant, IconButton},
documents::source,
forms::{Pick, Run},
primitives::{Icon, IconName, Image},
primitives::{Icon, IconName, Image, file_icon},
theme::{ActiveTheme, AvatarSize, ContainerSize, IconSize, Radius, TextSize},
typography::{Ellipsis, format::file_size},
};
@@ -205,16 +205,6 @@ impl RenderOnce for ImageGrid {
}
}
/// The icon a file's name suggests.
pub(crate) fn file_icon(name: &str) -> IconName {
let extension = name.rsplit_once('.').map(|(_, ext)| ext.to_lowercase());
match extension.as_deref() {
Some("png" | "jpg" | "jpeg" | "gif" | "webp" | "svg" | "heic") => IconName::Image,
Some("pdf" | "md" | "txt" | "doc" | "docx" | "rtf" | "pages") => IconName::FileText,
_ => IconName::File,
}
}
/// A file in a message: its kind's icon, its name and size, and a way to download it.
#[derive(IntoElement)]
pub struct FileMessage {
@@ -412,15 +402,3 @@ impl RenderOnce for LinkPreviewCard {
}))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_file_name_picks_its_icon() {
assert_eq!(file_icon("lift.PNG"), IconName::Image);
assert_eq!(file_icon("notes.md"), IconName::FileText);
assert_eq!(file_icon("archive"), IconName::File);
}
}
-1
View File
@@ -28,7 +28,6 @@ pub use code::CodeBlock;
pub use composer::{AttachmentButton, DragDropOverlay, InputHint, PromptInput, SendButton};
pub use conversations::{Conversation, ConversationItem, ConversationList, new_chat_button};
pub use list::{DateSeparator, MessageList, ScrollToBottomButton};
pub(crate) use media::file_icon;
pub use media::{FileMessage, ImageGrid, ImageMessage, LinkPreviewCard};
pub use message::{
ChatContainer, MessageAvatar, MessageBubble, MessageFooter, MessageHeader, Role,
+1 -2
View File
@@ -7,13 +7,12 @@ use gpui::{
};
use jiff::Timestamp;
use super::media::file_icon;
use crate::{
buttons::{Button, ButtonVariant, IconButton},
data_display::Meter,
forms::{CheckState, Checkbox, Choice, OnFlag, OnValue, Pick, RadioGroup, Run},
overlays::Dialog,
primitives::{FocusRing, Icon, IconName},
primitives::{FocusRing, Icon, IconName, file_icon},
theme::{ActiveTheme, ControlSize, IconSize, Radius, TextSize},
typography::{Ellipsis, RelativeTime, format::file_size, tabular},
};