mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2025-12-11 20:15:30 +01:00
Refactor file handling in Explorer component
- Updated file type checks from `file.kind.type` to `file.kind` for consistency across various components in the Explorer views. - Enhanced the `Thumb` component to conditionally hide the icon based on thumbnail loading status. - Adjusted the `HeroStats` component for improved readability and structure. - Added a new `iconScale` prop to the `FileInspector` component's thumbnail for better visual scaling.
This commit is contained in:
parent
553fadd2d4
commit
008d05414a
@ -20,3 +20,4 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -70,3 +70,4 @@ enum VideoMediaData {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -49,3 +49,4 @@ enum Entries {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -10,3 +10,4 @@ pub use output::LibraryOpenOutput;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -124,3 +124,4 @@ mod tests {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -16,3 +16,4 @@ pub struct VolumeTrackInput {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -13,3 +13,4 @@ pub struct VolumeUntrackInput {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
crates/log-analyzer/.gitignore
vendored
1
crates/log-analyzer/.gitignore
vendored
@ -7,3 +7,4 @@ analysis.md
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -41,3 +41,4 @@ required-features = ["cli"]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -52,3 +52,4 @@ fn main() -> Result<()> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -19,3 +19,4 @@ pub fn export_json(templates: &[Template], groups: &[LogGroup]) -> Result<String
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -241,3 +241,4 @@ mod tests {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -106,3 +106,4 @@ mod tests {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -147,7 +147,8 @@ export const Thumb = memo(function Thumb({
|
||||
alt=""
|
||||
className={clsx(
|
||||
"object-contain transition-opacity",
|
||||
thumbLoaded && "opacity-0",
|
||||
// Only hide icon if we actually have a thumbnail that loaded
|
||||
thumbLoaded && thumbnailSrc && "opacity-0",
|
||||
)}
|
||||
style={{
|
||||
width: iconSize,
|
||||
@ -191,16 +192,21 @@ export function Icon({
|
||||
size?: number;
|
||||
className?: string;
|
||||
}) {
|
||||
const kindCapitalized = file.content_identity?.kind
|
||||
? file.content_identity.kind.charAt(0).toUpperCase() +
|
||||
file.content_identity.kind.slice(1)
|
||||
: "Document";
|
||||
// This is jank and has to be done in several places. Ideally a util function.
|
||||
const fileKind =
|
||||
file?.content_identity?.kind && file.content_identity.kind !== "unknown"
|
||||
? file.content_identity.kind
|
||||
: file.kind === "File"
|
||||
? file.extension || "File"
|
||||
: file.kind;
|
||||
// this too
|
||||
const kindCapitalized = fileKind.charAt(0).toUpperCase() + fileKind.slice(1);
|
||||
|
||||
const icon = getIcon(
|
||||
kindCapitalized,
|
||||
true, // Dark theme
|
||||
file.kind.type === "File" ? file.kind.data?.extension : undefined,
|
||||
file.kind.type === "Directory",
|
||||
file.extension,
|
||||
file.kind === "Directory",
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -67,7 +67,7 @@ export function Column({ path, isActive, onNavigate }: ColumnProps) {
|
||||
icon: FolderOpen,
|
||||
label: "Open",
|
||||
onClick: (file: File) => {
|
||||
if (file.kind.type === "Directory") {
|
||||
if (file.kind === "Directory") {
|
||||
onNavigate(file.sd_path);
|
||||
}
|
||||
},
|
||||
|
||||
@ -40,7 +40,7 @@ export function ColumnItem({
|
||||
>
|
||||
<FileComponent.Thumb file={file} size={20} />
|
||||
<span className="text-sm truncate flex-1">{file.name}</span>
|
||||
{file.kind.type === "Directory" && (
|
||||
{file.kind === "Directory" && (
|
||||
<svg
|
||||
className="size-3 text-ink-dull"
|
||||
fill="none"
|
||||
|
||||
@ -70,7 +70,7 @@ export const FileCard = memo(function FileCard({ file, fileIndex, allFiles, sele
|
||||
icon: FolderOpen,
|
||||
label: "Open",
|
||||
onClick: () => {
|
||||
if (file.kind.type === "Directory") {
|
||||
if (file.kind === "Directory") {
|
||||
setCurrentPath(file.sd_path);
|
||||
} else {
|
||||
console.log("Open file:", file.name);
|
||||
@ -78,7 +78,7 @@ export const FileCard = memo(function FileCard({ file, fileIndex, allFiles, sele
|
||||
}
|
||||
},
|
||||
keybind: "⌘O",
|
||||
condition: () => file.kind.type === "Directory" || file.kind.type === "File",
|
||||
condition: () => file.kind === "Directory" || file.kind === "File",
|
||||
},
|
||||
{
|
||||
icon: MagnifyingGlass,
|
||||
@ -308,7 +308,7 @@ export const FileCard = memo(function FileCard({ file, fileIndex, allFiles, sele
|
||||
type: "submenu",
|
||||
icon: FileText,
|
||||
label: "Document Processing",
|
||||
condition: () => ["pdf", "doc", "docx"].includes(file.kind.type === "File" ? file.kind.data?.extension || "" : ""),
|
||||
condition: () => file.kind === "File" && ["pdf", "doc", "docx"].includes(file.extension || ""),
|
||||
submenu: [
|
||||
{
|
||||
icon: TextAa,
|
||||
@ -425,7 +425,7 @@ export const FileCard = memo(function FileCard({ file, fileIndex, allFiles, sele
|
||||
};
|
||||
|
||||
const handleDoubleClick = () => {
|
||||
if (file.kind.type === "Directory") {
|
||||
if (file.kind === "Directory") {
|
||||
setCurrentPath(file.sd_path);
|
||||
}
|
||||
};
|
||||
|
||||
@ -24,7 +24,7 @@ export function FileRow({ file, fileIndex, allFiles }: FileRowProps) {
|
||||
};
|
||||
|
||||
const handleDoubleClick = () => {
|
||||
if (file.kind.type === "Directory") {
|
||||
if (file.kind === "Directory") {
|
||||
setCurrentPath(file.sd_path);
|
||||
}
|
||||
};
|
||||
@ -60,7 +60,7 @@ export function FileRow({ file, fileIndex, allFiles }: FileRowProps) {
|
||||
{formatRelativeTime(file.modified_at)}
|
||||
</div>
|
||||
<div className="w-24 text-sm text-ink-dull">
|
||||
{file.kind.type === "File" ? file.kind.data?.extension || "—" : "Folder"}
|
||||
{file.kind === "File" ? file.extension || "—" : "Folder"}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -11,7 +11,7 @@ interface SizeCircleProps {
|
||||
|
||||
// Get file extension or type
|
||||
function getFileType(file: File): string {
|
||||
if (file.kind.type === "Directory") return "Folder";
|
||||
if (file.kind === "Directory") return "Folder";
|
||||
|
||||
const name = file.name;
|
||||
const lastDot = name.lastIndexOf(".");
|
||||
@ -22,7 +22,7 @@ function getFileType(file: File): string {
|
||||
|
||||
// Get color based on file type
|
||||
function getFileColor(file: File): string {
|
||||
if (file.kind.type === "Directory") return "bg-blue-500";
|
||||
if (file.kind === "Directory") return "bg-blue-500";
|
||||
|
||||
const ext = file.name.split(".").pop()?.toLowerCase() || "";
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ function getTailwindColor(className: string): string {
|
||||
}
|
||||
|
||||
function getFileColorClass(file: File): string {
|
||||
if (file.kind.type === "Directory") return "bg-accent";
|
||||
if (file.kind === "Directory") return "bg-accent";
|
||||
|
||||
const ext = file.name.split(".").pop()?.toLowerCase() || "";
|
||||
|
||||
@ -71,7 +71,7 @@ function getFileColor(file: File): string {
|
||||
}
|
||||
|
||||
function getFileType(file: File): string {
|
||||
if (file.kind.type === "Directory") return "Folder";
|
||||
if (file.kind === "Directory") return "Folder";
|
||||
|
||||
const name = file.name;
|
||||
const lastDot = name.lastIndexOf(".");
|
||||
@ -348,7 +348,7 @@ export function SizeView() {
|
||||
}
|
||||
|
||||
// Navigate if directory
|
||||
if (d.data.file.kind.type === "Directory") {
|
||||
if (d.data.file.kind === "Directory") {
|
||||
setCurrentPathRef.current(d.data.file.sd_path);
|
||||
}
|
||||
})
|
||||
|
||||
@ -59,3 +59,4 @@ export function useJobDispatch() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -137,6 +137,7 @@ function OverviewTab({ file }: { file: File }) {
|
||||
<FileComponent.Thumb
|
||||
file={file}
|
||||
size={200}
|
||||
iconScale={0.6}
|
||||
className="w-full max-w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -28,15 +28,15 @@ export function HeroStats({
|
||||
deviceCount,
|
||||
uniqueContentCount,
|
||||
}: HeroStatsProps) {
|
||||
const usagePercent = totalStorage > 0 ? (usedStorage / totalStorage) * 100 : 0;
|
||||
const usagePercent =
|
||||
totalStorage > 0 ? (usedStorage / totalStorage) * 100 : 0;
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
<div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="bg-app-box border border-app-line rounded-2xl p-8"
|
||||
>
|
||||
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
{/* Total Storage */}
|
||||
<StatCard
|
||||
@ -45,7 +45,8 @@ export function HeroStats({
|
||||
value={formatBytes(totalStorage)}
|
||||
subtitle={
|
||||
<>
|
||||
<span className="text-accent">{formatBytes(usedStorage)}</span> used
|
||||
<span className="text-accent">{formatBytes(usedStorage)}</span>{" "}
|
||||
used
|
||||
</>
|
||||
}
|
||||
progress={usagePercent}
|
||||
@ -80,8 +81,7 @@ export function HeroStats({
|
||||
badge="PREVIEW"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -133,7 +133,6 @@ function StatCard({
|
||||
<div className="text-xs text-ink-dull mb-1">{label}</div>
|
||||
<div className="text-xs text-ink-faint">{subtitle}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user