From e9dc7359896265027741e63b5f030ac51e933e17 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Fri, 11 Oct 2024 04:02:31 -0700 Subject: [PATCH] Cleanup Stores. [server] --- pages/info/debug.tsx | 9 +- pages/link/share_target.tsx | 2 +- pages/news.tsx | 2 +- src/apps/beam/AppBeam.tsx | 2 +- src/apps/chat/AppChat.tsx | 2 +- src/apps/chat/components/ChatMessageList.tsx | 2 +- src/apps/chat/components/Ephemerals.tsx | 2 +- .../chat/components/composer/Composer.tsx | 7 +- .../llmattachments/LLMAttachmentMenu.tsx | 2 +- .../llmattachments/LLMAttachmentsList.tsx | 2 +- .../components/composer/store-composer.ts | 33 --- .../layout-bar/useFolderDropdown.tsx | 2 +- .../components/layout-drawer/ChatDrawer.tsx | 2 +- .../layout-drawer/ChatDrawerItem.tsx | 2 +- .../layout-drawer/folders/AddFolderButton.tsx | 2 +- .../layout-drawer/folders/ChatFolderList.tsx | 2 +- .../layout-drawer/folders/FolderListItem.tsx | 2 +- .../useChatDrawerRenderItems.tsx | 2 +- src/apps/link-chat/AppLinkChat.tsx | 2 +- src/apps/link-chat/LinkChatDrawer.tsx | 2 +- src/apps/news/news.version.tsx | 45 ---- src/apps/settings-modal/SettingsModal.tsx | 2 +- src/common/app.nav.ts | 2 +- .../attachment-drafts/attachment.pipeline.ts | 2 +- ... store-perchat-attachment-drafts_slice.ts} | 0 .../attachment-drafts/useAttachmentDrafts.tsx | 4 +- .../chat-overlay/ConversationHandler.ts | 6 +- ...ice.ts => store-perchat_composer_slice.ts} | 0 ...e.ts => store-perchat_ephemerals_slice.ts} | 0 ...at-overlay.ts => store-perchat_vanilla.ts} | 6 +- .../layout/optima/portals/OptimaPortalsIn.tsx | 6 +- ...ima-portals.ts => store-layout-portals.ts} | 2 +- .../portals/useOptimaPortalHasInputs.ts | 4 +- .../optima/portals/useOptimaPortalOutRef.ts | 4 +- ...store-optima.ts => store-layout-optima.ts} | 2 +- src/common/layout/optima/useOptima.tsx | 40 +-- src/common/layout/overlays/OverlaysInsert.tsx | 4 +- ...e-overlays.ts => store-layout-overlays.ts} | 2 +- .../layout/overlays/useOverlayComponents.tsx | 4 +- ...onf.ts => store-logic-autoconf_vanilla.ts} | 0 src/common/logic/store-logic-sherpa.ts | 72 ++++++ .../providers/ProviderBootstrapLogic.tsx | 8 +- src/common/state/store-appstate.ts | 25 -- src/common/state/store-ux-labs.ts | 2 +- src/common/stores/chat/chats.converters.ts | 2 +- .../folders/store-chat-folders.ts} | 0 src/common/util/globalStoredList.ts | 232 +++++++++--------- src/modules/beam/gather/beam.gather.ts | 2 +- src/modules/beam/scatter/beam.scatter.ts | 2 +- src/modules/beam/store-beam.hooks.ts | 2 +- ...-beam-vanilla.ts => store-beam_vanilla.ts} | 0 src/modules/trade/link/ChatLinkDetails.tsx | 2 +- src/modules/trade/link/ChatLinkExport.tsx | 2 +- .../{store-link.ts => store-share-link.ts} | 14 +- src/modules/trade/trade.client.ts | 2 +- 55 files changed, 276 insertions(+), 309 deletions(-) delete mode 100644 src/apps/chat/components/composer/store-composer.ts rename src/common/attachment-drafts/{store-attachment-drafts-slice.tsx => store-perchat-attachment-drafts_slice.ts} (100%) rename src/common/chat-overlay/{store-composeroverlay-slice.ts => store-perchat_composer_slice.ts} (100%) rename src/common/chat-overlay/{store-ephemeralsoverlay-slice.ts => store-perchat_ephemerals_slice.ts} (100%) rename src/common/chat-overlay/{store-chat-overlay.ts => store-perchat_vanilla.ts} (92%) rename src/common/layout/optima/portals/{store-optima-portals.ts => store-layout-portals.ts} (97%) rename src/common/layout/optima/{store-optima.ts => store-layout-optima.ts} (97%) rename src/common/layout/overlays/{store-overlays.ts => store-layout-overlays.ts} (97%) rename src/common/logic/{autoconf.ts => store-logic-autoconf_vanilla.ts} (100%) create mode 100644 src/common/logic/store-logic-sherpa.ts delete mode 100644 src/common/state/store-appstate.ts rename src/common/{state/store-folders.ts => stores/folders/store-chat-folders.ts} (100%) rename src/modules/beam/{store-beam-vanilla.ts => store-beam_vanilla.ts} (100%) rename src/modules/trade/link/{store-link.ts => store-share-link.ts} (77%) diff --git a/pages/info/debug.tsx b/pages/info/debug.tsx index 066e70b9a..391d38d35 100644 --- a/pages/info/debug.tsx +++ b/pages/info/debug.tsx @@ -17,16 +17,16 @@ import { Brand } from '~/common/app.config'; import { ROUTE_APP_CHAT, ROUTE_INDEX } from '~/common/app.routes'; // apps access -import { incrementalNewsVersion, useAppNewsStateStore } from '../../src/apps/news/news.version'; +import { incrementalNewsVersion } from '../../src/apps/news/news.version'; // capabilities access import { useCapabilityBrowserSpeechRecognition, useCapabilityElevenLabs, useCapabilityTextToImage } from '~/common/components/useCapabilities'; // stores access import { getLLMsDebugInfo } from '~/common/stores/llms/store-llms'; -import { useAppStateStore } from '~/common/state/store-appstate'; import { useChatStore } from '~/common/stores/chat/store-chats'; -import { useFolderStore } from '~/common/state/store-folders'; +import { useFolderStore } from '~/common/stores/folders/store-chat-folders'; +import { useLogicSherpaStore } from '~/common/logic/store-logic-sherpa'; import { useUXLabsStore } from '~/common/state/store-ux-labs'; // utils access @@ -81,8 +81,7 @@ function AppDebug() { const chatsCount = useChatStore.getState().conversations?.length; const uxLabsExperiments = Object.entries(useUXLabsStore.getState()).filter(([_k, v]) => v === true).map(([k, _]) => k).join(', '); const { folders, enableFolders } = useFolderStore.getState(); - const { lastSeenNewsVersion } = useAppNewsStateStore.getState(); - const { usageCount } = useAppStateStore.getState(); + const { lastSeenNewsVersion, usageCount } = useLogicSherpaStore.getState(); // derived state const cClient = { diff --git a/pages/link/share_target.tsx b/pages/link/share_target.tsx index 0fb8e027a..7c48ee94f 100644 --- a/pages/link/share_target.tsx +++ b/pages/link/share_target.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { Alert, Box, Button, Typography } from '@mui/joy'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; -import { setComposerStartupText } from '../../src/apps/chat/components/composer/store-composer'; +import { setComposerStartupText } from '~/common/logic/store-logic-sherpa'; import { callBrowseFetchPage } from '~/modules/browse/browse.client'; diff --git a/pages/news.tsx b/pages/news.tsx index 96b08dfee..abd9bfbb4 100644 --- a/pages/news.tsx +++ b/pages/news.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import { AppNews } from '../src/apps/news/AppNews'; -import { markNewsAsSeen } from '../src/apps/news/news.version'; +import { markNewsAsSeen } from '~/common/logic/store-logic-sherpa'; import { withNextJSPerPageLayout } from '~/common/layout/withLayout'; diff --git a/src/apps/beam/AppBeam.tsx b/src/apps/beam/AppBeam.tsx index c9e0aa4a4..854f3e3a7 100644 --- a/src/apps/beam/AppBeam.tsx +++ b/src/apps/beam/AppBeam.tsx @@ -5,7 +5,7 @@ import { Box, Button, Typography } from '@mui/joy'; import { BeamStoreApi, useBeamStore } from '~/modules/beam/store-beam.hooks'; import { BeamView } from '~/modules/beam/BeamView'; -import { createBeamVanillaStore } from '~/modules/beam/store-beam-vanilla'; +import { createBeamVanillaStore } from '~/modules/beam/store-beam_vanilla'; import { OptimaToolbarIn } from '~/common/layout/optima/portals/OptimaPortalsIn'; import { createDConversation, DConversation } from '~/common/stores/chat/chat.conversation'; diff --git a/src/apps/chat/AppChat.tsx b/src/apps/chat/AppChat.tsx index 0c3d17b52..6836dac5f 100644 --- a/src/apps/chat/AppChat.tsx +++ b/src/apps/chat/AppChat.tsx @@ -32,7 +32,7 @@ import { getConversation, getConversationSystemPurposeId, useConversation } from import { optimaActions, optimaOpenModels, optimaOpenPreferences, useSetOptimaAppMenu } from '~/common/layout/optima/useOptima'; import { themeBgAppChatComposer } from '~/common/app.theme'; import { useChatLLM } from '~/common/stores/llms/llms.hooks'; -import { useFolderStore } from '~/common/state/store-folders'; +import { useFolderStore } from '~/common/stores/folders/store-chat-folders'; import { useGlobalShortcuts } from '~/common/components/shortcuts/useGlobalShortcuts'; import { useIsMobile, useIsTallScreen } from '~/common/components/useMatchMedia'; import { useOverlayComponents } from '~/common/layout/overlays/useOverlayComponents'; diff --git a/src/apps/chat/components/ChatMessageList.tsx b/src/apps/chat/components/ChatMessageList.tsx index 8c6cec862..9cf24d27f 100644 --- a/src/apps/chat/components/ChatMessageList.tsx +++ b/src/apps/chat/components/ChatMessageList.tsx @@ -20,7 +20,7 @@ import { openFileForAttaching } from '~/common/components/ButtonAttachFiles'; import { optimaOpenPreferences } from '~/common/layout/optima/useOptima'; import { useBrowserTranslationWarning } from '~/common/components/useIsBrowserTranslating'; import { useCapabilityElevenLabs } from '~/common/components/useCapabilities'; -import { useChatOverlayStore } from '~/common/chat-overlay/store-chat-overlay'; +import { useChatOverlayStore } from '~/common/chat-overlay/store-perchat_vanilla'; import { useScrollToBottom } from '~/common/scroll-to-bottom/useScrollToBottom'; import { ChatMessage, ChatMessageMemo } from './message/ChatMessage'; diff --git a/src/apps/chat/components/Ephemerals.tsx b/src/apps/chat/components/Ephemerals.tsx index 594bdcca4..3bfb26f6a 100644 --- a/src/apps/chat/components/Ephemerals.tsx +++ b/src/apps/chat/components/Ephemerals.tsx @@ -9,7 +9,7 @@ import VerticalSplitOutlinedIcon from '@mui/icons-material/VerticalSplitOutlined import { ScaledTextBlockRenderer } from '~/modules/blocks/ScaledTextBlockRenderer'; -import type { DEphemeral } from '~/common/chat-overlay/store-ephemeralsoverlay-slice'; +import type { DEphemeral } from '~/common/chat-overlay/store-perchat_ephemerals_slice'; import { ConversationHandler } from '~/common/chat-overlay/ConversationHandler'; import { adjustContentScaling, ContentScaling, lineHeightChatTextMd } from '~/common/app.theme'; import { useUIPreferencesStore } from '~/common/state/store-ui'; diff --git a/src/apps/chat/components/composer/Composer.tsx b/src/apps/chat/components/composer/Composer.tsx index 2734a0070..15cd332a6 100644 --- a/src/apps/chat/components/composer/Composer.tsx +++ b/src/apps/chat/components/composer/Composer.tsx @@ -41,8 +41,8 @@ import { lineHeightTextareaMd } from '~/common/app.theme'; import { optimaOpenPreferences } from '~/common/layout/optima/useOptima'; import { platformAwareKeystrokes } from '~/common/components/KeyStroke'; import { supportsScreenCapture } from '~/common/util/screenCaptureUtils'; -import { useAppStateStore } from '~/common/state/store-appstate'; -import { useChatComposerOverlayStore } from '~/common/chat-overlay/store-chat-overlay'; +import { useChatComposerOverlayStore } from '~/common/chat-overlay/store-perchat_vanilla'; +import { useComposerStartupText, useLogicSherpaStore } from '~/common/logic/store-logic-sherpa'; import { useDebouncer } from '~/common/components/useDebouncer'; import { useOverlayComponents } from '~/common/layout/overlays/useOverlayComponents'; import { useUICounter, useUIPreferencesStore } from '~/common/state/store-ui'; @@ -75,7 +75,6 @@ import { StatusBar } from '../StatusBar'; import { TokenBadgeMemo } from './tokens/TokenBadge'; import { TokenProgressbarMemo } from './tokens/TokenProgressbar'; import { useComposerDragDrop } from './useComposerDragDrop'; -import { useComposerStartupText } from './store-composer'; const zIndexComposerOverlayMic = 10; @@ -124,7 +123,7 @@ export function Composer(props: { labsShowCost: state.labsShowCost, labsShowShortcutBar: state.labsShowShortcutBar, }))); - const timeToShowTips = useAppStateStore(state => state.usageCount >= 5); + const timeToShowTips = useLogicSherpaStore(state => state.usageCount >= 5); const { novel: explainShiftEnter, touch: touchShiftEnter } = useUICounter('composer-shift-enter'); const { novel: explainAltEnter, touch: touchAltEnter } = useUICounter('composer-alt-enter'); const { novel: explainCtrlEnter, touch: touchCtrlEnter } = useUICounter('composer-ctrl-enter'); diff --git a/src/apps/chat/components/composer/llmattachments/LLMAttachmentMenu.tsx b/src/apps/chat/components/composer/llmattachments/LLMAttachmentMenu.tsx index 92a7960a9..d8a88f44b 100644 --- a/src/apps/chat/components/composer/llmattachments/LLMAttachmentMenu.tsx +++ b/src/apps/chat/components/composer/llmattachments/LLMAttachmentMenu.tsx @@ -23,7 +23,7 @@ import { showImageDataURLInNewTab } from '~/common/util/imageUtils'; import { useUIPreferencesStore } from '~/common/state/store-ui'; import type { AttachmentDraftId } from '~/common/attachment-drafts/attachment.types'; -import type { AttachmentDraftsStoreApi } from '~/common/attachment-drafts/store-attachment-drafts-slice'; +import type { AttachmentDraftsStoreApi } from '~/common/attachment-drafts/store-perchat-attachment-drafts_slice'; import type { LLMAttachmentDraft } from './useLLMAttachmentDrafts'; import type { LLMAttachmentDraftsAction } from './LLMAttachmentsList'; diff --git a/src/apps/chat/components/composer/llmattachments/LLMAttachmentsList.tsx b/src/apps/chat/components/composer/llmattachments/LLMAttachmentsList.tsx index e40930669..facbdb8e8 100644 --- a/src/apps/chat/components/composer/llmattachments/LLMAttachmentsList.tsx +++ b/src/apps/chat/components/composer/llmattachments/LLMAttachmentsList.tsx @@ -14,7 +14,7 @@ import { ConfirmationModal } from '~/common/components/modals/ConfirmationModal' import { useOverlayComponents } from '~/common/layout/overlays/useOverlayComponents'; import type { AttachmentDraftId } from '~/common/attachment-drafts/attachment.types'; -import type { AttachmentDraftsStoreApi } from '~/common/attachment-drafts/store-attachment-drafts-slice'; +import type { AttachmentDraftsStoreApi } from '~/common/attachment-drafts/store-perchat-attachment-drafts_slice'; import type { DMessageImageRefPart } from '~/common/stores/chat/chat.fragments'; import { ViewImageRefPartModal } from '../../message/fragments-content/ViewImageRefPartModal'; diff --git a/src/apps/chat/components/composer/store-composer.ts b/src/apps/chat/components/composer/store-composer.ts deleted file mode 100644 index 24bffc9e0..000000000 --- a/src/apps/chat/components/composer/store-composer.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { create } from 'zustand'; -import { persist } from 'zustand/middleware'; - - -/// Composer Store - -interface ComposerStore { - - startupText: string | null; // if not null, the composer will load this text at startup - setStartupText: (text: string | null) => void; - -} - -const useComposerStore = create()( - persist((set, _get) => ({ - - startupText: null, - setStartupText: (text: string | null) => set({ startupText: text }), - - }), - { - name: 'app-composer', - version: 1, - }), -); - -export const setComposerStartupText = (text: string | null) => - useComposerStore.getState().setStartupText(text); - -export const useComposerStartupText = (): [string | null, (text: string | null) => void] => { - const text = useComposerStore(state => state.startupText); - return [text, useComposerStore.getState().setStartupText]; -}; \ No newline at end of file diff --git a/src/apps/chat/components/layout-bar/useFolderDropdown.tsx b/src/apps/chat/components/layout-bar/useFolderDropdown.tsx index 9f955ec68..a71d4035e 100644 --- a/src/apps/chat/components/layout-bar/useFolderDropdown.tsx +++ b/src/apps/chat/components/layout-bar/useFolderDropdown.tsx @@ -5,7 +5,7 @@ import FolderIcon from '@mui/icons-material/Folder'; import { DConversationId } from '~/common/stores/chat/chat.conversation'; import { OptimaBarDropdownMemo, OptimaDropdownItems } from '~/common/layout/optima/bar/OptimaBarDropdown'; -import { useFolderStore } from '~/common/state/store-folders'; +import { useFolderStore } from '~/common/stores/folders/store-chat-folders'; export const ClearFolderText = 'No Folder'; diff --git a/src/apps/chat/components/layout-drawer/ChatDrawer.tsx b/src/apps/chat/components/layout-drawer/ChatDrawer.tsx index 73c3c47f5..d0af4ee78 100644 --- a/src/apps/chat/components/layout-drawer/ChatDrawer.tsx +++ b/src/apps/chat/components/layout-drawer/ChatDrawer.tsx @@ -16,7 +16,7 @@ import StarOutlineRoundedIcon from '@mui/icons-material/StarOutlineRounded'; import type { DConversationId } from '~/common/stores/chat/chat.conversation'; import { CloseableMenu } from '~/common/components/CloseableMenu'; -import { DFolder, useFolderStore } from '~/common/state/store-folders'; +import { DFolder, useFolderStore } from '~/common/stores/folders/store-chat-folders'; import { DebouncedInputMemo } from '~/common/components/DebouncedInput'; import { FoldersToggleOff } from '~/common/components/icons/FoldersToggleOff'; import { FoldersToggleOn } from '~/common/components/icons/FoldersToggleOn'; diff --git a/src/apps/chat/components/layout-drawer/ChatDrawerItem.tsx b/src/apps/chat/components/layout-drawer/ChatDrawerItem.tsx index ff95ee4b2..f41579960 100644 --- a/src/apps/chat/components/layout-drawer/ChatDrawerItem.tsx +++ b/src/apps/chat/components/layout-drawer/ChatDrawerItem.tsx @@ -17,7 +17,7 @@ import { SystemPurposeId, SystemPurposes } from '../../../../data'; import { autoConversationTitle } from '~/modules/aifn/autotitle/autoTitle'; import type { DConversationId } from '~/common/stores/chat/chat.conversation'; -import type { DFolder } from '~/common/state/store-folders'; +import type { DFolder } from '~/common/stores/folders/store-chat-folders'; import { ANIM_BUSY_TYPING } from '~/common/util/dMessageUtils'; import { InlineTextarea } from '~/common/components/InlineTextarea'; import { isDeepEqual } from '~/common/util/hooks/useDeep'; diff --git a/src/apps/chat/components/layout-drawer/folders/AddFolderButton.tsx b/src/apps/chat/components/layout-drawer/folders/AddFolderButton.tsx index bcdf2ec36..f8bb580a3 100644 --- a/src/apps/chat/components/layout-drawer/folders/AddFolderButton.tsx +++ b/src/apps/chat/components/layout-drawer/folders/AddFolderButton.tsx @@ -5,7 +5,7 @@ import AddIcon from '@mui/icons-material/Add'; import FolderIcon from '@mui/icons-material/Folder'; import { InlineTextarea } from '~/common/components/InlineTextarea'; -import { getRotatingFolderColor, useFolderStore } from '~/common/state/store-folders'; +import { getRotatingFolderColor, useFolderStore } from '~/common/stores/folders/store-chat-folders'; export function AddFolderButton() { diff --git a/src/apps/chat/components/layout-drawer/folders/ChatFolderList.tsx b/src/apps/chat/components/layout-drawer/folders/ChatFolderList.tsx index 35806d584..4deecb88f 100644 --- a/src/apps/chat/components/layout-drawer/folders/ChatFolderList.tsx +++ b/src/apps/chat/components/layout-drawer/folders/ChatFolderList.tsx @@ -6,7 +6,7 @@ import { List, ListItem, ListItemButton, ListItemDecorator, Sheet } from '@mui/j import FolderIcon from '@mui/icons-material/Folder'; import { ContentScaling, themeScalingMap } from '~/common/app.theme'; -import { DFolder, useFolderStore } from '~/common/state/store-folders'; +import { DFolder, useFolderStore } from '~/common/stores/folders/store-chat-folders'; import { StrictModeDroppable } from '~/common/components/StrictModeDroppable'; import { AddFolderButton } from './AddFolderButton'; diff --git a/src/apps/chat/components/layout-drawer/folders/FolderListItem.tsx b/src/apps/chat/components/layout-drawer/folders/FolderListItem.tsx index ecfbb44bc..36618f64a 100644 --- a/src/apps/chat/components/layout-drawer/folders/FolderListItem.tsx +++ b/src/apps/chat/components/layout-drawer/folders/FolderListItem.tsx @@ -10,7 +10,7 @@ import FolderIcon from '@mui/icons-material/Folder'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { CloseableMenu } from '~/common/components/CloseableMenu'; -import { DFolder, FOLDERS_COLOR_PALETTE, useFolderStore } from '~/common/state/store-folders'; +import { DFolder, FOLDERS_COLOR_PALETTE, useFolderStore } from '~/common/stores/folders/store-chat-folders'; import { InlineTextarea } from '~/common/components/InlineTextarea'; import { themeZIndexOverMobileDrawer } from '~/common/app.theme'; diff --git a/src/apps/chat/components/layout-drawer/useChatDrawerRenderItems.tsx b/src/apps/chat/components/layout-drawer/useChatDrawerRenderItems.tsx index 8e4d3a0bb..401e48720 100644 --- a/src/apps/chat/components/layout-drawer/useChatDrawerRenderItems.tsx +++ b/src/apps/chat/components/layout-drawer/useChatDrawerRenderItems.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import type { DFolder } from '~/common/state/store-folders'; +import type { DFolder } from '~/common/stores/folders/store-chat-folders'; import { DMessage, DMessageUserFlag, MESSAGE_FLAG_STARRED, messageFragmentsReduceText, messageHasUserFlag, messageUserFlagToEmoji } from '~/common/stores/chat/chat.message'; import { conversationTitle, DConversationId } from '~/common/stores/chat/chat.conversation'; import { getLocalMidnightInUTCTimestamp, getTimeBucketEn } from '~/common/util/timeUtils'; diff --git a/src/apps/link-chat/AppLinkChat.tsx b/src/apps/link-chat/AppLinkChat.tsx index 805f8ce22..2e9097fa4 100644 --- a/src/apps/link-chat/AppLinkChat.tsx +++ b/src/apps/link-chat/AppLinkChat.tsx @@ -5,7 +5,7 @@ import { useQuery } from '@tanstack/react-query'; import { Box, Button, Card, CardContent, Divider, Input, Typography } from '@mui/joy'; import WarningRoundedIcon from '@mui/icons-material/WarningRounded'; -import { forgetChatLinkItem, useSharedChatLinkItems } from '~/modules/trade/link/store-link'; +import { forgetChatLinkItem, useSharedChatLinkItems } from '~/modules/trade/link/store-share-link'; import { Brand } from '~/common/app.config'; import { ConfirmationModal } from '~/common/components/modals/ConfirmationModal'; diff --git a/src/apps/link-chat/LinkChatDrawer.tsx b/src/apps/link-chat/LinkChatDrawer.tsx index f0e2ad635..db4a813dc 100644 --- a/src/apps/link-chat/LinkChatDrawer.tsx +++ b/src/apps/link-chat/LinkChatDrawer.tsx @@ -4,7 +4,7 @@ import TimeAgo from 'react-timeago'; import { Box, ListDivider, ListItem, ListItemButton, ListItemDecorator, Switch, Typography } from '@mui/joy'; import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; -import type { SharedChatLinkItem } from '~/modules/trade/link/store-link'; +import type { SharedChatLinkItem } from '~/modules/trade/link/store-share-link'; import { Link } from '~/common/components/Link'; import { OptimaDrawerHeader } from '~/common/layout/optima/drawer/OptimaDrawerHeader'; diff --git a/src/apps/news/news.version.tsx b/src/apps/news/news.version.tsx index 7b03ed020..775403fe0 100644 --- a/src/apps/news/news.version.tsx +++ b/src/apps/news/news.version.tsx @@ -1,49 +1,4 @@ // NOTE: this is a separate file to help with bundle tracing, as it's included by the ProviderBootstrapLogic (i.e. by All pages) -import { create } from 'zustand'; -import { persist } from 'zustand/middleware'; - -import { useAppStateStore } from '~/common/state/store-appstate'; - - // update this variable every time you want to broadcast a new version to clients export const incrementalNewsVersion: number = 16.1; // not notifying for 1.16.8 - - -interface NewsState { - lastSeenNewsVersion: number; -} - -export const useAppNewsStateStore = create()( - persist( - (set) => ({ - lastSeenNewsVersion: 0, - }), - { - name: 'app-news', - }, - ), -); - - -export function shallRedirectToNews() { - const { lastSeenNewsVersion } = useAppNewsStateStore.getState(); - const { usageCount } = useAppStateStore.getState(); - const isNewsOutdated = (lastSeenNewsVersion || 0) < incrementalNewsVersion; - return isNewsOutdated && usageCount > 2; -} - -export function markNewsAsSeen() { - useAppNewsStateStore.setState({ lastSeenNewsVersion: incrementalNewsVersion }); -} - - -// NOTE: moved to the ProviderBootstrapLogic, and to the functions above - we used to have hoooks for switching to the news -/*export function useRedirectToNewsOnUpdates() { - React.useEffect(() => { - const { usageCount, lastSeenNewsVersion } = useAppStateStore.getState(); - const isNewsOutdated = (lastSeenNewsVersion || 0) < incrementalVersion; - if (isNewsOutdated && usageCount > 2) - return runWhenIdle(navigateToNews, 20000); - }, []); -}*/ diff --git a/src/apps/settings-modal/SettingsModal.tsx b/src/apps/settings-modal/SettingsModal.tsx index 3a5742e4c..a30680539 100644 --- a/src/apps/settings-modal/SettingsModal.tsx +++ b/src/apps/settings-modal/SettingsModal.tsx @@ -14,7 +14,7 @@ import { GoogleSearchSettings } from '~/modules/google/GoogleSearchSettings'; import { ProdiaSettings } from '~/modules/t2i/prodia/ProdiaSettings'; import { T2ISettings } from '~/modules/t2i/T2ISettings'; -import type { PreferencesTabId } from '~/common/layout/optima/store-optima'; +import type { PreferencesTabId } from '~/common/layout/optima/store-layout-optima'; import { GoodModal } from '~/common/components/modals/GoodModal'; import { useIsMobile } from '~/common/components/useMatchMedia'; diff --git a/src/common/app.nav.ts b/src/common/app.nav.ts index 83a81ac61..4a72cb642 100644 --- a/src/common/app.nav.ts +++ b/src/common/app.nav.ts @@ -32,7 +32,7 @@ import SettingsIcon from '@mui/icons-material/Settings'; import { Brand } from '~/common/app.config'; import { ChatBeamIcon } from '~/common/components/icons/ChatBeamIcon'; -import { hasNoChatLinkItems } from '~/modules/trade/link/store-link'; +import { hasNoChatLinkItems } from '~/modules/trade/link/store-share-link'; // enable to show all items, for layout development diff --git a/src/common/attachment-drafts/attachment.pipeline.ts b/src/common/attachment-drafts/attachment.pipeline.ts index 7bdfb41f2..73563a061 100644 --- a/src/common/attachment-drafts/attachment.pipeline.ts +++ b/src/common/attachment-drafts/attachment.pipeline.ts @@ -13,7 +13,7 @@ import { pdfToImageDataURLs, pdfToText } from '~/common/util/pdfUtils'; import { createDMessageDataInlineText, createDocAttachmentFragment, DMessageAttachmentFragment, DMessageDataInline, DMessageDocPart, DVMimeType, isContentOrAttachmentFragment, isDocPart, specialContentPartToDocAttachmentFragment } from '~/common/stores/chat/chat.fragments'; import type { AttachmentCreationOptions, AttachmentDraft, AttachmentDraftConverter, AttachmentDraftId, AttachmentDraftInput, AttachmentDraftSource, AttachmentDraftSourceOriginFile, DraftEgoFragmentsInputData, DraftWebInputData, DraftYouTubeInputData } from './attachment.types'; -import type { AttachmentsDraftsStore } from './store-attachment-drafts-slice'; +import type { AttachmentsDraftsStore } from './store-perchat-attachment-drafts_slice'; import { attachmentGetLiveFileId, attachmentSourceSupportsLiveFile } from './attachment.livefile'; import { guessInputContentTypeFromMime, heuristicMimeTypeFixup, mimeTypeIsDocX, mimeTypeIsPDF, mimeTypeIsPlainText, mimeTypeIsSupportedImage, reverseLookupMimeType } from './attachment.mimetypes'; import { imageDataToImageAttachmentFragmentViaDBlob } from './attachment.dblobs'; diff --git a/src/common/attachment-drafts/store-attachment-drafts-slice.tsx b/src/common/attachment-drafts/store-perchat-attachment-drafts_slice.ts similarity index 100% rename from src/common/attachment-drafts/store-attachment-drafts-slice.tsx rename to src/common/attachment-drafts/store-perchat-attachment-drafts_slice.ts diff --git a/src/common/attachment-drafts/useAttachmentDrafts.tsx b/src/common/attachment-drafts/useAttachmentDrafts.tsx index 14d71faff..dfdaa6abe 100644 --- a/src/common/attachment-drafts/useAttachmentDrafts.tsx +++ b/src/common/attachment-drafts/useAttachmentDrafts.tsx @@ -10,10 +10,10 @@ import type { DConversationId } from '~/common/stores/chat/chat.conversation'; import type { DMessageFragment } from '~/common/stores/chat/chat.fragments'; import type { DMessageId } from '~/common/stores/chat/chat.message'; import { getAllFilesFromDirectoryRecursively, getDataTransferFilesOrPromises } from '~/common/util/fileSystemUtils'; -import { useChatAttachmentsStore } from '~/common/chat-overlay/store-chat-overlay'; +import { useChatAttachmentsStore } from '~/common/chat-overlay/store-perchat_vanilla'; import type { AttachmentDraftSourceOriginDTO, AttachmentDraftSourceOriginFile } from './attachment.types'; -import type { AttachmentDraftsStoreApi } from './store-attachment-drafts-slice'; +import type { AttachmentDraftsStoreApi } from './store-perchat-attachment-drafts_slice'; // enable to debug operations diff --git a/src/common/chat-overlay/ConversationHandler.ts b/src/common/chat-overlay/ConversationHandler.ts index 7ed501031..be3476036 100644 --- a/src/common/chat-overlay/ConversationHandler.ts +++ b/src/common/chat-overlay/ConversationHandler.ts @@ -3,7 +3,7 @@ import { bareBonesPromptMixer } from '~/modules/persona/pmix/pmix'; import { SystemPurposes } from '../../data'; import { gcChatImageAssets } from '../../apps/chat/editors/image-generate'; -import { createBeamVanillaStore } from '~/modules/beam/store-beam-vanilla'; +import { createBeamVanillaStore } from '~/modules/beam/store-beam_vanilla'; import type { DConversationId } from '~/common/stores/chat/chat.conversation'; import type { DLLMId } from '~/common/stores/llms/llms.types'; @@ -14,8 +14,8 @@ import { getChatLLMId } from '~/common/stores/llms/store-llms'; import { getChatAutoAI } from '../../apps/chat/store-app-chat'; -import { createDEphemeral } from './store-ephemeralsoverlay-slice'; -import { createPerChatVanillaStore } from './store-chat-overlay'; +import { createDEphemeral } from './store-perchat_ephemerals_slice'; +import { createPerChatVanillaStore } from './store-perchat_vanilla'; // configuration diff --git a/src/common/chat-overlay/store-composeroverlay-slice.ts b/src/common/chat-overlay/store-perchat_composer_slice.ts similarity index 100% rename from src/common/chat-overlay/store-composeroverlay-slice.ts rename to src/common/chat-overlay/store-perchat_composer_slice.ts diff --git a/src/common/chat-overlay/store-ephemeralsoverlay-slice.ts b/src/common/chat-overlay/store-perchat_ephemerals_slice.ts similarity index 100% rename from src/common/chat-overlay/store-ephemeralsoverlay-slice.ts rename to src/common/chat-overlay/store-perchat_ephemerals_slice.ts diff --git a/src/common/chat-overlay/store-chat-overlay.ts b/src/common/chat-overlay/store-perchat_vanilla.ts similarity index 92% rename from src/common/chat-overlay/store-chat-overlay.ts rename to src/common/chat-overlay/store-perchat_vanilla.ts index 17faa7683..2d9fd841d 100644 --- a/src/common/chat-overlay/store-chat-overlay.ts +++ b/src/common/chat-overlay/store-perchat_vanilla.ts @@ -1,9 +1,9 @@ import { StoreApi, useStore } from 'zustand'; import { createStore as createVanillaStore } from 'zustand/vanilla'; -import { AttachmentsDraftsStore, createAttachmentDraftsStoreSlice } from '~/common/attachment-drafts/store-attachment-drafts-slice'; -import { ComposerOverlayStore, createComposerOverlayStoreSlice } from './store-composeroverlay-slice'; -import { createEphemeralsOverlayStoreSlice, EphemeralsOverlayStore } from './store-ephemeralsoverlay-slice'; +import { AttachmentsDraftsStore, createAttachmentDraftsStoreSlice } from '~/common/attachment-drafts/store-perchat-attachment-drafts_slice'; +import { ComposerOverlayStore, createComposerOverlayStoreSlice } from './store-perchat_composer_slice'; +import { createEphemeralsOverlayStoreSlice, EphemeralsOverlayStore } from './store-perchat_ephemerals_slice'; /* Per-chat overlay store, combining all the slices. diff --git a/src/common/layout/optima/portals/OptimaPortalsIn.tsx b/src/common/layout/optima/portals/OptimaPortalsIn.tsx index c0fdbe246..27fb527d6 100644 --- a/src/common/layout/optima/portals/OptimaPortalsIn.tsx +++ b/src/common/layout/optima/portals/OptimaPortalsIn.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { createPortal } from 'react-dom'; -import { OptimaPortalId, useOptimaPortalsStore } from './store-optima-portals'; +import { OptimaPortalId, useLayoutPortalsStore } from './store-layout-portals'; export function OptimaDrawerIn(props: { children: React.ReactNode }) { @@ -25,11 +25,11 @@ export function OptimaToolbarIn(props: { children: React.ReactNode }) { */ function useOptimaPortalTargetElement(targetPortalId: OptimaPortalId) { // get the output element - const targetPortalEl = useOptimaPortalsStore(state => state.portals[targetPortalId]?.element ?? null); + const targetPortalEl = useLayoutPortalsStore(state => state.portals[targetPortalId]?.element ?? null); // increment/decrement input count React.useEffect(() => { - const { incrementInputs, decrementInputs } = useOptimaPortalsStore.getState(); + const { incrementInputs, decrementInputs } = useLayoutPortalsStore.getState(); incrementInputs(targetPortalId); return () => decrementInputs(targetPortalId); }, [targetPortalId]); diff --git a/src/common/layout/optima/portals/store-optima-portals.ts b/src/common/layout/optima/portals/store-layout-portals.ts similarity index 97% rename from src/common/layout/optima/portals/store-optima-portals.ts rename to src/common/layout/optima/portals/store-layout-portals.ts index 3a7f62939..7b6ed9a45 100644 --- a/src/common/layout/optima/portals/store-optima-portals.ts +++ b/src/common/layout/optima/portals/store-layout-portals.ts @@ -30,7 +30,7 @@ interface OptimaPortalActions { } -export const useOptimaPortalsStore = create((_set, _get) => ({ +export const useLayoutPortalsStore = create((_set, _get) => ({ // init state portals: { diff --git a/src/common/layout/optima/portals/useOptimaPortalHasInputs.ts b/src/common/layout/optima/portals/useOptimaPortalHasInputs.ts index 0af4fe499..680072e82 100644 --- a/src/common/layout/optima/portals/useOptimaPortalHasInputs.ts +++ b/src/common/layout/optima/portals/useOptimaPortalHasInputs.ts @@ -1,5 +1,5 @@ -import { OptimaPortalId, useOptimaPortalsStore } from './store-optima-portals'; +import { OptimaPortalId, useLayoutPortalsStore } from './store-layout-portals'; export function useOptimaPortalHasInputs(portalTargetId: OptimaPortalId) { - return useOptimaPortalsStore(state => state.portals[portalTargetId]?.inputs >= 1); + return useLayoutPortalsStore(state => state.portals[portalTargetId]?.inputs >= 1); } diff --git a/src/common/layout/optima/portals/useOptimaPortalOutRef.ts b/src/common/layout/optima/portals/useOptimaPortalOutRef.ts index 64bb108da..062a1935a 100644 --- a/src/common/layout/optima/portals/useOptimaPortalOutRef.ts +++ b/src/common/layout/optima/portals/useOptimaPortalOutRef.ts @@ -1,6 +1,6 @@ import * as React from 'react'; -import { OptimaPortalId, useOptimaPortalsStore } from './store-optima-portals'; +import { OptimaPortalId, useLayoutPortalsStore } from './store-layout-portals'; /** @@ -20,7 +20,7 @@ export function useOptimaPortalOutRef(portalTargetId: OptimaPortalId, debugCalle const ref = React.useRef(null); React.useLayoutEffect(() => { - const { setElement } = useOptimaPortalsStore.getState(); + const { setElement } = useLayoutPortalsStore.getState(); if (!ref.current) { console.warn(`useOptimaPortalOut: ref.current is null for type ${portalTargetId} (called by ${debugCallerName})`); } else { diff --git a/src/common/layout/optima/store-optima.ts b/src/common/layout/optima/store-layout-optima.ts similarity index 97% rename from src/common/layout/optima/store-optima.ts rename to src/common/layout/optima/store-layout-optima.ts index 44a87e2eb..a987f870d 100644 --- a/src/common/layout/optima/store-optima.ts +++ b/src/common/layout/optima/store-layout-optima.ts @@ -101,7 +101,7 @@ export interface OptimaActions { } -export const useOptimaStore = create((_set, _get) => ({ +export const useLayoutOptimaStore = create((_set, _get) => ({ ...initialState, diff --git a/src/common/layout/optima/useOptima.tsx b/src/common/layout/optima/useOptima.tsx index a154bb70d..36bb8b0ba 100644 --- a/src/common/layout/optima/useOptima.tsx +++ b/src/common/layout/optima/useOptima.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { useShallow } from 'zustand/react/shallow'; -import { OptimaActions, PreferencesTabId, useOptimaStore } from './store-optima'; +import { OptimaActions, PreferencesTabId, useLayoutOptimaStore } from './store-layout-optima'; // configuration @@ -16,52 +16,52 @@ export function optimaActions(): Omit { - return useOptimaStore.getState(); + return useLayoutOptimaStore.getState(); } export function optimaCloseDrawer() { - useOptimaStore.getState().closeDrawer(); + useLayoutOptimaStore.getState().closeDrawer(); } export function optimaOpenDrawer(event?: React.MouseEvent) { _eatMouseEvent(event); - useOptimaStore.getState().openDrawer(); + useLayoutOptimaStore.getState().openDrawer(); } export function optimaToggleDrawer(event?: React.MouseEvent) { _eatMouseEvent(event); - useOptimaStore.getState().toggleDrawer(); + useLayoutOptimaStore.getState().toggleDrawer(); } export function optimaCloseAppMenu() { - useOptimaStore.getState().closeAppMenu(); + useLayoutOptimaStore.getState().closeAppMenu(); } export function optimaOpenAppMenu(event?: React.MouseEvent) { _eatMouseEvent(event); - useOptimaStore.getState().openAppMenu(); + useLayoutOptimaStore.getState().openAppMenu(); } export function optimaClosePanel() { - useOptimaStore.getState().closePanel(); + useLayoutOptimaStore.getState().closePanel(); } export function optimaOpenPanel(event?: React.MouseEvent) { _eatMouseEvent(event); - useOptimaStore.getState().openPanel(); + useLayoutOptimaStore.getState().openPanel(); } export function optimaTogglePanel(event?: React.MouseEvent) { _eatMouseEvent(event); - useOptimaStore.getState().togglePanel(); + useLayoutOptimaStore.getState().togglePanel(); } export function optimaOpenModels() { - useOptimaStore.getState().openModels(); + useLayoutOptimaStore.getState().openModels(); } export function optimaOpenPreferences(changeTab?: PreferencesTabId) { - useOptimaStore.getState().openPreferences(changeTab); + useLayoutOptimaStore.getState().openPreferences(changeTab); } function _eatMouseEvent(event?: (React.MouseEvent | React.TouchEvent)) { @@ -75,19 +75,19 @@ function _eatMouseEvent(event?: (React.MouseEvent | React.TouchEvent)) { /// React to UI State (mainly within the Optima Layout itself) export function useOptimaDrawerOpen() { - return useOptimaStore(({ drawerIsOpen }) => drawerIsOpen); + return useLayoutOptimaStore(({ drawerIsOpen }) => drawerIsOpen); } export function useOptimaAppMenuOpen() { - return useOptimaStore(({ appMenuIsOpen }) => appMenuIsOpen); + return useLayoutOptimaStore(({ appMenuIsOpen }) => appMenuIsOpen); } export function useOptimaPanelOpen() { - return useOptimaStore(({ panelIsOpen }) => panelIsOpen); + return useLayoutOptimaStore(({ panelIsOpen }) => panelIsOpen); } export function useOptimaModalsState() { - return useOptimaStore(useShallow(state => ({ + return useLayoutOptimaStore(useShallow(state => ({ showKeyboardShortcuts: state.showKeyboardShortcuts, showPreferences: state.showPreferences, preferencesTab: state.preferencesTab, @@ -95,7 +95,7 @@ export function useOptimaModalsState() { } export function useOptimaModelsModalsState() { - return useOptimaStore(useShallow(state => ({ + return useLayoutOptimaStore(useShallow(state => ({ showModelOptions: state.showModelOptions, showModels: state.showModels, showPreferences: state.showPreferences, @@ -109,7 +109,7 @@ export function useOptimaModelsModalsState() { * Reacts the App Menu component */ export function useOptimaAppMenu() { - return useOptimaStore(state => state.menuComponent); + return useLayoutOptimaStore(state => state.menuComponent); } /** @@ -118,12 +118,12 @@ export function useOptimaAppMenu() { export function useSetOptimaAppMenu(menu: React.ReactNode, debugCallerName: string) { React.useEffect(() => { if (DEBUG_OPTIMA_PLUGGING) console.log(' +PLUG layout', debugCallerName); - useOptimaStore.setState({ + useLayoutOptimaStore.setState({ menuComponent: menu, }); return () => { if (DEBUG_OPTIMA_PLUGGING) console.log(' -UNplug layout', debugCallerName); - useOptimaStore.setState({ + useLayoutOptimaStore.setState({ menuComponent: null, }); }; diff --git a/src/common/layout/overlays/OverlaysInsert.tsx b/src/common/layout/overlays/OverlaysInsert.tsx index 8e3d682ac..5b6721d97 100644 --- a/src/common/layout/overlays/OverlaysInsert.tsx +++ b/src/common/layout/overlays/OverlaysInsert.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; -import { useOverlayStore } from './store-overlays'; +import { useLayoutOverlaysStore } from './store-layout-overlays'; export const OverlaysInsert: React.FC = () => { // external state - const overlays = useOverlayStore(state => state.overlays); + const overlays = useLayoutOverlaysStore(state => state.overlays); // Transient Overlays / Modals return overlays.map(({ id, component }) => ( diff --git a/src/common/layout/overlays/store-overlays.ts b/src/common/layout/overlays/store-layout-overlays.ts similarity index 97% rename from src/common/layout/overlays/store-overlays.ts rename to src/common/layout/overlays/store-layout-overlays.ts index 9d69de5ce..cd1891ffe 100644 --- a/src/common/layout/overlays/store-overlays.ts +++ b/src/common/layout/overlays/store-layout-overlays.ts @@ -38,7 +38,7 @@ interface OverlayActions { // removeOverlaysBy: (predicate: (item: OverlayItem) => boolean) => void; } -export const useOverlayStore = create((set, get) => ({ +export const useLayoutOverlaysStore = create((set, get) => ({ // state overlays: [], diff --git a/src/common/layout/overlays/useOverlayComponents.tsx b/src/common/layout/overlays/useOverlayComponents.tsx index 55f9184a2..3ce5e6326 100644 --- a/src/common/layout/overlays/useOverlayComponents.tsx +++ b/src/common/layout/overlays/useOverlayComponents.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { GlobalOverlayId, useOverlayStore } from './store-overlays'; +import { GlobalOverlayId, useLayoutOverlaysStore } from './store-layout-overlays'; enum OverlayCloseReason { @@ -65,7 +65,7 @@ export function useOverlayComponents(): { ): Promise => { return new Promise((pResolve, pReject) => { - const { appendOverlay, overlayExists, overlayToFront, removeOverlay } = useOverlayStore.getState(); + const { appendOverlay, overlayExists, overlayToFront, removeOverlay } = useLayoutOverlaysStore.getState(); // Check if the overlay already exists and exit early // This is like doReject, but doesn't remove the overlay as we don't insert it diff --git a/src/common/logic/autoconf.ts b/src/common/logic/store-logic-autoconf_vanilla.ts similarity index 100% rename from src/common/logic/autoconf.ts rename to src/common/logic/store-logic-autoconf_vanilla.ts diff --git a/src/common/logic/store-logic-sherpa.ts b/src/common/logic/store-logic-sherpa.ts new file mode 100644 index 000000000..4d5af1e60 --- /dev/null +++ b/src/common/logic/store-logic-sherpa.ts @@ -0,0 +1,72 @@ +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; +import { useShallow } from 'zustand/react/shallow'; + +import { incrementalNewsVersion } from '../../apps/news/news.version'; + + +// Sherpa State: navigation thought the app, remembers the counters for progressive disclosure of complex features + +interface SherpaStore { + + usageCount: number; + + lastSeenNewsVersion: number; + + chatComposerPrefill: string | null; // if not null, the composer will load this text at startup + setChatComposerPrefill: (text: string | null) => void; + +} + +export const useLogicSherpaStore = create()( + persist( + (set) => ({ + + usageCount: 0, + + lastSeenNewsVersion: 0, + + chatComposerPrefill: null, + setChatComposerPrefill: (text) => set({ chatComposerPrefill: text }), + + }), + { + name: 'app-state', + }, + ), +); + +// increment the usage count +useLogicSherpaStore.setState((state) => ({ usageCount: (state.usageCount || 0) + 1 })); + + +/// News Navigation + +export function shallRedirectToNews() { + const { lastSeenNewsVersion, usageCount } = useLogicSherpaStore.getState(); + + // first time user - ignore the news up to the next refresh + if (lastSeenNewsVersion === 0) { + markNewsAsSeen(); + return false; + } + + // if the news is outdated and the user has used the app a few times, show the news + const isNewsOutdated = (lastSeenNewsVersion || 0) < incrementalNewsVersion; + return isNewsOutdated && usageCount >= 3; +} + +export function markNewsAsSeen() { + useLogicSherpaStore.setState({ lastSeenNewsVersion: incrementalNewsVersion }); +} + + +// Chat Composer Prefill + +export const setComposerStartupText = (text: string | null) => { + useLogicSherpaStore.getState().setChatComposerPrefill(text); +}; + +export const useComposerStartupText = (): [string | null, (text: string | null) => void] => { + return useLogicSherpaStore(useShallow(state => [state.chatComposerPrefill, state.setChatComposerPrefill])); +}; diff --git a/src/common/providers/ProviderBootstrapLogic.tsx b/src/common/providers/ProviderBootstrapLogic.tsx index 2ba7cc9de..eb53760ee 100644 --- a/src/common/providers/ProviderBootstrapLogic.tsx +++ b/src/common/providers/ProviderBootstrapLogic.tsx @@ -3,11 +3,11 @@ import { useRouter } from 'next/router'; import { gcAttachmentDBlobs } from '~/common/attachment-drafts/attachment.dblobs'; import { gcChatImageAssets } from '../../apps/chat/editors/image-generate'; -import { markNewsAsSeen, shallRedirectToNews } from '../../apps/news/news.version'; -import { autoConfInitiateConfiguration } from '~/common/logic/autoconf'; -import { navigateToNews, ROUTE_APP_CHAT } from '~/common/app.routes'; +import { autoConfInitiateConfiguration } from '~/common/logic/store-logic-autoconf_vanilla'; import { estimatePersistentStorageOrThrow, requestPersistentStorage } from '~/common/util/storageUtils'; +import { markNewsAsSeen, shallRedirectToNews } from '~/common/logic/store-logic-sherpa'; +import { navigateToNews, ROUTE_APP_CHAT } from '~/common/app.routes'; import { useNextLoadProgress } from '~/common/components/useNextLoadProgress'; @@ -20,7 +20,7 @@ export function ProviderBootstrapLogic(props: { children: React.ReactNode }) { useNextLoadProgress(route, events); - // [bootup] logic + // [boot-up] logic const isOnChat = route === ROUTE_APP_CHAT; const doRedirectToNews = isOnChat && shallRedirectToNews(); diff --git a/src/common/state/store-appstate.ts b/src/common/state/store-appstate.ts deleted file mode 100644 index 0e3ff9308..000000000 --- a/src/common/state/store-appstate.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { create } from 'zustand'; -import { persist } from 'zustand/middleware'; - - -// App State - -interface AppStateData { - usageCount: number; -} - -export const useAppStateStore = create()( - persist( - (set) => ({ - - usageCount: 0, - - }), - { - name: 'app-state', - }, - ), -); - -// increment the usage count -useAppStateStore.setState((state) => ({ usageCount: (state.usageCount || 0) + 1 })); diff --git a/src/common/state/store-ux-labs.ts b/src/common/state/store-ux-labs.ts index 0d214b989..c7acc66c1 100644 --- a/src/common/state/store-ux-labs.ts +++ b/src/common/state/store-ux-labs.ts @@ -7,7 +7,7 @@ import { Is } from '~/common/util/pwaUtils'; // UX Labs Experiments // UxLabsSettings.tsx contains the graduated settings, but the following are not stated: -// - Text Tools: dinamically shown where applicable +// - Text Tools: dynamically shown where applicable // - Chat Mode: Follow-Ups; moved to Chat Advanced UI interface UXLabsStore { diff --git a/src/common/stores/chat/chats.converters.ts b/src/common/stores/chat/chats.converters.ts index 25533c5e7..dbd76b77f 100644 --- a/src/common/stores/chat/chats.converters.ts +++ b/src/common/stores/chat/chats.converters.ts @@ -1,6 +1,6 @@ import type { SystemPurposeId } from '../../../data'; -import type { DFolder } from '~/common/state/store-folders'; +import type { DFolder } from '~/common/stores/folders/store-chat-folders'; import type { LiveFileId } from '~/common/livefile/liveFile.types'; import { liveFileGetAllValidIDs } from '~/common/livefile/store-live-file'; diff --git a/src/common/state/store-folders.ts b/src/common/stores/folders/store-chat-folders.ts similarity index 100% rename from src/common/state/store-folders.ts rename to src/common/stores/folders/store-chat-folders.ts diff --git a/src/common/util/globalStoredList.ts b/src/common/util/globalStoredList.ts index b61753c64..1271b06ce 100644 --- a/src/common/util/globalStoredList.ts +++ b/src/common/util/globalStoredList.ts @@ -1,116 +1,116 @@ -import { create } from 'zustand'; -import { persist } from 'zustand/middleware'; - - -type TaggedListItem = { - id: TId; - listTags: TTag[]; -} - -/** - * Create a persistent list of type TaggedListItem that will handle list functions, and item editing functions. - * - your item can have all the properties you want, but must have an id and listTags property - * - your item will be serialized/de-serialized to/from localStorage, make sure it's JSON-serializable - */ -export function createStoredTaggetList>(persistName: string) { - - // Infer TId and TTag from TItem's id and listTags array type - type TId = TItem['id']; - type TTag = TItem['listTags'][number]; - - type SelectionMap = { - [K in TTag]?: TId; - }; - - type TaggedListState = { - // State - items: TItem[]; - selections: SelectionMap; // Maps TTag to selected TId - - // Actions - addItem: (item: TItem) => void; - removeItem: (itemId: TId) => void; - modifyItem: (itemId: TId, changes: Partial) => void; - modifyItemDeep: (itemId: TId, updater: (item: TItem) => TItem) => void; - - selectItemForTag: (tag: TTag, itemId: TId) => void; - }; - - return create()(persist((set, get) => ({ - - items: [] as TItem[], - selections: {} as SelectionMap, - - - addItem: (item: TItem) => set((state: TaggedListState) => ({ - items: [...state.items, item], - })), - - removeItem: (itemId: TId) => set((state: TaggedListState) => ({ - items: state.items.filter((item: TItem) => item.id !== itemId), - selections: Object.fromEntries( - Object.entries(state.selections).filter(([, selectedId]) => selectedId !== itemId), - ) as SelectionMap, - })), - - modifyItem: (itemId: TId, changes: Partial) => set((state: TaggedListState) => ({ - items: state.items.map((item: TItem) => item.id === itemId ? { ...item, ...changes } : item), - })), - - modifyItemDeep: (itemId: TId, updater: (item: TItem) => TItem) => set((state: TaggedListState) => ({ - items: state.items.map((item: TItem) => item.id === itemId ? updater(item) : item), - })), - - - selectItemForTag: (tag: TTag, itemId: TId) => { - const item = get().items.find((item) => item.id === itemId); - if (item && item.listTags.includes(tag)) { - set((state) => ({ - selections: { ...state.selections, [tag]: itemId }, - })); - } else { - console.warn(`Item with id ${itemId} does not support tag ${tag} and cannot be selected for it.`); - } - }, - - }), - - { - name: persistName, - }), - ); -} - - -/* Example: - -// Define the specific subtype for VoiceOutModel -type VoiceModelId = string; -type VoiceModelTag = 'voice' | 'text' | 'image' | 'video' | 'audio'; - -// Define the VoiceOutModel interface -export interface VoiceOutModel extends TaggedListItem { - music: string; - count: number; - fruits: string[]; -} - -// Create the Zustand store with the specific VoiceOutModel type -const useVoiceOutModels = createStoredTaggetList('app-voice-synth'); - -export const useVoiceModel = (modelId: VoiceModelId) => { - const { item, modifyItem } = useVoiceOutModels(useShallow(state => ({ - item: state.items.find(item => item.id === modelId) as Readonly, - modifyItem: state.modifyItem, - }))); - - // Memoize all the update functions at once - const { setMusic, setCount, setFruits } = React.useMemo(() => ({ - setMusic: (music: string) => modifyItem(modelId, { music }), - setCount: (count: number) => modifyItem(modelId, { count }), - setFruits: (fruits: string[]) => modifyItem(modelId, { fruits }), - }), [modifyItem, modelId]); - - return { item, setMusic, setCount, setFruits }; -}; -*/ \ No newline at end of file +// import { create } from 'zustand'; +// import { persist } from 'zustand/middleware'; +// +// +// type TaggedListItem = { +// id: TId; +// listTags: TTag[]; +// } +// +// /** +// * Create a persistent list of type TaggedListItem that will handle list functions, and item editing functions. +// * - your item can have all the properties you want, but must have an id and listTags property +// * - your item will be serialized/de-serialized to/from localStorage, make sure it's JSON-serializable +// */ +// export function createStoredTaggedList>(persistName: string) { +// +// // Infer TId and TTag from TItem's id and listTags array type +// type TId = TItem['id']; +// type TTag = TItem['listTags'][number]; +// +// type SelectionMap = { +// [K in TTag]?: TId; +// }; +// +// type TaggedListState = { +// // State +// items: TItem[]; +// selections: SelectionMap; // Maps TTag to selected TId +// +// // Actions +// addItem: (item: TItem) => void; +// removeItem: (itemId: TId) => void; +// modifyItem: (itemId: TId, changes: Partial) => void; +// modifyItemDeep: (itemId: TId, updater: (item: TItem) => TItem) => void; +// +// selectItemForTag: (tag: TTag, itemId: TId) => void; +// }; +// +// return create()(persist((set, get) => ({ +// +// items: [] as TItem[], +// selections: {} as SelectionMap, +// +// +// addItem: (item: TItem) => set((state: TaggedListState) => ({ +// items: [...state.items, item], +// })), +// +// removeItem: (itemId: TId) => set((state: TaggedListState) => ({ +// items: state.items.filter((item: TItem) => item.id !== itemId), +// selections: Object.fromEntries( +// Object.entries(state.selections).filter(([, selectedId]) => selectedId !== itemId), +// ) as SelectionMap, +// })), +// +// modifyItem: (itemId: TId, changes: Partial) => set((state: TaggedListState) => ({ +// items: state.items.map((item: TItem) => item.id === itemId ? { ...item, ...changes } : item), +// })), +// +// modifyItemDeep: (itemId: TId, updater: (item: TItem) => TItem) => set((state: TaggedListState) => ({ +// items: state.items.map((item: TItem) => item.id === itemId ? updater(item) : item), +// })), +// +// +// selectItemForTag: (tag: TTag, itemId: TId) => { +// const item = get().items.find((item) => item.id === itemId); +// if (item && item.listTags.includes(tag)) { +// set((state) => ({ +// selections: { ...state.selections, [tag]: itemId }, +// })); +// } else { +// console.warn(`Item with id ${itemId} does not support tag ${tag} and cannot be selected for it.`); +// } +// }, +// +// }), +// +// { +// name: persistName, +// }), +// ); +// } +// +// +// /* Example: +// +// // Define the specific subtype for VoiceOutModel +// type VoiceModelId = string; +// type VoiceModelTag = 'voice' | 'text' | 'image' | 'video' | 'audio'; +// +// // Define the VoiceOutModel interface +// export interface VoiceOutModel extends TaggedListItem { +// music: string; +// count: number; +// fruits: string[]; +// } +// +// // Create the Zustand store with the specific VoiceOutModel type +// const useVoiceOutModels = createStoredTaggetList('app-voice-synth'); +// +// export const useVoiceModel = (modelId: VoiceModelId) => { +// const { item, modifyItem } = useVoiceOutModels(useShallow(state => ({ +// item: state.items.find(item => item.id === modelId) as Readonly, +// modifyItem: state.modifyItem, +// }))); +// +// // Memoize all the update functions at once +// const { setMusic, setCount, setFruits } = React.useMemo(() => ({ +// setMusic: (music: string) => modifyItem(modelId, { music }), +// setCount: (count: number) => modifyItem(modelId, { count }), +// setFruits: (fruits: string[]) => modifyItem(modelId, { fruits }), +// }), [modifyItem, modelId]); +// +// return { item, setMusic, setCount, setFruits }; +// }; +// */ \ No newline at end of file diff --git a/src/modules/beam/gather/beam.gather.ts b/src/modules/beam/gather/beam.gather.ts index 916035bf8..bfa6e8784 100644 --- a/src/modules/beam/gather/beam.gather.ts +++ b/src/modules/beam/gather/beam.gather.ts @@ -6,7 +6,7 @@ import type { DMessage } from '~/common/stores/chat/chat.message'; import { agiUuid } from '~/common/util/idUtils'; import { CUSTOM_FACTORY_ID, FFactoryId, findFusionFactory, FUSION_FACTORIES, FUSION_FACTORY_DEFAULT } from './instructions/beam.gather.factories'; -import { RootStoreSlice } from '../store-beam-vanilla'; +import { RootStoreSlice } from '../store-beam_vanilla'; import { ScatterStoreSlice } from '../scatter/beam.scatter'; import { gatherStartFusion, gatherStopFusion, Instruction } from './instructions/beam.gather.execution'; import { updateBeamLastConfig } from '../store-module-beam'; diff --git a/src/modules/beam/scatter/beam.scatter.ts b/src/modules/beam/scatter/beam.scatter.ts index d641b2aaf..ffe40d71d 100644 --- a/src/modules/beam/scatter/beam.scatter.ts +++ b/src/modules/beam/scatter/beam.scatter.ts @@ -9,7 +9,7 @@ import { createPlaceholderMetaFragment } from '~/common/stores/chat/chat.fragmen import { findLLMOrThrow } from '~/common/stores/llms/store-llms'; import { getUXLabsHighPerformance } from '~/common/state/store-ux-labs'; -import type { RootStoreSlice } from '../store-beam-vanilla'; +import type { RootStoreSlice } from '../store-beam_vanilla'; import { SCATTER_DEBUG_STATE, SCATTER_PLACEHOLDER } from '../beam.config'; import { updateBeamLastConfig } from '../store-module-beam'; diff --git a/src/modules/beam/store-beam.hooks.ts b/src/modules/beam/store-beam.hooks.ts index 71afbbde6..4e5247938 100644 --- a/src/modules/beam/store-beam.hooks.ts +++ b/src/modules/beam/store-beam.hooks.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { type StoreApi, useStore } from 'zustand'; -import type { BeamStore } from './store-beam-vanilla'; +import type { BeamStore } from './store-beam_vanilla'; export type BeamStoreApi = Readonly>; diff --git a/src/modules/beam/store-beam-vanilla.ts b/src/modules/beam/store-beam_vanilla.ts similarity index 100% rename from src/modules/beam/store-beam-vanilla.ts rename to src/modules/beam/store-beam_vanilla.ts diff --git a/src/modules/trade/link/ChatLinkDetails.tsx b/src/modules/trade/link/ChatLinkDetails.tsx index bf5335005..a412128ad 100644 --- a/src/modules/trade/link/ChatLinkDetails.tsx +++ b/src/modules/trade/link/ChatLinkDetails.tsx @@ -23,7 +23,7 @@ import { getOriginUrl } from '~/common/util/urlUtils'; import { webShare, webSharePresent } from '~/common/util/pwaUtils'; import type { StorageDeleteSchema, StoragePutSchema } from '../server/link'; -import { forgetChatLinkItem } from './store-link'; +import { forgetChatLinkItem } from './store-share-link'; export function ChatLinkDetails(props: { diff --git a/src/modules/trade/link/ChatLinkExport.tsx b/src/modules/trade/link/ChatLinkExport.tsx index a0f8580b6..3694b8888 100644 --- a/src/modules/trade/link/ChatLinkExport.tsx +++ b/src/modules/trade/link/ChatLinkExport.tsx @@ -15,7 +15,7 @@ import { getConversation } from '~/common/stores/chat/store-chats'; import type { StoragePutSchema, StorageUpdateDeletionKeySchema } from '../server/link'; import { ChatLinkDetails } from './ChatLinkDetails'; -import { rememberChatLinkItem, updateChatLinkDeletionKey, useLinkStorageOwnerId } from './store-link'; +import { rememberChatLinkItem, updateChatLinkDeletionKey, useLinkStorageOwnerId } from './store-share-link'; export function ChatLinkExport(props: { diff --git a/src/modules/trade/link/store-link.ts b/src/modules/trade/link/store-share-link.ts similarity index 77% rename from src/modules/trade/link/store-link.ts rename to src/modules/trade/link/store-share-link.ts index c8e3748f1..13f9e0a6f 100644 --- a/src/modules/trade/link/store-link.ts +++ b/src/modules/trade/link/store-share-link.ts @@ -25,7 +25,7 @@ interface LinkStore { } -const useLinkStore = create()( +const useShareLinkStore = create()( persist( (set) => ({ @@ -52,18 +52,18 @@ const useLinkStore = create()( // by AppChatLink -export const useSharedChatLinkItems = () => useLinkStore(useShallow(state => state.chatLinkItems)); +export const useSharedChatLinkItems = () => useShareLinkStore(useShallow(state => state.chatLinkItems)); // by ChatLinkExport/ChatLinkDetails -export const rememberChatLinkItem = useLinkStore.getState().chatLinkItemAdd; -export const updateChatLinkDeletionKey = useLinkStore.getState().chatLinkItemChangeDeletionKey; -export const forgetChatLinkItem = useLinkStore.getState().chatLinkItemRemove; -export const useLinkStorageOwnerId = () => useLinkStore(useShallow(state => ({ +export const rememberChatLinkItem = useShareLinkStore.getState().chatLinkItemAdd; +export const updateChatLinkDeletionKey = useShareLinkStore.getState().chatLinkItemChangeDeletionKey; +export const forgetChatLinkItem = useShareLinkStore.getState().chatLinkItemRemove; +export const useLinkStorageOwnerId = () => useShareLinkStore(useShallow(state => ({ linkStorageOwnerId: state.linkStorageOwnerId, setLinkStorageOwnerId: state.setLinkStorageOwnerId, }))); // by Nav export function hasNoChatLinkItems() { - return !useLinkStore.getState().chatLinkItems.length; + return !useShareLinkStore.getState().chatLinkItems.length; } diff --git a/src/modules/trade/trade.client.ts b/src/modules/trade/trade.client.ts index 98c45385c..7b23876bf 100644 --- a/src/modules/trade/trade.client.ts +++ b/src/modules/trade/trade.client.ts @@ -11,7 +11,7 @@ import { messageFragmentsReduceText } from '~/common/stores/chat/chat.message'; import { prettyShortChatModelName } from '~/common/util/dMessageUtils'; import { prettyTimestampForFilenames } from '~/common/util/timeUtils'; import { useChatStore } from '~/common/stores/chat/store-chats'; -import { useFolderStore } from '~/common/state/store-folders'; +import { useFolderStore } from '~/common/stores/folders/store-chat-folders'; import type { ImportedOutcome } from './ImportOutcomeModal';