Skip to content

Commit

Permalink
ChatStore should export ChatViewModels
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdjohnson committed Nov 23, 2024
1 parent a0c979c commit 69605dc
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 37 deletions.
4 changes: 2 additions & 2 deletions src/components/OmniBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ const useRegisterChatActions = () => {
},
]

_.orderBy(chatStore.chats, 'lastMessageDate', 'desc').forEach(chat => {
chatStore.orderedChats.forEach(chat => {
const name = chat.name || 'new chat'

return nextChatActions.push({
Expand Down Expand Up @@ -349,7 +349,7 @@ const useRegisterMessageActions = () => {
const nextMessageActions: Action[] = []

chatStore.chats.forEach(chat => {
const messageCount = countMessagesWithText(chat.messageIds)
const messageCount = countMessagesWithText(chat.source.messageIds)

if (messageCount > 0) {
nextMessageActions.push(
Expand Down
4 changes: 2 additions & 2 deletions src/components/chat/ChatListSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import DocumentArrowUp from '~/icons/DocumentArrowUp'
import Edit from '~/icons/Edit'

import { chatStore } from '~/core/chat/ChatStore'
import { ChatModel } from '~/core/chat/ChatModel'
import { ChatViewModel } from '~/core/chat/ChatViewModel'
import { chatTable } from '~/core/chat/ChatTable'

export const ChatListSection = observer(({ onChatSelected }: { onChatSelected: () => void }) => {
const { dateLabelToChatPairs } = chatStore

const handleChatSelected = async (chat: ChatModel) => {
const handleChatSelected = async (chat: ChatViewModel) => {
await chatStore.selectChat(chat)

onChatSelected()
Expand Down
16 changes: 7 additions & 9 deletions src/components/chat/ChatSettingsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ export const ChatSettingsSection = observer(({ onBackClicked }: { onBackClicked:

const chat = chatStore.selectedChat!

const chatModel = chat.source

const onExportClose = () => {
setIsExportOpen(false)
}
Expand All @@ -43,7 +41,7 @@ export const ChatSettingsSection = observer(({ onBackClicked }: { onBackClicked:
}

const handleFormSubmit = handleSubmit(async formData => {
await chatTable.put({ ...chatModel, ...formData })
await chatTable.put({ ...chat.source, ...formData })

reset(formData)
})
Expand All @@ -60,12 +58,12 @@ export const ChatSettingsSection = observer(({ onBackClicked }: { onBackClicked:

const link = document.createElement('a')
link.href = URL.createObjectURL(new Blob([data], { type: 'application/json' }))
link.download = `llm-x-chat-${_.snakeCase(chatModel.name).replace('_', '-')}.json`
link.download = `llm-x-chat-${_.snakeCase(chat.name).replace('_', '-')}.json`
link.click()
}

useEffect(() => {
reset({ name: chatModel.name || 'new chat' })
reset({ name: chat.name || 'new chat' })
}, [chat])

useEffect(() => {
Expand Down Expand Up @@ -93,12 +91,12 @@ export const ChatSettingsSection = observer(({ onBackClicked }: { onBackClicked:
</button>

<span className="flex-shrink-1 line-clamp-1 max-w-[85%] flex-1 text-left md:text-lg">
{chatModel.name || 'new chat'}
{chat.name || 'new chat'}
</span>

<NavButton
to={'/chats/' + chat.id}
className="!bg-transparent text-base-content/60 hover:text-base-content p-1 transition-colors duration-250 ease-in-out"
className="!bg-transparent p-1 text-base-content/60 transition-colors duration-250 ease-in-out hover:text-base-content"
>
<Edit />
</NavButton>
Expand Down Expand Up @@ -130,7 +128,7 @@ export const ChatSettingsSection = observer(({ onBackClicked }: { onBackClicked:
)}
control={control}
name="name"
defaultValue={chatModel.name || 'new chat'}
defaultValue={chat.name || 'new chat'}
rules={{
validate: validateName,
}}
Expand All @@ -152,7 +150,7 @@ export const ChatSettingsSection = observer(({ onBackClicked }: { onBackClicked:

<Tooltip label="Delete Chat">
<button
onClick={() => chatStore.destroyChat(chatModel)}
onClick={() => chatStore.destroyChat(chat)}
className="btn btn-ghost text-error"
>
<Delete className="h-5 w-5" />
Expand Down
18 changes: 9 additions & 9 deletions src/core/chat/ChatStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class ChatStore {
makeAutoObservable(this)
}

get chats(): ChatModel[] {
return chatTable.cache.allValues()
get chats() {
return _.compact(chatTable.cache.allValues().map(this.chatCache.getOrPut))
}

get selectedChat() {
Expand All @@ -34,12 +34,12 @@ class ChatStore {
return undefined
}

get emptyChat(): ChatModel | undefined {
return _.find(this.chats, chat => chat.messageIds.length === 0)
get emptyChat(): ChatViewModel | undefined {
return _.find(this.chats, chat => chat.source.messageIds.length === 0)
}

get orderedChats() {
return _.orderBy(this.chats, 'lastMessageTimestamp', 'desc') // newest sent message first
return _.orderBy(this.chats, 'source.lastMessageTimestamp', 'desc') // newest sent message first
}

// todo, see if this is used in more than one place?
Expand All @@ -51,11 +51,11 @@ class ChatStore {
.value()
}

async destroyChat(chat: ChatModel) {
async destroyChat(chat: ChatViewModel) {
let nextSelectedChat: ChatModel | undefined = undefined

if (this.selectedChat?.id === chat.id) {
nextSelectedChat = _.without(chatStore.orderedChats, chat)[0]
nextSelectedChat = _.without(chatStore.orderedChats, chat)[0]?.source
}

// if we deleted the selected chat, and there was nothing to replace it
Expand All @@ -67,10 +67,10 @@ class ChatStore {

this.chatCache.remove(chat.id)

return chatTable.destroy(chat)
return chatTable.destroy(chat.source)
}

async selectChat(chat: ChatModel) {
async selectChat(chat: ChatViewModel) {
return settingTable.put({ selectedChatId: chat.id })
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/core/chat/ChatViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export class ChatViewModel {
return this.source.id
}

get name() {
return this.source.name
}

get messages() {
return _.compact(this.source.messageIds.map(this.messageViewModelCache.get))
}
Expand Down Expand Up @@ -224,7 +228,7 @@ export class ChatViewModel {
this.messageViewModelCache.put(userMessage)

// if there was not a name before, auto make one now
const name = this.source.name === 'New Chat' ? content.substring(0, 40) : this.source.name
const name = this.name === 'New Chat' ? content.substring(0, 40) : this.name
// add the message (and new name) to the chat
await this.update({
name,
Expand Down
4 changes: 2 additions & 2 deletions src/features/settings/panels/chat/ChatForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const ChatForm = observer(() => {
const handleDelete = async () => {
navigate('/chats')

await chatStore.destroyChat(chat.source)
await chatStore.destroyChat(chat)
}

const validateName = (name: string) => {
Expand All @@ -49,7 +49,7 @@ export const ChatForm = observer(() => {
}, [chat])

return (
<Drawer path={chat.id} label={chat.source.name}>
<Drawer path={chat.id} label={chat.name}>
<form onSubmit={handleFormSubmit} className="flex h-full flex-col p-2">
<Controller
render={({ field }) => (
Expand Down
16 changes: 7 additions & 9 deletions src/features/settings/panels/chat/ChatPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SettingSection, { SettingSectionItem } from '~/containers/SettingSection'

import Edit from '~/icons/Edit'

import { ChatModel } from '~/core/chat/ChatModel'
import { ChatViewModel } from '~/core/chat/ChatViewModel'
import { chatTable } from '~/core/chat/ChatTable'
import { chatStore } from '~/core/chat/ChatStore'
import { settingTable } from '~/core/setting/SettingTable'
Expand All @@ -17,20 +17,18 @@ export const ChatPanel = observer(() => {
const { selectedChat, chats } = chatStore
const navigate = useNavigate()

const chatToSectionItem = (chat: ChatModel): SettingSectionItem<ChatModel> => ({
const chatToSectionItem = (chat: ChatViewModel): SettingSectionItem<ChatViewModel> => ({
id: chat.id,
label: chat.name,
subLabels: [chat.messageIds.length + ' messages'],
subLabels: [chat.source.messageIds.length + ' messages'],
data: chat,
})

const itemFilter = (chat: ChatModel, filterText: string) => {
return (
chat.name.toLowerCase().includes(filterText)
)
const itemFilter = (chat: ChatViewModel, filterText: string) => {
return chat.name.toLowerCase().includes(filterText)
}

const handleChatSelected = async (chat: ChatModel) => {
const handleChatSelected = async (chat: ChatViewModel) => {
await chatStore.selectChat(chat)
}

Expand Down Expand Up @@ -65,7 +63,7 @@ export const ChatPanel = observer(() => {
addButtonProps={{
label: 'Add New Chat',
onClick: e => createChat(e),
isDisabled: !!chatStore.emptyChat
isDisabled: !!chatStore.emptyChat,
}}
/>
)
Expand Down
6 changes: 3 additions & 3 deletions src/utils/chatToDateLabel.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import moment from 'moment'

import { ChatModel } from '~/core/chat/ChatModel'
import { ChatViewModel } from '~/core/chat/ChatViewModel'

export const chatToDateLabel = (chat: ChatModel) => {
const sentTime = moment(chat.lastMessageTimestamp)
export const chatToDateLabel = (chat: ChatViewModel) => {
const sentTime = moment(chat.source.lastMessageTimestamp)

const today = moment().startOf('day')

Expand Down

0 comments on commit 69605dc

Please sign in to comment.