AppChat: prop-drill Workspace Contents

This commit is contained in:
Enrico Ros
2024-08-08 20:42:04 -07:00
parent c3565d99fa
commit ef30a45388
4 changed files with 33 additions and 26 deletions
+4
View File
@@ -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() {
<ChatMessageList
conversationId={_paneConversationId}
conversationHandler={_paneChatHandler}
workspaceContents={_paneIsFocused ? focusedWorkspaceContents : null}
capabilityHasT2I={capabilityHasT2I}
chatLLMContextTokens={chatLLM?.contextTokens ?? null}
fitScreen={isMobile || isMultiPane}
+4 -2
View File
@@ -9,6 +9,7 @@ import type { DiagramConfig } from '~/modules/aifn/digrams/DiagramsModal';
import type { ConversationHandler } from '~/common/chat-overlay/ConversationHandler';
import type { DConversationId } from '~/common/stores/chat/chat.conversation';
import type { DMessageFragment, DMessageFragmentId } from '~/common/stores/chat/chat.fragments';
import type { WorkspaceContents } from '~/common/stores/workspace/workspace.hooks';
import { InlineError } from '~/common/components/InlineError';
import { ShortcutKey, useGlobalShortcuts } from '~/common/components/shortcuts/useGlobalShortcuts';
import { createDMessageTextContent, DMessageId, DMessageUserFlag, DMetaReferenceItem, messageToggleUserFlag } from '~/common/stores/chat/chat.message';
@@ -33,6 +34,7 @@ import { useChatComposerOverlayStore } from '~/common/chat-overlay/store-chat-ov
export function ChatMessageList(props: {
conversationId: DConversationId | null,
conversationHandler: ConversationHandler | null,
workspaceContents: WorkspaceContents | null,
capabilityHasT2I: boolean,
chatLLMContextTokens: number | null,
fitScreen: boolean,
@@ -271,7 +273,7 @@ export function ChatMessageList(props: {
/>
)}
{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}
@@ -111,8 +111,6 @@ export const useClientWorkspaceStore = create<WorkspaceState & WorkspaceActions>
});
});
console.log('workspaceImportAssignmentsFromMessages', newFileIds);
return {
liveFilesByWorkspace: {
...state.liveFilesByWorkspace,
+25 -22
View File
@@ -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]);
}