fix: add show more/less toggle for truncated highlights in Nova (#1029)

Co-authored-by: Vorflux AI <noreply@vorflux.com>
This commit is contained in:
vorflux[bot] 2026-05-31 19:10:43 -07:00 committed by GitHub
parent 53c971ac85
commit 253a82bdb7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 5 deletions

View file

@ -364,12 +364,23 @@ export function ChatSidebar({
)
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
if (e.key === "Enter" && !e.shiftKey && !isMobile) {
e.preventDefault()
handleSend()
}
}
// When the user stops generation before any assistant response arrives,
// remove the dangling user message so it isn't duplicated on the next send.
const handleStop = useCallback(() => {
stop()
setMessages((prev) => {
const last = prev[prev.length - 1]
if (last?.role === "user") return prev.slice(0, -1)
return prev
})
}, [stop, setMessages])
const handleCopyMessage = useCallback((messageId: string, text: string) => {
analytics.chatMessageCopied({ message_id: messageId })
navigator.clipboard.writeText(text)
@ -1137,7 +1148,7 @@ export function ChatSidebar({
value={input}
onChange={(e) => setInput(e.target.value)}
onSend={handleSend}
onStop={stop}
onStop={handleStop}
onKeyDown={handleKeyDown}
isResponding={isResponding}
activeStatus={

View file

@ -1,6 +1,12 @@
"use client"
import { useState, useCallback, useRef, useEffect } from "react"
import {
useState,
useCallback,
useRef,
useEffect,
useLayoutEffect,
} from "react"
import { cn } from "@lib/utils"
import { dmSansClassName } from "@/lib/fonts"
import {
@ -75,6 +81,9 @@ export function HighlightsCard({
const [activeIndex, setActiveIndex] = useState(0)
const [isReplyOpen, setIsReplyOpen] = useState(false)
const [replyText, setReplyText] = useState("")
const [isExpanded, setIsExpanded] = useState(false)
const [isClamped, setIsClamped] = useState(false)
const contentRef = useRef<HTMLDivElement>(null)
const replyInputRef = useRef<HTMLInputElement>(null)
const currentItem = items[activeIndex]
@ -87,18 +96,28 @@ export function HighlightsCard({
useEffect(() => {
setIsReplyOpen(false)
setReplyText("")
setIsExpanded(false)
}, [items])
// biome-ignore lint/correctness/useExhaustiveDependencies: re-run when item or expansion changes to detect clamping
useLayoutEffect(() => {
const el = contentRef.current
if (!el) return
setIsClamped(el.scrollHeight > el.clientHeight)
}, [currentItem, isExpanded])
const handlePrev = useCallback(() => {
setActiveIndex((prev) => (prev > 0 ? prev - 1 : items.length - 1))
setIsReplyOpen(false)
setReplyText("")
setIsExpanded(false)
}, [items.length])
const handleNext = useCallback(() => {
setActiveIndex((prev) => (prev < items.length - 1 ? prev + 1 : 0))
setIsReplyOpen(false)
setReplyText("")
setIsExpanded(false)
}, [items.length])
const handleChatClick = useCallback(() => {
@ -259,12 +278,27 @@ export function HighlightsCard({
</div>
<div id="highlights-body" className="flex flex-col gap-1.5">
<p className="text-[12px] font-semibold text-fg-primary leading-tight truncate">
<p className="text-[12px] font-semibold text-fg-primary leading-tight">
{currentItem.title}
</p>
<div className="text-[12px] text-fg-primary leading-normal line-clamp-5">
<div
ref={contentRef}
className={cn(
"text-[12px] text-fg-primary leading-normal",
!isExpanded && "line-clamp-5",
)}
>
{renderContent(currentItem.content, currentItem.format)}
</div>
{(isClamped || isExpanded) && (
<button
type="button"
onClick={() => setIsExpanded((v) => !v)}
className="self-start text-[11px] text-fg-subtle hover:text-fg-primary transition-colors cursor-pointer"
>
{isExpanded ? "Show less" : "Show more"}
</button>
)}
</div>
{isReplyOpen && (