Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions client/__tests__/GameDownloadDialog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type TorrentItemOverrides = {
seeders?: number;
leechers?: number;
indexerName?: string;
comments?: string;
group?: string;
downloadVolumeFactor?: number;
uploadVolumeFactor?: number;
Expand Down Expand Up @@ -138,6 +139,7 @@ const makeTorrentItem = (overrides: TorrentItemOverrides = {}) => ({
seeders: overrides.seeders ?? 10,
leechers: overrides.leechers ?? 2,
indexerName: overrides.indexerName ?? "Indexer A",
...(overrides.comments !== undefined && { comments: overrides.comments }),
...(overrides.group !== undefined && { group: overrides.group }),
...(overrides.downloadVolumeFactor !== undefined && {
downloadVolumeFactor: overrides.downloadVolumeFactor,
Expand Down Expand Up @@ -288,6 +290,28 @@ describe("GameDownloadDialog", () => {
);
});

it.each([false, true])(
"links release titles to their indexer source when mobile is %s",
async (isMobile) => {
mockIsMobile = isMobile;
globalThis.fetch = createFetchMock({
search: makeSearchResult([
makeTorrentItem({
title: "Linked Release",
comments: "https://indexer.example/releases/123",
}),
]),
});

renderComponent();

const link = await screen.findByRole("link", { name: "Linked Release" });
expect(link).toHaveAttribute("href", "https://indexer.example/releases/123");
expect(link).toHaveAttribute("target", "_blank");
expect(link).toHaveAttribute("rel", "noopener noreferrer");
}
);

it("identifies Usenet vs Torrent items", async () => {
renderComponent();

Expand Down
36 changes: 30 additions & 6 deletions client/src/components/GameDownloadDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1137,9 +1137,21 @@ export default function GameDownloadDialog({ game, open, onOpenChange }: GameDow
<div className="flex items-start justify-between gap-2">
<div className="flex-1 min-w-0">
<div className="flex items-start gap-1.5 min-w-0">
<h4 className="font-semibold text-sm leading-snug break-all line-clamp-2 min-w-0 flex-1">
{download.title}
</h4>
{download.comments ? (
<a
href={download.comments}
target="_blank"
rel="noopener noreferrer"
className="font-semibold text-sm leading-snug break-all line-clamp-2 min-w-0 flex-1 hover:underline cursor-pointer"
onClick={(event) => event.stopPropagation()}
>
{download.title}
</a>
) : (
<h4 className="font-semibold text-sm leading-snug break-all line-clamp-2 min-w-0 flex-1">
{download.title}
</h4>
)}
Comment on lines +1140 to +1154

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve heading semantics in both result layouts.

Both conditional branches replace the existing <h4> with a bare <a> when download.comments exists. This removes the heading role from linked release titles.

  • client/src/components/GameDownloadDialog.tsx#L1140-L1154: Keep the mobile <h4> wrapper and render the conditional external <a> inside it.
  • client/src/components/GameDownloadDialog.tsx#L1256-L1270: Keep the desktop <h4> wrapper and render the conditional external <a> inside it.

As per coding guidelines: client/src/**/*.{tsx,ts}: Use semantic HTML elements such as <button>, <nav>, <main>, and <section> instead of clickable <div> elements.

📍 Affects 1 file
  • client/src/components/GameDownloadDialog.tsx#L1140-L1154 (this comment)
  • client/src/components/GameDownloadDialog.tsx#L1256-L1270
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@client/src/components/GameDownloadDialog.tsx` around lines 1140 - 1154,
Preserve heading semantics in both result layouts by keeping the existing h4
wrappers around the release titles and rendering the conditional external a
inside them. Apply this change to client/src/components/GameDownloadDialog.tsx
lines 1140-1154 and 1256-1270, while retaining the existing link behavior and
non-link title rendering.

Source: Coding guidelines

{isNew && (
<Badge
variant="default"
Expand Down Expand Up @@ -1241,9 +1253,21 @@ export default function GameDownloadDialog({ game, open, onOpenChange }: GameDow
</TooltipContent>
</Tooltip>

<h4 className="font-bold text-base leading-tight break-words min-w-0">
{download.title}
</h4>
{download.comments ? (
<a
href={download.comments}
target="_blank"
rel="noopener noreferrer"
className="font-bold text-base leading-tight break-words min-w-0 hover:underline cursor-pointer"
onClick={(event) => event.stopPropagation()}
>
{download.title}
</a>
) : (
<h4 className="font-bold text-base leading-tight break-words min-w-0">
{download.title}
</h4>
)}

{isNew && (
<Badge
Expand Down