diff --git a/src/renderer/components/team/TeamDetailView.tsx b/src/renderer/components/team/TeamDetailView.tsx index 338b8255..8e2e031f 100644 --- a/src/renderer/components/team/TeamDetailView.tsx +++ b/src/renderer/components/team/TeamDetailView.tsx @@ -39,8 +39,8 @@ import { } from '@renderer/store/slices/teamSlice'; import { createChipFromSelection } from '@renderer/utils/chipUtils'; import { sumContextInjectionTokens } from '@renderer/utils/contextMath'; -import { formatProjectPath } from '@renderer/utils/pathDisplay'; import { buildMemberColorMap } from '@renderer/utils/memberHelpers'; +import { formatProjectPath } from '@renderer/utils/pathDisplay'; import { buildTaskCountsByOwner, normalizePath } from '@renderer/utils/pathNormalize'; import { nameColorSet } from '@renderer/utils/projectColor'; import { resolveProjectIdByPath } from '@renderer/utils/projectLookup'; @@ -2011,6 +2011,7 @@ export const TeamDetailView = ({ onReplyToMessage: handleReplyToMessage, onRestartTeam: handleRestartTeam, onTaskIdClick: handleTaskIdClick, + inlineScrollContainerRef: contentRef, }), [ activeMembers, diff --git a/src/renderer/components/team/messages/MessagesPanel.tsx b/src/renderer/components/team/messages/MessagesPanel.tsx index 3dcd1d9a..98ec9c66 100644 --- a/src/renderer/components/team/messages/MessagesPanel.tsx +++ b/src/renderer/components/team/messages/MessagesPanel.tsx @@ -1,4 +1,13 @@ -import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import { + memo, + type RefObject, + useCallback, + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState, +} from 'react'; import { Sheet, type SheetRef } from 'react-modal-sheet'; import { Badge } from '@renderer/components/ui/badge'; @@ -91,6 +100,13 @@ interface MessagesPanelProps { onRestartTeam?: () => void; /** Callback when a task ID link is clicked. */ onTaskIdClick?: (taskId: string) => void; + /** + * Scroll container owned by the parent view when `position === 'inline'`. + * MessagesPanel does not own this element — the viewport lives in + * TeamDetailView's content scroll area. Plumbed for future viewport + * consumers (virtualization); unused in this release. + */ + inlineScrollContainerRef?: RefObject; } export function reconcilePendingRepliesByMember( @@ -214,6 +230,11 @@ export const MessagesPanel = memo(function MessagesPanel({ const sidebarScrollRef = useRef(null); const bottomSheetRef = useRef(null); const bottomSheetStickyTopRef = useRef(null); + // Scroll container inside `Sheet.Content` for the bottom-sheet layout. + // react-modal-sheet merges this ref with its own internal scroll ref. + // Held here so future viewport consumers (virtualization) can observe the + // true scrolling element in bottom-sheet mode. + const bottomSheetScrollRef = useRef(null); const handleExpandContent = useCallback(() => { // no-op: user is reading expanded content, not composing }, []); @@ -1063,6 +1084,7 @@ export const MessagesPanel = memo(function MessagesPanel({ state.scrollPosition !== 'top'} >