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();