mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
refactor(desktop): host the markdown-doc provider in GuardedChannelPane
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 <rileycrane@squareup.com> Co-authored-by: Fizz <d4ec90109b43092b0ec94cf136850915a3732a29ab3089a1dec43d2ed43dd6eb@buzz.block.builderlab.xyz> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
<MarkdownDocViewerProvider value={handleOpenMarkdownDoc}>
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<ChannelScreenLoadingFallback
|
||||
isHuddleTranscript={isHuddleTranscript}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{searchForwarding.renderSearchAwareChannel(
|
||||
<GuardedChannelPane
|
||||
activeChannel={activeChannel}
|
||||
activityAgents={channelAgentSessionAgents}
|
||||
agentPubkeys={agentPubkeys}
|
||||
agentPubkeysPending={agentPubkeysPending}
|
||||
agentSessionAgents={agentSessionAgents}
|
||||
autoSendDraftKey={autoSendDraftKey}
|
||||
onAutoSendComplete={clearAutoSend}
|
||||
botTypingEntries={botTypingEntries}
|
||||
channelManagementOpen={channelManagementOpen}
|
||||
currentPubkey={currentPubkey}
|
||||
canResetThreadPanelWidth={canResetThreadPanelWidth}
|
||||
fetchOlder={fetchOlder}
|
||||
header={channelHeader}
|
||||
hasOlderMessages={hasOlderMessages}
|
||||
historyExhausted={historyExhausted}
|
||||
onAddAgent={handleOpenAddBot}
|
||||
onBrowseChannels={openBrowseChannels}
|
||||
onCreateChannel={openCreateChannel}
|
||||
onOpenMembers={handleOpenMembersSidebar}
|
||||
isFetchingOlder={isFetchingOlder}
|
||||
isHuddleTranscript={isHuddleTranscript}
|
||||
entranceMessageId={welcomeEntranceMessageId}
|
||||
onEntranceMessageComplete={handleWelcomeEntranceComplete}
|
||||
welcomeKickoffStage={welcomeKickoffStage}
|
||||
welcomeKickoffSettingUp={welcomeKickoffSettingUp}
|
||||
editTarget={
|
||||
editTargetMessage
|
||||
? buildMessageComposerEditTarget(
|
||||
editTargetMessage,
|
||||
messageProfiles,
|
||||
(pubkey) =>
|
||||
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,
|
||||
)}
|
||||
</React.Suspense>
|
||||
</MarkdownDocViewerProvider>
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<ChannelScreenLoadingFallback
|
||||
isHuddleTranscript={isHuddleTranscript}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{searchForwarding.renderSearchAwareChannel(
|
||||
<GuardedChannelPane
|
||||
onOpenMarkdownDoc={handleOpenMarkdownDoc}
|
||||
activeChannel={activeChannel}
|
||||
activityAgents={channelAgentSessionAgents}
|
||||
agentPubkeys={agentPubkeys}
|
||||
agentPubkeysPending={agentPubkeysPending}
|
||||
agentSessionAgents={agentSessionAgents}
|
||||
autoSendDraftKey={autoSendDraftKey}
|
||||
onAutoSendComplete={clearAutoSend}
|
||||
botTypingEntries={botTypingEntries}
|
||||
channelManagementOpen={channelManagementOpen}
|
||||
currentPubkey={currentPubkey}
|
||||
canResetThreadPanelWidth={canResetThreadPanelWidth}
|
||||
fetchOlder={fetchOlder}
|
||||
header={channelHeader}
|
||||
hasOlderMessages={hasOlderMessages}
|
||||
historyExhausted={historyExhausted}
|
||||
onAddAgent={handleOpenAddBot}
|
||||
onBrowseChannels={openBrowseChannels}
|
||||
onCreateChannel={openCreateChannel}
|
||||
onOpenMembers={handleOpenMembersSidebar}
|
||||
isFetchingOlder={isFetchingOlder}
|
||||
isHuddleTranscript={isHuddleTranscript}
|
||||
entranceMessageId={welcomeEntranceMessageId}
|
||||
onEntranceMessageComplete={handleWelcomeEntranceComplete}
|
||||
welcomeKickoffStage={welcomeKickoffStage}
|
||||
welcomeKickoffSettingUp={welcomeKickoffSettingUp}
|
||||
editTarget={
|
||||
editTargetMessage
|
||||
? buildMessageComposerEditTarget(
|
||||
editTargetMessage,
|
||||
messageProfiles,
|
||||
(pubkey) =>
|
||||
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,
|
||||
)}
|
||||
</React.Suspense>
|
||||
)
|
||||
) : (
|
||||
<ChannelScreenEmptyState />
|
||||
|
||||
@@ -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<typeof ChannelPane>,
|
||||
) {
|
||||
return <ChannelPane {...props} />;
|
||||
/**
|
||||
* 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<typeof ChannelPane> & {
|
||||
onOpenMarkdownDoc: (doc: MarkdownDocTarget) => void;
|
||||
}) {
|
||||
return (
|
||||
<MarkdownDocViewerProvider value={onOpenMarkdownDoc}>
|
||||
<ChannelPane {...props} />
|
||||
</MarkdownDocViewerProvider>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user