From 2b0bf52e1e33e1d68e0145107a65a315176cd5b4 Mon Sep 17 00:00:00 2001 From: Matthew Sigal Date: Thu, 16 Jul 2026 15:56:41 -0700 Subject: [PATCH 1/2] Add Read More collapsible text container to media details description - Clamps long description texts (> 4 lines) inside a focusable SpottableDiv container. - Measures scrollHeight vs clientHeight on layout to dynamically detect overflow. - Disables D-pad spotlight focus on the description block when it does not overflow. - Adds accent-colored 'Read More' label and scale/border focus transitions. --- .../src/views/Details/ModernDetailContent.js | 35 +++++++++++++++- .../Details/ModernDetailContent.module.less | 41 ++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/packages/app/src/views/Details/ModernDetailContent.js b/packages/app/src/views/Details/ModernDetailContent.js index 2b97e544..c3f3bf50 100644 --- a/packages/app/src/views/Details/ModernDetailContent.js +++ b/packages/app/src/views/Details/ModernDetailContent.js @@ -58,6 +58,28 @@ const ModernDetailContent = (props) => { const played = item.UserData?.Played; const isFavorite = item.UserData?.IsFavorite; + const [canToggle, setCanToggle] = useState(false); + const [isExpanded, setIsExpanded] = useState(false); + const descriptionRef = useRef(null); + + // Reset expanded state when item changes + useEffect(() => { + setIsExpanded(false); + setCanToggle(false); + }, [item]); + + // Detect if description text overflows 4 lines + useEffect(() => { + const el = descriptionRef.current; + if (el && !isExpanded) { + setCanToggle(el.scrollHeight > el.clientHeight); + } + }, [item?.Overview, isExpanded]); + + const handleToggleExpand = useCallback(() => { + setIsExpanded(prev => !prev); + }, []); + const scrollToRef = useRef(null); const handleScrollTo = useCallback((fn) => { scrollToRef.current = fn; @@ -507,7 +529,18 @@ const ModernDetailContent = (props) => { )} {!isPerson && } {tagline &&
{tagline}
} - {item.Overview &&

{item.Overview}

} + {item.Overview && ( + +

+ {item.Overview} +

+ {canToggle && !isExpanded &&
{$L('Read More')}
} +
+ )} {renderUpNext()} diff --git a/packages/app/src/views/Details/ModernDetailContent.module.less b/packages/app/src/views/Details/ModernDetailContent.module.less index 4ada2f30..af10f7cb 100644 --- a/packages/app/src/views/Details/ModernDetailContent.module.less +++ b/packages/app/src/views/Details/ModernDetailContent.module.less @@ -131,11 +131,50 @@ .overview { font-size: 26px; line-height: 1.5; - max-width: 900px; + max-width: 100%; opacity: 0.92; margin: 0; } +.overviewCollapsed { + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.descriptionContainer { + display: flex; + flex-direction: column; + gap: 12px; + padding: 24px; + border-radius: 16px; + border: 1px solid rgba(255, 255, 255, 0.08); + background: rgba(255, 255, 255, 0.03); + max-width: 900px; + box-sizing: border-box; + transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.15s ease; + outline: none; +} + +.descriptionContainerSpottable { + cursor: pointer; +} + +.descriptionContainerSpottable:focus { + border-color: rgba(255, 255, 255, 0.35); + background: rgba(255, 255, 255, 0.06); + transform: scale(1.01); +} + +.readMoreBtn { + color: #ff5b5b; + font-weight: 600; + font-size: 22px; + align-self: flex-start; +} + + .icon { width: 32px; height: 32px; From 78252e353347f544e6506bf66abdfd9577da9d82 Mon Sep 17 00:00:00 2001 From: RadicalMuffinMan <103554043+RadicalMuffinMan@users.noreply.github.com> Date: Thu, 16 Jul 2026 23:15:20 -0400 Subject: [PATCH 2/2] Fixed Read More collapse on item update and added Read Less --- packages/app/src/views/Details/ModernDetailContent.js | 7 ++++--- .../app/src/views/Details/ModernDetailContent.module.less | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/app/src/views/Details/ModernDetailContent.js b/packages/app/src/views/Details/ModernDetailContent.js index c3f3bf50..6140b729 100644 --- a/packages/app/src/views/Details/ModernDetailContent.js +++ b/packages/app/src/views/Details/ModernDetailContent.js @@ -62,11 +62,12 @@ const ModernDetailContent = (props) => { const [isExpanded, setIsExpanded] = useState(false); const descriptionRef = useRef(null); - // Reset expanded state when item changes + // Reset expanded state when navigating to a different item. Keyed on the id so an + // in-place update to the same item doesn't collapse the text. useEffect(() => { setIsExpanded(false); setCanToggle(false); - }, [item]); + }, [item?.Id]); // Detect if description text overflows 4 lines useEffect(() => { @@ -538,7 +539,7 @@ const ModernDetailContent = (props) => {

{item.Overview}

- {canToggle && !isExpanded &&
{$L('Read More')}
} + {canToggle &&
{isExpanded ? $L('Read Less') : $L('Read More')}
} )} diff --git a/packages/app/src/views/Details/ModernDetailContent.module.less b/packages/app/src/views/Details/ModernDetailContent.module.less index af10f7cb..5599158e 100644 --- a/packages/app/src/views/Details/ModernDetailContent.module.less +++ b/packages/app/src/views/Details/ModernDetailContent.module.less @@ -174,7 +174,6 @@ align-self: flex-start; } - .icon { width: 32px; height: 32px;