diff --git a/frontend/src/components/common/icons.tsx b/frontend/src/components/common/icons.tsx index 5f719c83..6a324539 100644 --- a/frontend/src/components/common/icons.tsx +++ b/frontend/src/components/common/icons.tsx @@ -57,6 +57,7 @@ export function FolderTypeIcon({ style={{ transform: isOpen ? "rotate(90deg)" : "", transition: "transform 0.15s ease-in-out", + flexShrink: 0, }} {...props} /> diff --git a/frontend/src/components/frontpage/statsCard.tsx b/frontend/src/components/frontpage/statsCard.tsx index 0d3240bf..ddead836 100644 --- a/frontend/src/components/frontpage/statsCard.tsx +++ b/frontend/src/components/frontpage/statsCard.tsx @@ -272,7 +272,7 @@ export function CardHeader({ paddingLeft: reverse ? 1 : 4, paddingRight: reverse ? 4 : 1, display: "flex", - alignItems: "flex-start", + alignItems: "flex-end", justifyContent: "space-between", zIndex: 1, flexDirection: reverse ? "row-reverse" : "row", diff --git a/frontend/src/components/inbox/cards/inboxCard.tsx b/frontend/src/components/inbox/cards/inboxCard.tsx new file mode 100644 index 00000000..2b56653b --- /dev/null +++ b/frontend/src/components/inbox/cards/inboxCard.tsx @@ -0,0 +1,164 @@ +import { useMemo } from "react"; +import { Box, Card, CardContent, Tooltip, Typography } from "@mui/material"; + +import { useConfig } from "@/api/config"; +import { InboxTypeIcon } from "@/components/common/icons"; +import { CardHeader } from "@/components/frontpage/statsCard"; +import { FolderActionDesktopBar } from "@/components/inbox/actions"; +import { + FolderComponent, + GridWrapper, + SelectedStats, +} from "@/components/inbox/fileTree"; +import { Folder } from "@/pythonTypes"; + +export function InboxCard({ folder }: { folder: Folder }) { + const config = useConfig(); + + // configuration for this inbox folder + const folderConfig = useMemo<(typeof config)["gui"]["inbox"]["folders"][0]>(() => { + const fc = Object.entries(config.gui.inbox.folders).find( + ([_k, v]) => v.path === folder.full_path + ); + + return fc + ? fc[1] + : { + name: "Inbox", + autotag: false, + path: folder.full_path, + }; + }, [config, folder.full_path]); + + const innerFolders = useMemo(() => { + // Filter out folders that are not albums or files + return folder.children.filter((f) => f.type === "directory"); + }, [folder.children]); + + const threshold = folderConfig.auto_threshold ?? config.match.strong_rec_thresh; + + let tooltip: string; + switch (folderConfig.autotag) { + case "auto": + tooltip = + "Automatic tagging and import enabled. " + + (1 - threshold) * 100 + + "% threshold."; + break; + case "preview": + tooltip = "Automatic tagging enabled, but no import."; + break; + case "bootleg": + tooltip = "Import as-is, and split albums by meta-data."; + break; + default: + tooltip = "No automatic tagging or import enabled."; + break; + } + + return ( + + + + + } + dividerPos="70%" + color="secondary.main" + > + + {/* file path */} + + {folderConfig.path + .split("/") + .filter(Boolean) + .map((segment, idx, arr) => ( + + {`/ ${segment}${idx === arr.length - 1 && folderConfig.path.endsWith("/") ? " /" : ""}`} + + ))} + + + {/* inbox name */} + + {folderConfig.name} + + + + + + {/* Only show inner folders */} + {innerFolders.map((innerFolder) => ( + + ))} + {innerFolders.length === 0 && ( + + No folders in this inbox. + + )} + + + + + {/* */} + + ); +} diff --git a/frontend/src/routes/inbox/index.tsx b/frontend/src/routes/inbox/index.tsx index d3f5dcdf..b3511454 100644 --- a/frontend/src/routes/inbox/index.tsx +++ b/frontend/src/routes/inbox/index.tsx @@ -8,22 +8,18 @@ import { TerminalIcon, Trash2Icon, } from "lucide-react"; -import { useMemo, useState } from "react"; +import { useState } from "react"; import { Box, BoxProps, - Card, - CardContent, DialogContent, IconButton, - Tooltip, Typography, useTheme, } from "@mui/material"; import { useSuspenseQuery } from "@tanstack/react-query"; import { createFileRoute } from "@tanstack/react-router"; -import { useConfig } from "@/api/config"; import { inboxQueryOptions } from "@/api/inbox"; import { MatchChip, StyledChip } from "@/components/common/chips"; import { Dialog } from "@/components/common/dialogs"; @@ -31,21 +27,12 @@ import { FileTypeIcon, FolderStatusIcon, FolderTypeIcon, - InboxTypeIcon, PenaltyTypeIcon, SourceTypeIcon, } from "@/components/common/icons"; import { PageWrapper } from "@/components/common/page"; -import { CardHeader } from "@/components/frontpage/statsCard"; -import { - FolderActionDesktopBar, - RefreshAllFoldersButton, -} from "@/components/inbox/actions"; -import { - FolderComponent, - GridWrapper, - SelectedStats, -} from "@/components/inbox/fileTree"; +import { RefreshAllFoldersButton } from "@/components/inbox/actions"; +import { InboxCard } from "@/components/inbox/cards/inboxCard"; import { FolderSelectionProvider } from "@/components/inbox/folderSelectionContext"; import { Folder } from "@/pythonTypes"; @@ -163,133 +150,6 @@ function PageHeader({ inboxes, ...props }: { inboxes: Folder[] } & BoxProps) { ); } -function InboxCard({ folder }: { folder: Folder }) { - const config = useConfig(); - - // configuration for this inbox folder - const folderConfig = useMemo<(typeof config)["gui"]["inbox"]["folders"][0]>(() => { - const fc = Object.entries(config.gui.inbox.folders).find( - ([_k, v]) => v.path === folder.full_path - ); - - return fc - ? fc[1] - : { - name: "Inbox", - autotag: false, - path: folder.full_path, - }; - }, [config, folder.full_path]); - - const innerFolders = useMemo(() => { - // Filter out folders that are not albums or files - return folder.children.filter((f) => f.type === "directory"); - }, [folder.children]); - - const threshold = folderConfig.auto_threshold ?? config.match.strong_rec_thresh; - - let tooltip: string; - switch (folderConfig.autotag) { - case "auto": - tooltip = - "Automatic tagging and import enabled. " + - (1 - threshold) * 100 + - "% threshold."; - break; - case "preview": - tooltip = "Automatic tagging enabled, but no import."; - break; - case "bootleg": - tooltip = "Import as-is, and split albums by meta-data."; - break; - default: - tooltip = "No automatic tagging or import enabled."; - break; - } - - return ( - - - - - } - dividerPos="70%" - color="secondary.main" - > - - - {folderConfig.path.replaceAll("/", " / ")} - - - {folderConfig.name} - - - - - - {/* Only show inner folders */} - {innerFolders.map((innerFolder) => ( - - ))} - {innerFolders.length === 0 && ( - - No folders in this inbox. - - )} - - - - - {/* */} - - ); -} - /** Description of the inbox page, shown as modal on click */ function InfoDescription() { const theme = useTheme();