diff --git a/src/apps/chat/AppChat.tsx b/src/apps/chat/AppChat.tsx index 4dbb01904..a59c1f8e4 100644 --- a/src/apps/chat/AppChat.tsx +++ b/src/apps/chat/AppChat.tsx @@ -34,6 +34,7 @@ import { useIsMobile } from '~/common/components/useMatchMedia'; import { useOverlayComponents } from '~/common/layout/overlays/useOverlayComponents'; import { useRouterQuery } from '~/common/app.routes'; import { useUXLabsStore } from '~/common/state/store-ux-labs'; +import { useWorkspaceContents } from '~/common/stores/workspace/workspace.hooks'; import { ChatBarAltBeam } from './components/layout-bar/ChatBarAltBeam'; import { ChatBarAltTitle } from './components/layout-bar/ChatBarAltTitle'; @@ -144,6 +145,8 @@ export function AppChat() { deleteConversations, } = useConversation(focusedPaneConversationId); + const focusedWorkspaceContents = useWorkspaceContents(focusedPaneConversationId); + const { mayWork: capabilityHasT2I } = useCapabilityTextToImage(); const activeFolderId = useFolderStore(({ enableFolders, folders }) => { @@ -528,6 +531,7 @@ export function AppChat() { )} - {filteredMessages.map((message, idx, { length: count }) => { + {filteredMessages.map((message, idx) => { // Optimization: only memo complete components, or we'd be memoizing garbage const ChatMessageMemoOrNot = !message.pendingIncomplete ? ChatMessageMemo : ChatMessage; @@ -294,7 +296,7 @@ export function ChatMessageList(props: { fitScreen={props.fitScreen} hasInReferenceTo={composerHasInReferenceto} isMobile={props.isMobile} - isBottom={idx === count - 1} + isBottom={idx === filteredMessages.length - 1} isImagining={isImagining} isSpeaking={isSpeaking} showUnsafeHtml={danger_experimentalHtmlWebUi} diff --git a/src/common/stores/workspace/store-client-workspace.ts b/src/common/stores/workspace/store-client-workspace.ts index 49b72afac..e416de097 100644 --- a/src/common/stores/workspace/store-client-workspace.ts +++ b/src/common/stores/workspace/store-client-workspace.ts @@ -111,8 +111,6 @@ export const useClientWorkspaceStore = create }); }); - console.log('workspaceImportAssignmentsFromMessages', newFileIds); - return { liveFilesByWorkspace: { ...state.liveFilesByWorkspace, diff --git a/src/common/stores/workspace/workspace.hooks.ts b/src/common/stores/workspace/workspace.hooks.ts index 04a741ad5..0ae87129c 100644 --- a/src/common/stores/workspace/workspace.hooks.ts +++ b/src/common/stores/workspace/workspace.hooks.ts @@ -8,37 +8,40 @@ import type { DWorkspaceId } from './workspace.types'; import { useClientWorkspaceStore } from './store-client-workspace'; -const stableNoMetadata: LiveFileMetadata[] = []; +export interface WorkspaceContents { + liveFilesMetadata: LiveFileMetadata[]; +} -export function useWorkspaceLiveFilesMetadata(workspaceId: DWorkspaceId | null): LiveFileMetadata[] { +// const stableWorkspace: WorkspaceContents = { +// liveFilesMetadata: [], +// }; + +export function useWorkspaceContents(workspaceId: DWorkspaceId | null): WorkspaceContents | null { // stable reference to the LiveFileIds - const workspaceLiveFileIds: LiveFileId[] | null = useClientWorkspaceStore(useShallow(state => { - // if there's nothing for this workspace, return an empty array - if (!workspaceId || !state.liveFilesByWorkspace[workspaceId]?.length) - return null; - - // get an array of live file ids - return state.liveFilesByWorkspace[workspaceId]; - })); + // - w/out useShallow as updates to the array contents are real + const workspaceLiveFileIds: LiveFileId[] | null = useClientWorkspaceStore(state => + (!workspaceId || !state.liveFilesByWorkspace[workspaceId]?.length) ? null + : state.liveFilesByWorkspace[workspaceId], + ); // reactive stable reference to the LiveFiles - const workspaceLiveFiles: LiveFile[] | null = useLiveFileStore(useShallow(state => { - if (!workspaceLiveFileIds || !workspaceLiveFileIds.length) - return null; + // - with useShallow as map recreates the array every time + const workspaceLiveFiles: LiveFile[] | null = useLiveFileStore(useShallow(state => + !workspaceLiveFileIds?.length ? null + : workspaceLiveFileIds.map(id => state.liveFiles[id]).filter(Boolean), + )); - return workspaceLiveFileIds.map(id => state.liveFiles[id]).filter(Boolean); - })); - - // memoized metadata for files return React.useMemo(() => { - console.log('useWorkspaceLiveFilesMetadata - rememo', workspaceLiveFiles); - + // stable out if (!workspaceLiveFiles || !workspaceLiveFiles.length) - return stableNoMetadata; + return null; // stableWorkspace; - // otherwise return the metadata for the live files + // creation of the woekspace contents (stabilized thought the memo inputs) const { metadataGet } = useLiveFileStore.getState(); - return workspaceLiveFiles.map(lf => metadataGet(lf.id)).filter(Boolean) as LiveFileMetadata[]; + const liveFilesMetadata = workspaceLiveFiles.map(lf => metadataGet(lf.id)).filter(Boolean) as LiveFileMetadata[]; + return { + liveFilesMetadata, + }; }, [workspaceLiveFiles]); }