✂️ fix: Unicode-Safe Title Truncation and Shared View Layout Polish (#12003)

* fix: title sanitization with max length truncation and update ShareView for better text display

- Added functionality to `sanitizeTitle` to truncate titles exceeding 200 characters with an ellipsis, ensuring consistent title length.
- Updated `ShareView` component to apply a line clamp on the title, improving text display and preventing overflow in the UI.

* refactor: Update layout and styling in MessagesView and ShareView components

- Removed unnecessary padding in MessagesView to streamline the layout.
- Increased bottom padding in the message container for better spacing.
- Enhanced ShareView footer positioning and styling for improved visibility.
- Adjusted section and div classes in ShareView for better responsiveness and visual consistency.

* fix: Correct title fallback and enhance sanitization logic in sanitizeTitle

- Updated the fallback title in sanitizeTitle to use DEFAULT_TITLE_FALLBACK instead of a hardcoded string.
- Improved title truncation logic to ensure proper handling of maximum length and whitespace, including edge cases for emoji and whitespace-only titles.
- Added tests to validate the new sanitization behavior, ensuring consistent and expected results across various input scenarios.
This commit is contained in:
Danny Avila 2026-03-01 16:44:57 -05:00 committed by GitHub
parent ce1338285c
commit 5be90706b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 85 additions and 31 deletions

View file

@ -13,7 +13,7 @@ export default function MessagesView({
const localize = useLocalize();
const [currentEditId, setCurrentEditId] = useState<number | string | null>(-1);
return (
<div className="min-h-0 flex-1 overflow-hidden pb-[50px]">
<div className="min-h-0 flex-1 overflow-hidden">
<div className="dark:gpt-dark-gray relative h-full">
<div
style={{
@ -22,8 +22,8 @@ export default function MessagesView({
width: '100%',
}}
>
<div className="flex flex-col pb-9 text-sm dark:bg-transparent">
{(_messagesTree && _messagesTree.length == 0) || _messagesTree === null ? (
<div className="flex flex-col pb-16 text-sm dark:bg-transparent">
{(_messagesTree && _messagesTree.length === 0) || _messagesTree === null ? (
<div className="flex w-full items-center justify-center gap-1 bg-gray-50 p-3 text-sm text-gray-500 dark:border-gray-800/50 dark:bg-gray-800 dark:text-gray-300">
{localize('com_ui_nothing_found')}
</div>

View file

@ -123,14 +123,14 @@ function SharedView() {
}
const footer = (
<div className="w-full border-t-0 pl-0 pt-2 md:w-[calc(100%-.5rem)] md:border-t-0 md:border-transparent md:pl-0 md:pt-0 md:dark:border-transparent">
<Footer className="relative mx-auto mt-4 flex max-w-[55rem] flex-wrap items-center justify-center gap-2 px-3 pb-4 pt-2 text-center text-xs text-text-secondary" />
<div className="pointer-events-none absolute inset-x-0 bottom-0 z-10 bg-gradient-to-t from-surface-secondary from-40% to-transparent">
<Footer className="pointer-events-auto relative mx-auto flex max-w-[55rem] flex-wrap items-center justify-center gap-2 px-3 pb-4 pt-6 text-center text-xs text-text-secondary" />
</div>
);
const mainContent = (
<div className="transition-width relative flex h-full w-full flex-1 flex-col items-stretch overflow-hidden pt-0 dark:bg-surface-secondary">
<div className="flex h-full min-h-0 flex-col text-text-primary" role="presentation">
<div className="relative flex h-full min-h-0 flex-col text-text-primary" role="presentation">
{content}
{footer}
</div>
@ -189,11 +189,13 @@ function ShareHeader({
}, []);
return (
<section className="mx-auto w-full px-3 pb-4 pt-6 md:px-5">
<div className="bg-surface-primary/80 relative mx-auto flex w-full max-w-[60rem] flex-col gap-4 rounded-3xl border border-border-light px-6 py-5 shadow-xl backdrop-blur">
<section className="mx-auto w-full px-2 pb-3 pt-4 md:px-5 md:pb-4 md:pt-6">
<div className="bg-surface-primary/80 relative mx-auto flex w-full max-w-[60rem] flex-col gap-3 rounded-2xl border border-border-light px-4 py-4 shadow-xl backdrop-blur md:gap-4 md:rounded-3xl md:px-6 md:py-5">
<div className="flex flex-col gap-3 md:flex-row md:items-end md:justify-between">
<div className="space-y-2">
<h1 className="text-4xl font-semibold text-text-primary">{title}</h1>
<div className="min-w-0 space-y-1.5 md:space-y-2">
<h1 className="line-clamp-2 break-words text-2xl font-semibold text-text-primary md:text-4xl">
{title}
</h1>
{formattedDate && (
<div className="flex items-center gap-2 text-sm text-text-secondary">
<CalendarDays className="size-4" aria-hidden="true" />