From 7aae92ba52e213d8de983dda05742fc72c68bb28 Mon Sep 17 00:00:00 2001 From: Riley Crane Date: Tue, 25 Aug 2026 13:43:31 -0700 Subject: [PATCH] refactor(desktop): host the markdown-doc provider in GuardedChannelPane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ChannelScreen is over the file-size ratchet on main, and wrapping its 140-line channel-pane JSX in MarkdownDocViewerProvider re-indented the block past the line limit. GuardedChannelPane — the wrapper the channel branch already mounts and the forum branch never does — is the natural host: same provider scoping (forum FileCards keep download behavior), no indent shift, and ChannelScreen shrinks back under its allowance. Signed-off-by: Riley Crane Co-authored-by: Fizz Co-Authored-By: Claude Fable 5 --- .../features/channels/ui/ChannelScreen.tsx | 311 +++++++++--------- .../channels/ui/GuardedChannelPane.tsx | 26 +- 2 files changed, 172 insertions(+), 165 deletions(-) diff --git a/desktop/src/features/channels/ui/ChannelScreen.tsx b/desktop/src/features/channels/ui/ChannelScreen.tsx index 2b6872dcdf..e1cd68c906 100644 --- a/desktop/src/features/channels/ui/ChannelScreen.tsx +++ b/desktop/src/features/channels/ui/ChannelScreen.tsx @@ -55,7 +55,6 @@ import { useHuddleThreadIsolation } from "@/features/channels/ui/useHuddleThread import { AgentSessionProvider } from "@/shared/context/AgentSessionContext"; import { ProfilePanelProvider } from "@/shared/context/ProfilePanelContext"; import { useChannelPaneOpeners } from "@/features/channels/ui/useChannelPaneOpeners"; -import { MarkdownDocViewerProvider } from "@/shared/ui/markdown/markdownDocViewerContext"; import { useMainInsetRef } from "@/shared/layout/MainInsetContext"; import { channelContentTopPaddingMeasurement } from "@/shared/layout/chromeLayout"; import { useMeasuredCssVariable } from "@/shared/layout/useMeasuredCssVariable"; @@ -833,166 +832,156 @@ export function ChannelScreen({ searchTarget, ) ) : ( - // Forum has no doc-panel host; its FileCards keep downloading. - - - } - > - {searchForwarding.renderSearchAwareChannel( - - knownAgentPubkeys.has(pubkey) || - !!messageProfiles?.[pubkey]?.isAgent, - ) - : null - } - followThreadById={followThread} - unfollowThreadById={unfollowThread} - isFollowingThreadById={isFollowingThread} - isMessageUnreadById={isMessageUnread} - isFollowingThread={isNotifiedForEffectiveThread} - isSending={sendMessageMutation.isPending} - isSinglePanelView={isSinglePanelView} - isTimelineLoading={isTimelineLoading} - messages={timelineMessages} - threadSummaries={threadSummaries} - huddleThreadRepliesError={huddleThreadRepliesError} - onRetryHuddleThreadReplies={onRetryHuddleThreadReplies} - onCancelEdit={handleCancelEdit} - onCancelThreadReply={handleCancelThreadReply} - onChannelManagementDeleted={ - handleChannelManagementDeleted - } - onFollowThread={ - effectiveOpenThreadHeadId != null && - !isNotifiedForEffectiveThread - ? () => followThread(effectiveOpenThreadHeadId) - : undefined - } - onUnfollowThread={ - effectiveOpenThreadHeadId != null && - isNotifiedForEffectiveThread - ? () => unfollowThread(effectiveOpenThreadHeadId) - : undefined - } - onCloseAgentSession={handleCloseAgentSession} - onBackFromAgentSession={ - hasAgentSessionReturnTarget - ? handleBackFromAgentSession - : undefined - } - onCloseChannelManagement={handleCloseChannelManagement} - onCloseThread={handleCloseThread} - onDelete={ - activeChannel?.archivedAt ? undefined : handleDelete - } - onEdit={ - activeChannel?.archivedAt ? undefined : handleEdit - } - onEditSave={ - activeChannel?.archivedAt ? undefined : handleEditSave - } - onMarkUnread={handleMessageMarkUnread} - onMarkRead={handleMessageMarkRead} - onExpandThreadReplies={handleExpandThreadReplies} - onOpenAgentSession={handleOpenAgentSession} - onOpenDm={handleOpenDm} - onOpenProfilePanel={handleOpenProfilePanel} - onResetThreadPanelWidth={handleThreadPanelWidthReset} - onCloseProfilePanel={handleCloseProfilePanel} - onOpenThread={handleOpenThreadAndCloseAgentSession} - onSelectThreadReplyTarget={handleSelectThreadReplyTarget} - onSendMessage={handleSendMessage} - onSendToChannel={handleSendToChannel} - onSendVideoReviewComment={effectiveSendVideoReviewComment} - onSendThreadReply={handleSendThreadReply} - onThreadScrollTargetResolved={() => - setThreadScrollTargetId(null) - } - onThreadPanelResizeStart={handleThreadPanelResizeStart} - onTargetReached={() => - clearMessageRouteTarget({ replace: true }) - } - onToggleReaction={effectiveToggleReaction} - openAgentSessionChannelId={openAgentSessionChannelId} - openAgentSessionPubkey={openAgentSessionPubkey} - openThreadHeadId={effectiveOpenThreadHeadId} - shouldShowThreadSkeleton={shouldShowThreadSkeleton} - onProfilePanelViewChange={setProfilePanelView} - onProfilePanelTabChange={setProfilePanelTab} - markdownDocName={markdownDocName} - markdownDocUrl={markdownDocUrl} - onCloseMarkdownDoc={closeMarkdownDoc} - profilePanelPubkey={profilePanelPubkey} - profilePanelTab={profilePanelTab} - profilePanelView={profilePanelView} - personaLookup={personaLookup} - profiles={messageProfiles} - ownerProfiles={messageOwnerProfiles} - firstUnreadMessageId={firstUnreadMessageId} - unreadCount={unreadCount} - targetMessageId={mainTimelineTargetMessageId} - threadAllMessages={displayedThreadAllMessages} - threadHeadMessage={displayedThreadHeadMessage} - threadMessages={displayedThreadMessages} - threadMessagesPending={threadRepliesQuery.isPending} - threadMessagesError={threadRepliesQuery.isError} - onRetryThreadReplies={() => { - void threadRepliesQuery.refetch(); - }} - threadPanelWidthPx={threadPanelWidthPx} - threadTypingPubkeys={threadTypingPubkeys} - threadReplyTargetMessage={ - displayedThreadReplyTargetMessage - } - threadScrollTargetId={threadScrollTargetId} - threadUnreadCounts={threadUnreadCounts} - threadReplyUnreadCounts={threadReplyUnreadCounts} - threadFirstUnreadReplyId={ - displayedThreadFirstUnreadReplyId - } - isJoining={joinChannelMutation.isPending} - onJoinChannel={joinChannelMutation.mutateAsync} - typingPubkeys={humanTypingPubkeys} - />, - searchTarget, - )} - - + + } + > + {searchForwarding.renderSearchAwareChannel( + + knownAgentPubkeys.has(pubkey) || + !!messageProfiles?.[pubkey]?.isAgent, + ) + : null + } + followThreadById={followThread} + unfollowThreadById={unfollowThread} + isFollowingThreadById={isFollowingThread} + isMessageUnreadById={isMessageUnread} + isFollowingThread={isNotifiedForEffectiveThread} + isSending={sendMessageMutation.isPending} + isSinglePanelView={isSinglePanelView} + isTimelineLoading={isTimelineLoading} + messages={timelineMessages} + threadSummaries={threadSummaries} + huddleThreadRepliesError={huddleThreadRepliesError} + onRetryHuddleThreadReplies={onRetryHuddleThreadReplies} + onCancelEdit={handleCancelEdit} + onCancelThreadReply={handleCancelThreadReply} + onChannelManagementDeleted={handleChannelManagementDeleted} + onFollowThread={ + effectiveOpenThreadHeadId != null && + !isNotifiedForEffectiveThread + ? () => followThread(effectiveOpenThreadHeadId) + : undefined + } + onUnfollowThread={ + effectiveOpenThreadHeadId != null && + isNotifiedForEffectiveThread + ? () => unfollowThread(effectiveOpenThreadHeadId) + : undefined + } + onCloseAgentSession={handleCloseAgentSession} + onBackFromAgentSession={ + hasAgentSessionReturnTarget + ? handleBackFromAgentSession + : undefined + } + onCloseChannelManagement={handleCloseChannelManagement} + onCloseThread={handleCloseThread} + onDelete={ + activeChannel?.archivedAt ? undefined : handleDelete + } + onEdit={activeChannel?.archivedAt ? undefined : handleEdit} + onEditSave={ + activeChannel?.archivedAt ? undefined : handleEditSave + } + onMarkUnread={handleMessageMarkUnread} + onMarkRead={handleMessageMarkRead} + onExpandThreadReplies={handleExpandThreadReplies} + onOpenAgentSession={handleOpenAgentSession} + onOpenDm={handleOpenDm} + onOpenProfilePanel={handleOpenProfilePanel} + onResetThreadPanelWidth={handleThreadPanelWidthReset} + onCloseProfilePanel={handleCloseProfilePanel} + onOpenThread={handleOpenThreadAndCloseAgentSession} + onSelectThreadReplyTarget={handleSelectThreadReplyTarget} + onSendMessage={handleSendMessage} + onSendToChannel={handleSendToChannel} + onSendVideoReviewComment={effectiveSendVideoReviewComment} + onSendThreadReply={handleSendThreadReply} + onThreadScrollTargetResolved={() => + setThreadScrollTargetId(null) + } + onThreadPanelResizeStart={handleThreadPanelResizeStart} + onTargetReached={() => + clearMessageRouteTarget({ replace: true }) + } + onToggleReaction={effectiveToggleReaction} + openAgentSessionChannelId={openAgentSessionChannelId} + openAgentSessionPubkey={openAgentSessionPubkey} + openThreadHeadId={effectiveOpenThreadHeadId} + shouldShowThreadSkeleton={shouldShowThreadSkeleton} + onProfilePanelViewChange={setProfilePanelView} + onProfilePanelTabChange={setProfilePanelTab} + markdownDocName={markdownDocName} + markdownDocUrl={markdownDocUrl} + onCloseMarkdownDoc={closeMarkdownDoc} + profilePanelPubkey={profilePanelPubkey} + profilePanelTab={profilePanelTab} + profilePanelView={profilePanelView} + personaLookup={personaLookup} + profiles={messageProfiles} + ownerProfiles={messageOwnerProfiles} + firstUnreadMessageId={firstUnreadMessageId} + unreadCount={unreadCount} + targetMessageId={mainTimelineTargetMessageId} + threadAllMessages={displayedThreadAllMessages} + threadHeadMessage={displayedThreadHeadMessage} + threadMessages={displayedThreadMessages} + threadMessagesPending={threadRepliesQuery.isPending} + threadMessagesError={threadRepliesQuery.isError} + onRetryThreadReplies={() => { + void threadRepliesQuery.refetch(); + }} + threadPanelWidthPx={threadPanelWidthPx} + threadTypingPubkeys={threadTypingPubkeys} + threadReplyTargetMessage={displayedThreadReplyTargetMessage} + threadScrollTargetId={threadScrollTargetId} + threadUnreadCounts={threadUnreadCounts} + threadReplyUnreadCounts={threadReplyUnreadCounts} + threadFirstUnreadReplyId={displayedThreadFirstUnreadReplyId} + isJoining={joinChannelMutation.isPending} + onJoinChannel={joinChannelMutation.mutateAsync} + typingPubkeys={humanTypingPubkeys} + />, + searchTarget, + )} + ) ) : ( diff --git a/desktop/src/features/channels/ui/GuardedChannelPane.tsx b/desktop/src/features/channels/ui/GuardedChannelPane.tsx index 2e9455a1e5..8bf3e6c180 100644 --- a/desktop/src/features/channels/ui/GuardedChannelPane.tsx +++ b/desktop/src/features/channels/ui/GuardedChannelPane.tsx @@ -1,9 +1,27 @@ import type * as React from "react"; +import { + type MarkdownDocTarget, + MarkdownDocViewerProvider, +} from "@/shared/ui/markdown/markdownDocViewerContext"; + import { ChannelPane } from "./ChannelScreenLazyViews"; -export function GuardedChannelPane( - props: React.ComponentProps, -) { - return ; +/** + * Hosts the markdown-doc viewer context for the channel pane — the surface + * that renders the doc auxiliary panel. The forum branch never mounts this + * wrapper, so forum FileCards keep plain download behavior instead of a + * dead open-in-viewer click. + */ +export function GuardedChannelPane({ + onOpenMarkdownDoc, + ...props +}: React.ComponentProps & { + onOpenMarkdownDoc: (doc: MarkdownDocTarget) => void; +}) { + return ( + + + + ); }