diff --git a/desktop/src/features/home/ui/HomeLoadingState.tsx b/desktop/src/features/home/ui/HomeLoadingState.tsx index 24977c7cb5..4d289e5944 100644 --- a/desktop/src/features/home/ui/HomeLoadingState.tsx +++ b/desktop/src/features/home/ui/HomeLoadingState.tsx @@ -1,8 +1,15 @@ +import type { Ref } from "react"; import { Skeleton } from "@/shared/ui/skeleton"; +import { Spinner } from "@/shared/ui/spinner"; +import { LoadingInboxComposer } from "@/features/home/ui/LoadingInboxComposer"; -export function HomeLoadingState() { +export function HomeLoadingState({ + containerRef, +}: { + containerRef?: Ref; +}) { return ( -
+
@@ -100,11 +107,15 @@ export function HomeLoadingState() {
- +
- +
diff --git a/desktop/src/features/home/ui/HomeView.tsx b/desktop/src/features/home/ui/HomeView.tsx index 4ffbbaddc5..51332d41f3 100644 --- a/desktop/src/features/home/ui/HomeView.tsx +++ b/desktop/src/features/home/ui/HomeView.tsx @@ -26,6 +26,7 @@ import { resolveInboxFilterSelection } from "@/features/home/lib/inboxSelection" import { useHomeInboxReadState } from "@/features/home/useHomeInboxReadState"; import { useHomeInboxAutoSelection } from "@/features/home/useHomeInboxAutoSelection"; import { useHomeInboxContextMessages } from "@/features/home/useHomeInboxContextMessages"; +import { useInboxLoadingDraftHandoff } from "@/features/home/useInboxLoadingDraftHandoff"; import { useHomePersonalInbox } from "@/features/home/useHomePersonalInbox"; import { useInboxThreadContext } from "@/features/home/useInboxThreadContext"; import { @@ -456,6 +457,13 @@ export function HomeView({ } return null; }, [filteredItems, selectedConversationId, selectedEventId]); + const isInboxDraftHandoffPending = useInboxLoadingDraftHandoff({ + feedReady: Boolean(feed), + hasVisibleItems: filteredItems.length > 0, + isMessagesMode, + isNarrowViewport: isNarrowHomeViewport, + selectedItem, + }); const deleteInboxMessage = React.useCallback( async (eventId: string) => { const channelId = selectedItem?.item.channelId; @@ -573,8 +581,8 @@ export function HomeView({ ], ); - if (isLoading && !feed) { - return ; + if ((isLoading && !feed) || isInboxDraftHandoffPending) { + return ; } if (!feed) { diff --git a/desktop/src/features/home/ui/LoadingInboxComposer.tsx b/desktop/src/features/home/ui/LoadingInboxComposer.tsx new file mode 100644 index 0000000000..527b0191c3 --- /dev/null +++ b/desktop/src/features/home/ui/LoadingInboxComposer.tsx @@ -0,0 +1,46 @@ +import * as React from "react"; + +import { + INBOX_LOADING_DRAFT_KEY, + loadDraftEntry, + persistDraftEntry, +} from "@/features/messages/lib/useDrafts"; + +const PLACEHOLDER = "Write a reply…"; + +/** Draft-backed input shown while Inbox resolves the conversation to reply to. */ +export function LoadingInboxComposer() { + const initialDraftRef = React.useRef(loadDraftEntry(INBOX_LOADING_DRAFT_KEY)); + const [content, setContent] = React.useState( + () => initialDraftRef.current?.content ?? "", + ); + + const persistContent = React.useCallback((nextContent: string) => { + const initialDraft = initialDraftRef.current; + persistDraftEntry( + INBOX_LOADING_DRAFT_KEY, + nextContent, + "", + initialDraft?.pendingImeta ?? [], + initialDraft?.spoileredAttachmentUrls ?? [], + initialDraft?.mentionRefs ?? [], + ); + }, []); + + return ( +