diff --git a/src/App.jsx b/src/App.jsx index ec59370..8200241 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -352,6 +352,38 @@ export default function App() { // Tip state: { [sessionId]: messageId } const [newMsgTip, setNewMsgTip] = useState({}); + // Collapse state per user message: { [msgKey]: boolean } — true means "collapsed" + const [collapsedUserMsgs, setCollapsedUserMsgs] = useState({}); + + // Compute a stable key for collapse map (prefer id, else session:index) + const collapseKeyFor = (m, i, sessionId) => (m?.id ? m.id : `${sessionId}:${i}`); + + // Initialize/maintain collapsed map whenever messages or the active session change + useEffect(() => { + if (!activeSessionId) return; + + const msgs = + (chatSessions.find(s => s.session_id === activeSessionId)?.messages) || []; + + setCollapsedUserMsgs(prev => { + const next = {}; + msgs.forEach((m, i) => { + if (m.role !== 'user') return; + const key = collapseKeyFor(m, i, activeSessionId); + const lineCount = (m.content || '').split(/\r\n|\r|\n/).length; + const needsCollapse = lineCount > 30; + // Default collapsed = true when needsCollapse; preserve user toggles + next[key] = needsCollapse ? (prev[key] ?? true) : false; + }); + return next; + }); + }, [chatSessions, activeSessionId]); + + // Toggle collapse/expand for a specific message + function toggleUserMsgCollapse(key) { + setCollapsedUserMsgs(prev => ({ ...prev, [key]: !(prev[key] ?? true) })); + } + const setUserScrolledUp = React.useCallback((sessionId, value) => { setUserScrolledUpState(prev => { const next = { ...prev, [sessionId]: value }; @@ -1181,12 +1213,10 @@ export default function App() {
{isEditingThis ? (
- {/* Shadow defines bubble width/height based on current text */} - {/* Overlay textarea fills the bubble exactly */}
) : ( -
{m.content}
+ (() => { + const raw = m.content || ''; + const lines = raw.split(/\r\n|\r|\n/); + const needsCollapse = lines.length > 30; + const key = collapseKeyFor(m, i, activeSessionId); + const isCollapsed = needsCollapse ? (collapsedUserMsgs[key] ?? true) : false; + const displayText = isCollapsed ? lines.slice(0, 30).join('\n') + '\n…' : raw; + + return ( + <> +
{displayText}
+ {needsCollapse && ( + + )} + + ); + })() )} {!isSending && !isEditingThis && (
diff --git a/src/styles.css b/src/styles.css index d8767c2..ca42cf0 100644 --- a/src/styles.css +++ b/src/styles.css @@ -351,15 +351,15 @@ textarea.input { padding: 0; background: transparent; border: none; - color: var(--accent); + color: var(--muted); font-weight: 700; /* bold as requested */ cursor: pointer; - text-align: left; /* align with text content */ + align-self: flex-start; /* <-- key line */ + margin-left: 0; /* ensure no stray left margin */ + text-align: left; /* you already had this */ } .msg.user .user-msg-expand:hover { - opacity: .9; - text-decoration: underline; } .msg.assistant {