desktop: move ChannelPane props out of oversized file

Move the ChannelPane prop type into a sibling type-only module so the main component file stays below the desktop file-size guard. No runtime behavior changes.

Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
This commit is contained in:
Wes
2026-06-29 08:34:05 -06:00
co-authored by Pinky
parent e3fc0e0278
commit d9b2b4591f
2 changed files with 131 additions and 132 deletions
@@ -1,4 +1,5 @@
import * as React from "react";
import type { ChannelPaneProps } from "./ChannelPane.types";
import { Bot, Hash, LogIn, Plus, Sparkles, UserPlus } from "lucide-react";
import { useMediaUpload } from "@/features/messages/lib/useMediaUpload";
import { MessageComposer } from "@/features/messages/ui/MessageComposer";
@@ -11,7 +12,6 @@ import {
MessageTimeline,
type MessageTimelineHandle,
} from "@/features/messages/ui/MessageTimeline";
import type { ImetaMedia } from "@/features/messages/lib/imetaMediaMarkdown";
import { buildDirectMessageIntro } from "@/features/channels/lib/dmParticipantDisplay";
import {
getDmHuddleMemberPubkeys,
@@ -23,20 +23,12 @@ import {
} from "@/features/messages/lib/videoReviewContext";
import { useComposerHeightPadding } from "@/features/messages/ui/useComposerHeightPadding";
import { TypingIndicatorRow } from "@/features/messages/ui/TypingIndicatorRow";
import type { TypingIndicatorEntry } from "@/features/messages/useChannelTyping";
import {
type ProfilePanelTab,
type ProfilePanelView,
UserProfilePanel,
} from "@/features/profile/ui/UserProfilePanel";
import { UserProfilePanel } from "@/features/profile/ui/UserProfilePanel";
import { ChannelFindBar } from "@/features/search/ui/ChannelFindBar";
import { AgentSessionThreadPanel } from "@/features/channels/ui/AgentSessionThreadPanel";
import { ChannelManagementAuxiliaryPanel } from "@/features/channels/ui/ChannelManagementAuxiliaryPanel";
import { RightAuxiliaryPane } from "@/features/channels/ui/RightAuxiliaryPane";
import {
BotActivityComposerAction,
type BotActivityAgent,
} from "@/features/channels/ui/BotActivityBar";
import { BotActivityComposerAction } from "@/features/channels/ui/BotActivityBar";
import {
containsWelcomePersonaMention,
WelcomeComposerBanner,
@@ -53,135 +45,15 @@ import {
mentionsKnownAgent,
} from "@/features/channels/ui/ChannelPane.helpers";
import * as agentSessionSelection from "@/features/channels/ui/agentSessionSelection";
import type { ChannelAgentSessionAgent } from "@/features/channels/ui/useChannelAgentSessions";
import { Button } from "@/shared/ui/button";
import type { useChannelFind } from "@/features/search/useChannelFind";
import {
buildMainTimelineEntries,
type MainTimelineEntry,
} from "@/features/messages/lib/threadPanel";
import { buildMainTimelineEntries } from "@/features/messages/lib/threadPanel";
import { useRenderScopedReactionHydration } from "@/features/messages/lib/useRenderScopedReactionHydration";
import type { TimelineMessage } from "@/features/messages/types";
import type { UserProfileLookup } from "@/features/profile/lib/identity";
import { isWelcomeChannel } from "@/features/onboarding/welcome";
import { KIND_SYSTEM_MESSAGE } from "@/shared/constants/kinds";
import type { Channel } from "@/shared/api/types";
import { useIsThreadPanelOverlay } from "@/shared/hooks/use-mobile";
import { channelChrome } from "@/shared/layout/chromeLayout";
import { cn } from "@/shared/lib/cn";
type ChannelPaneProps = {
activeChannel: Channel | null;
activityAgents?: BotActivityAgent[];
agentPubkeys?: ReadonlySet<string>;
agentPubkeysPending?: boolean;
agentSessionAgents: ChannelAgentSessionAgent[];
botTypingEntries: TypingIndicatorEntry[];
channelFind: ReturnType<typeof useChannelFind>;
channelManagementOpen?: boolean;
currentPubkey?: string;
editTarget?: {
author: string;
body: string;
id: string;
imetaMedia?: ImetaMedia[];
} | null;
fetchOlder?: () => Promise<void>;
header?: React.ReactNode;
hasOlderMessages?: boolean;
isFetchingOlder?: boolean;
isJoining?: boolean;
isSinglePanelView?: boolean;
isSending: boolean;
isTimelineLoading: boolean;
messages: TimelineMessage[];
firstUnreadMessageId?: string | null;
unreadCount?: number;
canResetThreadPanelWidth: boolean;
onCancelEdit?: () => void;
onCancelThreadReply: () => void;
onCloseAgentSession: () => void;
onCloseChannelManagement?: () => void;
onChannelManagementDeleted?: () => void;
onCloseProfilePanel: () => void;
onAddAgent?: () => void;
onCreateChannel?: () => void;
onCloseThread: () => void;
onDelete?: (message: TimelineMessage) => void;
onEdit?: (message: TimelineMessage) => void;
onEditSave?: (content: string, mediaTags?: string[][]) => Promise<void>;
onMarkUnread?: (message: TimelineMessage) => void;
onMarkRead?: (message: TimelineMessage) => void;
onExpandThreadReplies: (message: TimelineMessage) => void;
onJoinChannel?: () => Promise<void>;
onOpenAgentSession: (pubkey: string) => void;
onOpenDm?: (pubkeys: string[]) => Promise<void> | void;
onOpenMembers?: () => void;
onOpenProfilePanel: (pubkey: string) => void;
onOpenThread: (message: TimelineMessage) => void;
onResetThreadPanelWidth: () => void;
onSelectThreadReplyTarget: (message: TimelineMessage) => void;
onSendMessage: (
content: string,
mentionPubkeys: string[],
mediaTags?: string[][],
) => Promise<void>;
onSendVideoReviewComment?: (
message: TimelineMessage,
content: string,
mentionPubkeys: string[],
mediaTags?: string[][],
parentEventId?: string,
) => Promise<void>;
onSendThreadReply: (
content: string,
mentionPubkeys: string[],
mediaTags?: string[][],
) => Promise<void>;
onTargetReached?: (messageId: string) => void;
onToggleReaction?: (
message: TimelineMessage,
emoji: string,
remove: boolean,
) => Promise<void>;
onThreadScrollTargetResolved: () => void;
onThreadPanelResizeStart: (
event: React.PointerEvent<HTMLButtonElement>,
) => void;
personaLookup?: Map<string, string>;
profiles?: UserProfileLookup;
openThreadHeadId: string | null;
shouldShowThreadSkeleton: boolean;
openAgentSessionPubkey: string | null;
onProfilePanelViewChange: (
view: ProfilePanelView,
options?: { replace?: boolean },
) => void;
onProfilePanelTabChange: (
tab: ProfilePanelTab,
options?: { replace?: boolean },
) => void;
profilePanelPubkey?: string | null;
profilePanelTab: ProfilePanelTab;
profilePanelView: ProfilePanelView;
threadHeadMessage: TimelineMessage | null;
threadMessages: MainTimelineEntry[];
threadPanelWidthPx: number;
threadTypingPubkeys: string[];
threadReplyTargetMessage: TimelineMessage | null;
threadScrollTargetId: string | null;
threadUnreadCounts?: ReadonlyMap<string, number>;
threadReplyUnreadCounts?: ReadonlyMap<string, number>;
threadFirstUnreadReplyId?: string | null;
targetMessageId: string | null;
typingPubkeys: string[];
isFollowingThread?: boolean;
onFollowThread?: () => void;
onUnfollowThread?: () => void;
followThreadById?: (rootId: string) => void;
unfollowThreadById?: (rootId: string) => void;
isFollowingThreadById?: (rootId: string) => boolean;
isMessageUnreadById?: (messageId: string) => boolean;
};
export const ChannelPane = React.memo(function ChannelPane({
activeChannel,
agentPubkeys,
@@ -0,0 +1,127 @@
import type { ChannelAgentSessionAgent } from "@/features/channels/ui/useChannelAgentSessions";
import type { ImetaMedia } from "@/features/messages/lib/imetaMediaMarkdown";
import type { MainTimelineEntry } from "@/features/messages/lib/threadPanel";
import type { TimelineMessage } from "@/features/messages/types";
import type { TypingIndicatorEntry } from "@/features/messages/useChannelTyping";
import type { UserProfileLookup } from "@/features/profile/lib/identity";
import type {
ProfilePanelTab,
ProfilePanelView,
} from "@/features/profile/ui/UserProfilePanel";
import type { useChannelFind } from "@/features/search/useChannelFind";
import type { Channel } from "@/shared/api/types";
import type { BotActivityAgent } from "./BotActivityBar";
export type ChannelPaneProps = {
activeChannel: Channel | null;
activityAgents?: BotActivityAgent[];
agentPubkeys?: ReadonlySet<string>;
agentPubkeysPending?: boolean;
agentSessionAgents: ChannelAgentSessionAgent[];
botTypingEntries: TypingIndicatorEntry[];
channelFind: ReturnType<typeof useChannelFind>;
channelManagementOpen?: boolean;
currentPubkey?: string;
editTarget?: {
author: string;
body: string;
id: string;
imetaMedia?: ImetaMedia[];
} | null;
fetchOlder?: () => Promise<void>;
header?: React.ReactNode;
hasOlderMessages?: boolean;
isFetchingOlder?: boolean;
isJoining?: boolean;
isSinglePanelView?: boolean;
isSending: boolean;
isTimelineLoading: boolean;
messages: TimelineMessage[];
firstUnreadMessageId?: string | null;
unreadCount?: number;
canResetThreadPanelWidth: boolean;
onCancelEdit?: () => void;
onCancelThreadReply: () => void;
onCloseAgentSession: () => void;
onCloseChannelManagement?: () => void;
onChannelManagementDeleted?: () => void;
onCloseProfilePanel: () => void;
onAddAgent?: () => void;
onCreateChannel?: () => void;
onCloseThread: () => void;
onDelete?: (message: TimelineMessage) => void;
onEdit?: (message: TimelineMessage) => void;
onEditSave?: (content: string, mediaTags?: string[][]) => Promise<void>;
onMarkUnread?: (message: TimelineMessage) => void;
onMarkRead?: (message: TimelineMessage) => void;
onExpandThreadReplies: (message: TimelineMessage) => void;
onJoinChannel?: () => Promise<void>;
onOpenAgentSession: (pubkey: string) => void;
onOpenDm?: (pubkeys: string[]) => Promise<void> | void;
onOpenMembers?: () => void;
onOpenProfilePanel: (pubkey: string) => void;
onOpenThread: (message: TimelineMessage) => void;
onResetThreadPanelWidth: () => void;
onSelectThreadReplyTarget: (message: TimelineMessage) => void;
onSendMessage: (
content: string,
mentionPubkeys: string[],
mediaTags?: string[][],
) => Promise<void>;
onSendVideoReviewComment?: (
message: TimelineMessage,
content: string,
mentionPubkeys: string[],
mediaTags?: string[][],
parentEventId?: string,
) => Promise<void>;
onSendThreadReply: (
content: string,
mentionPubkeys: string[],
mediaTags?: string[][],
) => Promise<void>;
onTargetReached?: (messageId: string) => void;
onToggleReaction?: (
message: TimelineMessage,
emoji: string,
remove: boolean,
) => Promise<void>;
onThreadScrollTargetResolved: () => void;
onThreadPanelResizeStart: (
event: React.PointerEvent<HTMLButtonElement>,
) => void;
personaLookup?: Map<string, string>;
profiles?: UserProfileLookup;
openThreadHeadId: string | null;
shouldShowThreadSkeleton: boolean;
openAgentSessionPubkey: string | null;
onProfilePanelViewChange: (
view: ProfilePanelView,
options?: { replace?: boolean },
) => void;
onProfilePanelTabChange: (
tab: ProfilePanelTab,
options?: { replace?: boolean },
) => void;
profilePanelPubkey?: string | null;
profilePanelTab: ProfilePanelTab;
profilePanelView: ProfilePanelView;
threadHeadMessage: TimelineMessage | null;
threadMessages: MainTimelineEntry[];
threadPanelWidthPx: number;
threadTypingPubkeys: string[];
threadReplyTargetMessage: TimelineMessage | null;
threadScrollTargetId: string | null;
threadUnreadCounts?: ReadonlyMap<string, number>;
threadReplyUnreadCounts?: ReadonlyMap<string, number>;
threadFirstUnreadReplyId?: string | null;
targetMessageId: string | null;
typingPubkeys: string[];
isFollowingThread?: boolean;
onFollowThread?: () => void;
onUnfollowThread?: () => void;
followThreadById?: (rootId: string) => void;
unfollowThreadById?: (rootId: string) => void;
isFollowingThreadById?: (rootId: string) => boolean;
isMessageUnreadById?: (messageId: string) => boolean;
};