Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
aa26cc30
Unverified
Commit
aa26cc30
authored
Aug 03, 2023
by
boojack
Committed by
GitHub
Aug 03, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: remove memo chat components (#2073)
parent
1ce82ba0
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
0 additions
and
521 deletions
+0
-521
Header.tsx
web/src/components/Header.tsx
+0
-16
ChatInput.tsx
web/src/components/MemoChat/ChatInput.tsx
+0
-37
ChatMessage.tsx
web/src/components/MemoChat/ChatMessage.tsx
+0
-60
ConversationTab.tsx
web/src/components/MemoChat/ConversationTab.tsx
+0
-33
en.json
web/src/locales/en.json
+0
-12
hi.json
web/src/locales/hi.json
+0
-12
ja.json
web/src/locales/ja.json
+0
-10
zh-Hans.json
web/src/locales/zh-Hans.json
+0
-11
zh-Hant.json
web/src/locales/zh-Hant.json
+0
-10
MemoChat.tsx
web/src/pages/MemoChat.tsx
+0
-218
index.tsx
web/src/router/index.tsx
+0
-22
conversation.ts
web/src/store/v1/conversation.ts
+0
-43
message.ts
web/src/store/v1/message.ts
+0
-37
No files found.
web/src/components/Header.tsx
View file @
aa26cc30
...
@@ -115,22 +115,6 @@ const Header = () => {
...
@@ -115,22 +115,6 @@ const Header = () => {
{
!
isVisitorMode
&&
(
{
!
isVisitorMode
&&
(
<>
<>
{
globalStore
.
isDev
()
&&
(
<
NavLink
to=
"/memo-chat"
id=
"header-memo-chat"
className=
{
({
isActive
})
=>
classNames
(
"px-4 pr-5 py-2 rounded-full border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700"
,
isActive
?
"bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
:
"border-transparent"
)
}
>
<>
<
Icon
.
Bot
className=
"mr-3 w-6 h-auto opacity-70"
/>
{
t
(
"memo-chat.title"
)
}
</>
</
NavLink
>
)
}
<
NavLink
<
NavLink
to=
"/archived"
to=
"/archived"
id=
"header-archived"
id=
"header-archived"
...
...
web/src/components/MemoChat/ChatInput.tsx
deleted
100644 → 0
View file @
1ce82ba0
import
Textarea
from
"@mui/joy/Textarea/Textarea"
;
import
Icon
from
"@/components/Icon"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
interface
Props
{
question
:
string
;
handleQuestionTextareaChange
:
any
;
setIsInIME
:
any
;
handleKeyDown
:
any
;
handleSendQuestionButtonClick
:
any
;
}
const
ChatInput
=
({
question
,
handleQuestionTextareaChange
,
setIsInIME
,
handleKeyDown
,
handleSendQuestionButtonClick
}:
Props
)
=>
{
const
t
=
useTranslate
();
return
(
<
div
className=
"w-full relative mt-4"
>
<
Textarea
className=
"w-full"
placeholder=
{
t
(
"memo-chat.placeholder"
)
}
value=
{
question
}
minRows=
{
1
}
maxRows=
{
5
}
onChange=
{
handleQuestionTextareaChange
}
onCompositionStart=
{
()
=>
setIsInIME
(
true
)
}
onCompositionEnd=
{
()
=>
setIsInIME
(
false
)
}
onKeyDown=
{
handleKeyDown
}
/>
<
Icon
.
Send
className=
"cursor-pointer w-7 p-1 h-auto rounded-md bg-gray-100 dark:bg-zinc-800 absolute right-2 bottom-1.5 shadow hover:opacity-80"
onClick=
{
handleSendQuestionButtonClick
}
/>
</
div
>
);
};
export
default
ChatInput
;
web/src/components/MemoChat/ChatMessage.tsx
deleted
100644 → 0
View file @
1ce82ba0
import
toast
from
"react-hot-toast"
;
import
Icon
from
"@/components/Icon"
;
import
{
marked
}
from
"@/labs/marked"
;
import
{
useMemoStore
}
from
"@/store/module"
;
import
{
Message
}
from
"@/store/v1/message"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
Dropdown
from
"../kit/Dropdown"
;
interface
MessageProps
{
index
:
number
;
message
:
Message
;
}
const
ChatMessage
=
({
index
,
message
}:
MessageProps
)
=>
{
const
memoStore
=
useMemoStore
();
const
t
=
useTranslate
();
const
handleSaveAsMemos
=
async
()
=>
{
await
memoStore
.
createMemo
({
content
:
message
.
content
,
visibility
:
"PRIVATE"
,
resourceIdList
:
[],
relationList
:
[],
});
toast
.
success
(
t
(
"memo-chat.save-as-memo-success"
));
};
return
(
<
div
key=
{
index
}
className=
"w-full flex flex-col justify-start items-start space-y-2"
>
{
message
.
role
===
"user"
?
(
<
div
className=
"w-full flex flex-row justify-end items-start pl-6"
>
<
span
className=
"word-break shadow rounded-lg rounded-tr-none px-3 py-2 opacity-80 bg-white dark:bg-zinc-800"
>
{
message
.
content
}
</
span
>
</
div
>
)
:
(
<
div
className=
"w-full flex flex-row justify-start items-start pr-8 space-x-2"
>
<
Icon
.
Bot
className=
"mt-2 shrink-0 mr-1 w-6 h-auto opacity-80"
/>
<
div
className=
"memo-content-wrapper !w-auto flex flex-col justify-start items-start shadow rounded-lg rounded-tl-none px-3 py-2 bg-white dark:bg-zinc-800"
>
<
div
className=
"memo-content-text"
>
{
marked
(
message
.
content
)
}
</
div
>
</
div
>
<
Dropdown
actions=
{
<>
<
button
className=
"w-full m-auto text-left text-sm whitespace-nowrap leading-6 py-1 px-3 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-600"
onClick=
{
()
=>
handleSaveAsMemos
()
}
>
{
t
(
"memo-chat.save-as-memo"
)
}
</
button
>
</>
}
/>
</
div
>
)
}
</
div
>
);
};
export
default
ChatMessage
;
web/src/components/MemoChat/ConversationTab.tsx
deleted
100644 → 0
View file @
1ce82ba0
import
Icon
from
"@/components/Icon"
;
import
{
Conversation
}
from
"@/store/v1/conversation"
;
interface
ConversationTabProps
{
item
:
Conversation
;
selectedConversationId
:
string
;
setSelectedConversationId
:
(
id
:
string
)
=>
void
;
closeConversation
:
(
e
:
any
)
=>
void
;
}
const
ConversationTab
=
({
item
,
selectedConversationId
,
setSelectedConversationId
,
closeConversation
}:
ConversationTabProps
)
=>
{
return
(
<
div
className=
{
`flex rounded-lg h-8 px-3 cursor-pointer border dark:border-zinc-600 ${
selectedConversationId === item.messageStorageId ? "bg-white dark:bg-zinc-700" : "bg-gray-200 dark:bg-zinc-800 opacity-60"
}`
}
key=
{
item
.
messageStorageId
}
onClick=
{
()
=>
{
setSelectedConversationId
(
item
.
messageStorageId
);
}
}
>
<
div
className=
"truncate m-auto"
>
{
item
.
name
}
</
div
>
<
Icon
.
X
className=
"ml-1 w-4 h-auto m-auto cursor-pointer opacity-60"
onClick=
{
(
e
:
any
)
=>
{
closeConversation
(
e
);
}
}
/>
</
div
>
);
};
export
default
ConversationTab
;
web/src/locales/en.json
View file @
aa26cc30
...
@@ -390,18 +390,6 @@
...
@@ -390,18 +390,6 @@
"sat"
:
"Sat"
,
"sat"
:
"Sat"
,
"sun"
:
"Sun"
"sun"
:
"Sun"
},
},
"memo-chat"
:
{
"title"
:
"Memo Chat"
,
"save-as-memo"
:
"Save as memo"
,
"save-as-memo-success"
:
"Saved as memo successfully."
,
"not-enabled"
:
"You have not set up your OpenAI API key."
,
"go-to-settings"
:
"Go to settings"
,
"placeholder"
:
"Ask anything…"
,
"no-message"
:
"No Message"
,
"default-message-group-title"
:
"Default Session"
,
"create-message-group-title"
:
"Create Session"
,
"label-message-group-name-title"
:
"Session Name"
},
"embed-memo"
:
{
"embed-memo"
:
{
"title"
:
"Embed Memo"
,
"title"
:
"Embed Memo"
,
"text"
:
"Copy and paste the below codes into your blog or website."
,
"text"
:
"Copy and paste the below codes into your blog or website."
,
...
...
web/src/locales/hi.json
View file @
aa26cc30
...
@@ -385,18 +385,6 @@
...
@@ -385,18 +385,6 @@
"sat"
:
"शनिवार"
,
"sat"
:
"शनिवार"
,
"sun"
:
"रविवार"
"sun"
:
"रविवार"
},
},
"memo-chat"
:
{
"title"
:
"मेमो चैट"
,
"save-as-memo"
:
"मेमो के रूप में सहेजें"
,
"save-as-memo-success"
:
"मेमो के रूप में सफलतापूर्वक सहेजा गया।"
,
"not-enabled"
:
"आपने अपना OpenAI API कुंजी सेट नहीं किया है।"
,
"go-to-settings"
:
"सेटिंग्स पर जाएं"
,
"placeholder"
:
"कुछ भी पूछें..."
,
"no-message"
:
"कोई संदेश नहीं"
,
"default-message-group-title"
:
"डिफ़ॉल्ट सत्र"
,
"create-message-group-title"
:
"सत्र बनाएँ"
,
"label-message-group-name-title"
:
"सत्र का नाम"
},
"embed-memo"
:
{
"embed-memo"
:
{
"title"
:
"मेमो एम्बेड करें"
,
"title"
:
"मेमो एम्बेड करें"
,
"text"
:
"नीचे दिए गए कोड को अपने ब्लॉग या वेबसाइट में कॉपी और पेस्ट करें।"
,
"text"
:
"नीचे दिए गए कोड को अपने ब्लॉग या वेबसाइट में कॉपी और पेस्ट करें।"
,
...
...
web/src/locales/ja.json
View file @
aa26cc30
...
@@ -369,16 +369,6 @@
...
@@ -369,16 +369,6 @@
"sat"
:
"土"
,
"sat"
:
"土"
,
"sun"
:
"日"
"sun"
:
"日"
},
},
"memo-chat"
:
{
"title"
:
"AIに尋ねる"
,
"not-enabled"
:
"OpenAIのAPI keyが設定されていません"
,
"go-to-settings"
:
"設定へ"
,
"placeholder"
:
"何か聞いてみてください..."
,
"default-message-group-title"
:
"デフォルトセッション"
,
"create-message-group-title"
:
"セッションを作成する"
,
"label-message-group-name-title"
:
"セッションの名前"
},
"embed-memo"
:
{
"embed-memo"
:
{
"title"
:
"メモを埋め込む"
,
"title"
:
"メモを埋め込む"
,
"text"
:
"コードをあなたのサイズにコピーペーストすればメモを埋め込めます"
,
"text"
:
"コードをあなたのサイズにコピーペーストすればメモを埋め込めます"
,
...
...
web/src/locales/zh-Hans.json
View file @
aa26cc30
...
@@ -95,17 +95,6 @@
...
@@ -95,17 +95,6 @@
"fetching-data"
:
"请求数据中..."
,
"fetching-data"
:
"请求数据中..."
,
"no-archived-memos"
:
"没有归档的备忘录"
"no-archived-memos"
:
"没有归档的备忘录"
},
},
"memo-chat"
:
{
"go-to-settings"
:
"前往设置"
,
"save-as-memo"
:
"保存为 Memo"
,
"save-as-memo-success"
:
"保存为 Memo 成功"
,
"not-enabled"
:
"您尚未设置 OpenAI API 密钥。"
,
"placeholder"
:
"随便问"
,
"title"
:
"问 AI"
,
"default-message-group-title"
:
"默认会话"
,
"create-message-group-title"
:
"新建会话"
,
"label-message-group-name-title"
:
"会话名称"
},
"auth"
:
{
"auth"
:
{
"host-tip"
:
"你正在注册为管理员用户账号。"
,
"host-tip"
:
"你正在注册为管理员用户账号。"
,
"new-password"
:
"新密码"
,
"new-password"
:
"新密码"
,
...
...
web/src/locales/zh-Hant.json
View file @
aa26cc30
...
@@ -378,16 +378,6 @@
...
@@ -378,16 +378,6 @@
"friday"
:
"星期五"
,
"friday"
:
"星期五"
,
"wednesday"
:
"星期三"
"wednesday"
:
"星期三"
},
},
"memo-chat"
:
{
"title"
:
"問 AI"
,
"not-enabled"
:
"您尚未設置 OpenAI API 密鑰。"
,
"go-to-settings"
:
"前往設定"
,
"placeholder"
:
"凡事皆可問…"
,
"default-message-group-title"
:
"預設會話"
,
"create-message-group-title"
:
"建立對話"
,
"label-message-group-name-title"
:
"對話名稱"
},
"embed-memo"
:
{
"embed-memo"
:
{
"title"
:
"嵌入備忘錄"
,
"title"
:
"嵌入備忘錄"
,
"text"
:
"將以下程式碼複製並貼上到您的網誌或網站中。"
,
"text"
:
"將以下程式碼複製並貼上到您的網誌或網站中。"
,
...
...
web/src/pages/MemoChat.tsx
deleted
100644 → 0
View file @
1ce82ba0
import
{
fetchEventSource
}
from
"@microsoft/fetch-event-source"
;
import
{
Button
,
Stack
}
from
"@mui/joy"
;
import
{
head
}
from
"lodash-es"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
Empty
from
"@/components/Empty"
;
import
Icon
from
"@/components/Icon"
;
import
ChatInput
from
"@/components/MemoChat/ChatInput"
;
import
ChatMessage
from
"@/components/MemoChat/ChatMessage"
;
import
ConversationTab
from
"@/components/MemoChat/ConversationTab"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
*
as
api
from
"@/helpers/api"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
{
Conversation
,
useConversationStore
}
from
"@/store/v1/conversation"
;
import
{
Message
,
useMessageStore
}
from
"@/store/v1/message"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
generateUUID
}
from
"@/utils/uuid"
;
const
chatStreaming
=
async
(
messageList
:
Array
<
Message
>
,
onmessage
:
any
,
onclose
:
any
)
=>
{
await
fetchEventSource
(
"/api/v1/openai/chat-streaming"
,
{
method
:
"POST"
,
headers
:
{
"Content-Type"
:
"application/json"
,
},
body
:
JSON
.
stringify
(
messageList
),
async
onopen
()
{
// to do nth
},
onmessage
(
event
:
any
)
{
onmessage
(
event
);
},
onclose
()
{
onclose
();
},
onerror
(
error
:
any
)
{
console
.
log
(
"error"
,
error
);
},
});
};
const
MemoChat
=
()
=>
{
const
t
=
useTranslate
();
const
fetchingState
=
useLoading
(
false
);
const
[
isEnabled
,
setIsEnabled
]
=
useState
<
boolean
>
(
true
);
const
[
isInIME
,
setIsInIME
]
=
useState
(
false
);
const
[
question
,
setQuestion
]
=
useState
<
string
>
(
""
);
const
conversationStore
=
useConversationStore
();
const
conversationList
=
conversationStore
.
conversationList
;
const
[
selectedConversationId
,
setSelectedConversationId
]
=
useState
<
string
>
(
head
(
conversationList
)?.
messageStorageId
||
""
);
const
messageStore
=
useMessageStore
(
selectedConversationId
)();
const
messageList
=
messageStore
.
messageList
;
// The state didn't show in component, just for trigger re-render
const
[
message
,
setMessage
]
=
useState
<
string
>
(
""
);
useEffect
(()
=>
{
api
.
checkOpenAIEnabled
().
then
(({
data
})
=>
{
setIsEnabled
(
data
);
});
},
[]);
// to new a conversation when no conversation
useEffect
(()
=>
{
if
(
conversationList
.
length
===
0
)
{
newConversation
();
}
},
[
conversationList
]);
// to select head message conversation(conversation) when conversation be deleted
useEffect
(()
=>
{
setSelectedConversationId
(
head
(
conversationList
)?.
messageStorageId
||
""
);
},
[
conversationList
]);
const
handleGotoSystemSetting
=
()
=>
{
window
.
open
(
`/setting`
);
};
const
handleQuestionTextareaChange
=
async
(
event
:
React
.
ChangeEvent
<
HTMLTextAreaElement
>
)
=>
{
setQuestion
(
event
.
currentTarget
.
value
);
};
const
handleKeyDown
=
(
event
:
React
.
KeyboardEvent
)
=>
{
if
(
event
.
key
===
"Enter"
&&
!
event
.
shiftKey
&&
!
isInIME
)
{
event
.
preventDefault
();
handleSendQuestionButtonClick
().
then
();
}
};
const
handleSendQuestionButtonClick
=
async
()
=>
{
if
(
!
question
)
{
return
;
}
fetchingState
.
setLoading
();
setQuestion
(
""
);
messageStore
.
addMessage
({
id
:
generateUUID
(),
role
:
"user"
,
content
:
question
,
});
const
messageId
=
generateUUID
();
messageStore
.
addMessage
({
id
:
messageId
,
role
:
"assistant"
,
content
:
""
,
});
try
{
fetchChatStreaming
(
messageId
);
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toast
.
error
(
error
.
response
.
data
.
error
);
}
};
const
fetchChatStreaming
=
async
(
messageId
:
string
)
=>
{
const
messageList
=
messageStore
.
getState
().
messageList
;
await
chatStreaming
(
messageList
,
async
(
event
:
any
)
=>
{
messageStore
.
updateMessage
(
messageId
,
event
.
data
);
// to trigger re-render
setMessage
(
message
+
event
.
data
);
},
async
()
=>
{
fetchingState
.
setFinish
();
}
);
};
const
newConversation
=
()
=>
{
const
uuid
=
generateUUID
();
// get the time HH:mm as the default name
const
name
=
new
Date
().
toLocaleTimeString
(
"en-US"
,
{
hour
:
"2-digit"
,
minute
:
"2-digit"
,
});
conversationStore
.
addConversation
({
name
:
name
,
messageStorageId
:
uuid
,
});
setSelectedConversationId
(
uuid
);
};
return
(
<
section
className=
"w-full max-w-3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2 sm:pt-4 pb-8 bg-zinc-100 dark:bg-zinc-800"
>
<
MobileHeader
showSearch=
{
false
}
/>
<
div
className=
"w-full flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
div
className=
"w-full flex"
>
<
div
className=
"w-auto flex flex-row justify-start items-center select-none shrink-0 mr-4"
>
<
Icon
.
Bot
className=
"w-5 h-auto mr-1"
/>
{
t
(
"memo-chat.title"
)
}
</
div
>
<
div
className=
"flex flex-row w-auto justify-start items-center overflow-y-hidden overflow-x-auto"
>
<
div
className=
"flex space-x-2 overflow-x-auto"
>
{
conversationList
.
map
((
item
:
Conversation
)
=>
(
<
ConversationTab
key=
{
item
.
messageStorageId
}
item=
{
item
}
selectedConversationId=
{
selectedConversationId
}
setSelectedConversationId=
{
setSelectedConversationId
}
closeConversation=
{
(
e
)
=>
{
// this is very important. otherwise, the select event also be clicked.
e
.
stopPropagation
();
conversationStore
.
removeConversation
(
item
);
toast
.
success
(
"Remove successfully"
);
}
}
/>
))
}
</
div
>
<
button
className=
"btn-text px-1 ml-1 shrink-0"
>
<
Icon
.
Plus
className=
"w-4 h-auto"
onClick=
{
()
=>
{
newConversation
();
}
}
/>
</
button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container w-full"
>
<
Stack
spacing=
{
2
}
style=
{
{
width
:
"100%"
}
}
>
{
messageList
.
length
==
0
&&
(
<
div
className=
"w-full mt-8 mb-8 flex flex-col justify-center items-center italic"
>
<
Empty
/>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"memo-chat.no-message"
)
}
</
p
>
</
div
>
)
}
{
messageList
.
map
((
message
,
index
)
=>
(
<
ChatMessage
key=
{
index
}
message=
{
message
}
index=
{
index
}
/>
))
}
</
Stack
>
{
fetchingState
.
isLoading
&&
(
<
p
className=
"w-full py-2 mt-4 flex flex-row justify-center items-center"
>
<
Icon
.
Loader
className=
"w-5 h-auto animate-spin"
/>
</
p
>
)
}
{
!
isEnabled
&&
(
<
div
className=
"w-full flex flex-col justify-center items-center mt-4 space-y-2"
>
<
p
>
{
t
(
"memo-chat.not-enabled"
)
}
</
p
>
<
Button
onClick=
{
()
=>
handleGotoSystemSetting
()
}
>
{
t
(
"memo-chat.go-to-settings"
)
}
</
Button
>
</
div
>
)
}
<
ChatInput
question=
{
question
}
handleQuestionTextareaChange=
{
handleQuestionTextareaChange
}
setIsInIME=
{
setIsInIME
}
handleKeyDown=
{
handleKeyDown
}
handleSendQuestionButtonClick=
{
handleSendQuestionButtonClick
}
/>
</
div
>
</
div
>
</
section
>
);
};
export
default
MemoChat
;
web/src/router/index.tsx
View file @
aa26cc30
...
@@ -16,7 +16,6 @@ const Home = lazy(() => import("@/pages/Home"));
...
@@ -16,7 +16,6 @@ const Home = lazy(() => import("@/pages/Home"));
const
MemoDetail
=
lazy
(()
=>
import
(
"@/pages/MemoDetail"
));
const
MemoDetail
=
lazy
(()
=>
import
(
"@/pages/MemoDetail"
));
const
EmbedMemo
=
lazy
(()
=>
import
(
"@/pages/EmbedMemo"
));
const
EmbedMemo
=
lazy
(()
=>
import
(
"@/pages/EmbedMemo"
));
const
NotFound
=
lazy
(()
=>
import
(
"@/pages/NotFound"
));
const
NotFound
=
lazy
(()
=>
import
(
"@/pages/NotFound"
));
const
MemoChat
=
lazy
(()
=>
import
(
"@/pages/MemoChat"
));
const
initialGlobalStateLoader
=
(()
=>
{
const
initialGlobalStateLoader
=
(()
=>
{
let
done
=
false
;
let
done
=
false
;
...
@@ -162,27 +161,6 @@ const router = createBrowserRouter([
...
@@ -162,27 +161,6 @@ const router = createBrowserRouter([
return
null
;
return
null
;
},
},
},
},
{
path
:
"memo-chat"
,
element
:
<
MemoChat
/>,
loader
:
async
()
=>
{
await
initialGlobalStateLoader
();
try
{
await
initialUserState
();
}
catch
(
error
)
{
// do nth
}
const
{
user
}
=
store
.
getState
().
user
;
if
(
isNullorUndefined
(
user
))
{
return
redirect
(
"/auth"
);
}
return
null
;
},
},
{
{
path
:
"archived"
,
path
:
"archived"
,
element
:
<
Archived
/>,
element
:
<
Archived
/>,
...
...
web/src/store/v1/conversation.ts
deleted
100644 → 0
View file @
1ce82ba0
import
{
t
}
from
"i18next"
;
import
{
create
}
from
"zustand"
;
import
{
persist
}
from
"zustand/middleware"
;
export
interface
Conversation
{
name
:
string
;
messageStorageId
:
string
;
}
interface
ConversationState
{
conversationList
:
Conversation
[];
getState
:
()
=>
ConversationState
;
addConversation
:
(
conversation
:
Conversation
)
=>
void
;
removeConversation
:
(
conversation
:
Conversation
)
=>
Conversation
;
}
export
const
defaultConversation
:
Conversation
=
{
name
:
t
(
"ask-ai.default-message-conversation-title"
),
messageStorageId
:
"message-storage"
,
};
export
const
useConversationStore
=
create
<
ConversationState
>
()(
persist
(
(
set
,
get
)
=>
({
conversationList
:
[],
getState
:
()
=>
get
(),
addConversation
:
(
conversation
:
Conversation
)
=>
set
((
state
)
=>
({
conversationList
:
[...
state
.
conversationList
,
conversation
]
})),
removeConversation
:
(
conversation
:
Conversation
)
=>
{
set
((
state
)
=>
({
conversationList
:
state
.
conversationList
.
filter
(
(
i
)
=>
i
.
name
!=
conversation
.
name
||
i
.
messageStorageId
!=
conversation
.
messageStorageId
),
}));
localStorage
.
removeItem
(
conversation
.
messageStorageId
);
const
conversationList
=
get
().
conversationList
;
return
conversationList
.
length
>
0
?
conversationList
[
conversationList
.
length
-
1
]
:
defaultConversation
;
},
}),
{
name
:
"message-conversation-storage"
,
}
)
);
web/src/store/v1/message.ts
deleted
100644 → 0
View file @
1ce82ba0
import
{
create
}
from
"zustand"
;
import
{
persist
}
from
"zustand/middleware"
;
export
interface
Message
{
id
:
string
;
role
:
"user"
|
"assistant"
;
content
:
string
;
}
interface
MessageState
{
messageList
:
Message
[];
getState
:
()
=>
MessageState
;
addMessage
:
(
message
:
Message
)
=>
void
;
updateMessage
:
(
id
:
string
,
appendContent
:
string
)
=>
void
;
}
export
const
useMessageStore
=
(
messageStorageId
:
string
)
=>
{
return
create
<
MessageState
>
()(
persist
(
(
set
,
get
)
=>
({
messageList
:
[]
as
Message
[],
getState
:
()
=>
get
(),
addMessage
:
(
message
:
Message
)
=>
{
return
set
((
state
)
=>
({
messageList
:
[...
state
.
messageList
,
message
]
}));
},
updateMessage
:
(
id
:
string
,
appendContent
:
string
)
=>
set
((
state
)
=>
({
...
state
,
messageList
:
state
.
messageList
.
map
((
item
)
=>
(
item
.
id
===
id
?
{
...
item
,
content
:
item
.
content
+
appendContent
}
:
item
)),
})),
}),
{
name
:
messageStorageId
,
}
)
);
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment