mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): surface diff type badge in card title when file header is collapsed
Instead of forcing the per-file header open just to show the New file/Deleted badge (previous fix), keep the header collapsed when it would only repeat the card title, and show the badge in the diff card's title bar instead — both in the inline DiffMessage card and the expanded dialog. DIFF_TYPE_LABELS and the header-visibility check move into parseDiff.ts as shared helpers, and a new getDiffTitleBadge returns the badge label only for single-file diffs whose collapsed header has a notable change type — so the badge never renders in both places. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e3c9dfcfee
commit
0683e35d86
@@ -33,6 +33,14 @@ export function parseUnifiedDiff(content: string): ParsedDiffResult {
|
||||
}
|
||||
}
|
||||
|
||||
export const DIFF_TYPE_LABELS: Record<DiffType, string> = {
|
||||
add: "New file",
|
||||
copy: "Copied",
|
||||
delete: "Deleted",
|
||||
modify: "Modified",
|
||||
rename: "Renamed",
|
||||
};
|
||||
|
||||
export function getDiffFileLabel(
|
||||
file: FileData,
|
||||
fallbackFilePath?: string,
|
||||
@@ -47,6 +55,39 @@ export function getDiffFileLabel(
|
||||
return newPath || oldPath || fallbackFilePath || "diff";
|
||||
}
|
||||
|
||||
export function shouldShowDiffFileHeader(
|
||||
label: string,
|
||||
fileCount: number,
|
||||
fallbackFilePath?: string,
|
||||
): boolean {
|
||||
return fileCount > 1 || !fallbackFilePath || label !== fallbackFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Badge for the diff card's title bar. Set only when the diff is a single
|
||||
* file whose per-file header is collapsed (its label just repeats the card
|
||||
* title) and whose change type is notable — so "New file"/"Deleted" isn't
|
||||
* lost with the header.
|
||||
*/
|
||||
export function getDiffTitleBadge(
|
||||
content: string,
|
||||
fallbackFilePath?: string,
|
||||
): string | undefined {
|
||||
const { files } = parseUnifiedDiff(content);
|
||||
if (files.length !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const file = files[0];
|
||||
const label = getDiffFileLabel(file, fallbackFilePath);
|
||||
if (shouldShowDiffFileHeader(label, files.length, fallbackFilePath)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const diffType = normalizeDiffType(file.type);
|
||||
return diffType === "modify" ? undefined : DIFF_TYPE_LABELS[diffType];
|
||||
}
|
||||
|
||||
export function countDiffFileChanges(file: FileData) {
|
||||
let additions = 0;
|
||||
let deletions = 0;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from "react";
|
||||
import { FileDiff, Maximize2 } from "lucide-react";
|
||||
|
||||
import { getDiffTitleBadge } from "@/features/messages/lib/parseDiff";
|
||||
import { isSafeUrl } from "@/shared/lib/url";
|
||||
import { Button } from "@/shared/ui/button";
|
||||
import { useSmoothCorners } from "@/shared/ui/smoothCorners";
|
||||
@@ -39,6 +40,11 @@ export default function DiffMessage({
|
||||
|
||||
const safeRepoUrl = isSafeUrl(repoUrl) ? repoUrl : undefined;
|
||||
|
||||
const titleBadge = React.useMemo(
|
||||
() => getDiffTitleBadge(content, filePath),
|
||||
[content, filePath],
|
||||
);
|
||||
|
||||
const commitUrl =
|
||||
safeRepoUrl && commitSha ? `${safeRepoUrl}/commit/${commitSha}` : undefined;
|
||||
|
||||
@@ -54,6 +60,11 @@ export default function DiffMessage({
|
||||
<span className="flex-1 truncate font-mono text-xs text-foreground/80">
|
||||
{filePath ?? "diff"}
|
||||
</span>
|
||||
{titleBadge && (
|
||||
<span className="shrink-0 rounded-md border border-border/60 px-1.5 py-0.5 text-2xs uppercase tracking-[0.14em] text-muted-foreground">
|
||||
{titleBadge}
|
||||
</span>
|
||||
)}
|
||||
{shortSha && (
|
||||
<span className="text-xs text-muted-foreground font-mono">
|
||||
{commitUrl ? (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Rows3, SplitSquareVertical } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import { getDiffTitleBadge } from "@/features/messages/lib/parseDiff";
|
||||
import { DiffViewer } from "@/features/messages/ui/DiffViewer";
|
||||
import { Button } from "@/shared/ui/button";
|
||||
import {
|
||||
@@ -23,6 +24,11 @@ export default function DiffMessageExpanded({
|
||||
}: DiffMessageExpandedProps) {
|
||||
const [viewType, setViewType] = useState<"split" | "unified">("unified");
|
||||
|
||||
const titleBadge = useMemo(
|
||||
() => getDiffTitleBadge(content, filePath),
|
||||
[content, filePath],
|
||||
);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onOpenChange={(open) => {
|
||||
@@ -36,6 +42,11 @@ export default function DiffMessageExpanded({
|
||||
<DialogTitle className="min-w-0 flex-1 truncate font-mono text-sm font-medium">
|
||||
{filePath ?? "Diff Viewer"}
|
||||
</DialogTitle>
|
||||
{titleBadge && (
|
||||
<span className="shrink-0 rounded-md border border-border/60 px-1.5 py-0.5 text-2xs uppercase tracking-[0.14em] text-muted-foreground">
|
||||
{titleBadge}
|
||||
</span>
|
||||
)}
|
||||
<div className="flex items-center gap-1 rounded-lg border border-border/60 bg-muted/30 p-1">
|
||||
<Button
|
||||
className="h-7 px-2"
|
||||
|
||||
@@ -4,9 +4,11 @@ import { useMemo } from "react";
|
||||
|
||||
import {
|
||||
countDiffFileChanges,
|
||||
DIFF_TYPE_LABELS,
|
||||
getDiffFileLabel,
|
||||
normalizeDiffType,
|
||||
parseUnifiedDiff,
|
||||
shouldShowDiffFileHeader,
|
||||
} from "@/features/messages/lib/parseDiff";
|
||||
import { cn } from "@/shared/lib/cn";
|
||||
import "./DiffViewer.css";
|
||||
@@ -18,14 +20,6 @@ type DiffViewerProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const DIFF_TYPE_LABELS = {
|
||||
add: "New file",
|
||||
copy: "Copied",
|
||||
delete: "Deleted",
|
||||
modify: "Modified",
|
||||
rename: "Renamed",
|
||||
} as const;
|
||||
|
||||
function FileChangeBadge({
|
||||
tone,
|
||||
value,
|
||||
@@ -81,11 +75,11 @@ export function DiffViewer({
|
||||
const label = getDiffFileLabel(file, fallbackFilePath);
|
||||
const { additions, deletions } = countDiffFileChanges(file);
|
||||
const diffType = normalizeDiffType(file.type);
|
||||
const showFileHeader =
|
||||
files.length > 1 ||
|
||||
!fallbackFilePath ||
|
||||
label !== fallbackFilePath ||
|
||||
diffType !== "modify";
|
||||
const showFileHeader = shouldShowDiffFileHeader(
|
||||
label,
|
||||
files.length,
|
||||
fallbackFilePath,
|
||||
);
|
||||
const fileKey = [
|
||||
file.oldPath || "",
|
||||
file.newPath || "",
|
||||
|
||||
Reference in New Issue
Block a user