fix(stream): preserve filename extension in narrow bubbles
Previously the file bubble wrapped JS middle-ellipsis in CSS truncate, so narrow containers silently clipped the tail+extension, leaving e.g. "25cb264a-e06…." instead of "25cb264a-e06…811a.jpg". Split the displayed name into a shrinking head (with CSS truncate) and a non-shrinking tail (last 4 base chars + extension). The browser now decides how much head to clip while the suffix is always visible.
This commit is contained in:
@@ -5,10 +5,7 @@ import { useI18n } from "../../../i18n";
|
|||||||
import type { Attachment, Post } from "../../../types/post";
|
import type { Attachment, Post } from "../../../types/post";
|
||||||
import { downloadAttachment } from "../utils/downloadFile";
|
import { downloadAttachment } from "../utils/downloadFile";
|
||||||
import { fileIcon } from "../utils/fileIcon";
|
import { fileIcon } from "../utils/fileIcon";
|
||||||
import {
|
import { filenameWithExtension, splitFilename } from "../utils/filenameDisplay";
|
||||||
filenameWithExtension,
|
|
||||||
middleEllipsisFilename,
|
|
||||||
} from "../utils/filenameDisplay";
|
|
||||||
import { formatBytes } from "../utils/formatBytes";
|
import { formatBytes } from "../utils/formatBytes";
|
||||||
import { postDisplayText } from "../utils/postText";
|
import { postDisplayText } from "../utils/postText";
|
||||||
import { CollapsibleText } from "../CollapsibleText";
|
import { CollapsibleText } from "../CollapsibleText";
|
||||||
@@ -60,10 +57,21 @@ function AttachmentRow({ postId, att }: { postId: string; att: Attachment }) {
|
|||||||
)}
|
)}
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div
|
<div
|
||||||
className="truncate text-[15px] font-medium leading-6 text-ark-gold group-hover:text-ark-gold2"
|
className="flex min-w-0 items-baseline text-[15px] font-medium leading-6 text-ark-gold group-hover:text-ark-gold2"
|
||||||
title={displayFilename}
|
title={displayFilename}
|
||||||
>
|
>
|
||||||
{middleEllipsisFilename(displayFilename)}
|
{(() => {
|
||||||
|
const { base, ext } = splitFilename(displayFilename);
|
||||||
|
const tailChars = Math.min(4, base.length);
|
||||||
|
const head = base.slice(0, base.length - tailChars);
|
||||||
|
const tail = base.slice(base.length - tailChars) + ext;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span className="min-w-0 truncate">{head}</span>
|
||||||
|
<span className="shrink-0 whitespace-pre">{tail}</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[12px] font-medium leading-[19.2px] text-[#A8A9AE]">
|
<div className="text-[12px] font-medium leading-[19.2px] text-[#A8A9AE]">
|
||||||
{isDownloading ? t("downloading") : formatBytes(att.sizeBytes)}
|
{isDownloading ? t("downloading") : formatBytes(att.sizeBytes)}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export function middleEllipsisFilename(
|
|||||||
return `${base.slice(0, headLength)}${ellipsis}${base.slice(-tailLength)}${ext}`;
|
return `${base.slice(0, headLength)}${ellipsis}${base.slice(-tailLength)}${ext}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function splitFilename(filename: string): { base: string; ext: string } {
|
export function splitFilename(filename: string): { base: string; ext: string } {
|
||||||
const dotIndex = filename.lastIndexOf(".");
|
const dotIndex = filename.lastIndexOf(".");
|
||||||
if (!hasFileExtension(filename)) return { base: filename, ext: "" };
|
if (!hasFileExtension(filename)) return { base: filename, ext: "" };
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user