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
01f47806
Unverified
Commit
01f47806
authored
Jul 15, 2023
by
boojack
Committed by
GitHub
Jul 15, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update detail styles (#1964)
parent
49dd9057
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
133 additions
and
160 deletions
+133
-160
package.json
web/package.json
+1
-0
pnpm-lock.yaml
web/pnpm-lock.yaml
+8
-1
Header.tsx
web/src/components/Header.tsx
+34
-25
ChatInput.tsx
web/src/components/MemoChat/ChatInput.tsx
+4
-9
ChatMessage.tsx
web/src/components/MemoChat/ChatMessage.tsx
+2
-2
ConversationTab.tsx
web/src/components/MemoChat/ConversationTab.tsx
+0
-0
index.tsx
web/src/components/MemoEditor/index.tsx
+3
-2
MemoList.tsx
web/src/components/MemoList.tsx
+1
-1
en.json
web/src/locales/en.json
+8
-0
Auth.tsx
web/src/pages/Auth.tsx
+29
-56
Explore.tsx
web/src/pages/Explore.tsx
+6
-19
MemoChat.tsx
web/src/pages/MemoChat.tsx
+9
-12
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+24
-31
index.tsx
web/src/router/index.tsx
+2
-2
memo.ts
web/src/store/module/memo.ts
+2
-0
No files found.
web/package.json
View file @
01f47806
...
...
@@ -14,6 +14,7 @@
"@mui/joy"
:
"^5.0.0-alpha.75"
,
"@reduxjs/toolkit"
:
"^1.8.1"
,
"axios"
:
"^0.27.2"
,
"classnames"
:
"^2.3.2"
,
"copy-to-clipboard"
:
"^3.3.2"
,
"highlight.js"
:
"^11.6.0"
,
"i18next"
:
"^21.9.2"
,
...
...
web/pnpm-lock.yaml
View file @
01f47806
lockfileVersion
:
'
6.
0
'
lockfileVersion
:
'
6.
1
'
settings
:
autoInstallPeers
:
true
...
...
@@ -23,6 +23,9 @@ dependencies:
axios
:
specifier
:
^0.27.2
version
:
0.27.2
classnames
:
specifier
:
^2.3.2
version
:
2.3.2
copy-to-clipboard
:
specifier
:
^3.3.2
version
:
3.3.2
...
...
@@ -1346,6 +1349,10 @@ packages:
fsevents
:
2.3.2
dev
:
false
/classnames@2.3.2
:
resolution
:
{
integrity
:
sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
}
dev
:
false
/clsx@1.2.1
:
resolution
:
{
integrity
:
sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
}
engines
:
{
node
:
'
>=6'
}
...
...
web/src/components/Header.tsx
View file @
01f47806
import
classNames
from
"classnames"
;
import
{
useEffect
}
from
"react"
;
import
{
NavLink
,
useLocation
}
from
"react-router-dom"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useLayoutStore
,
useUserStore
}
from
"@/store/module"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
resolution
}
from
"@/utils/layout"
;
import
Icon
from
"./Icon"
;
import
UserBanner
from
"./UserBanner"
;
...
...
@@ -53,9 +54,10 @@ const Header = () => {
to=
"/"
id=
"header-home"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
@@ -66,9 +68,10 @@ const Header = () => {
to=
"/review"
id=
"header-review"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
@@ -79,9 +82,10 @@ const Header = () => {
to=
"/resources"
id=
"header-resources"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
@@ -94,9 +98,10 @@ const Header = () => {
to=
"/explore"
id=
"header-explore"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
@@ -110,9 +115,10 @@ const Header = () => {
to=
"/memo-chat"
id=
"header-memo-chat"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 shadow"
} px-4 pr-5 py-2 rounded-full flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:shadow dark:hover:bg-zinc-700`
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"
)
}
>
<>
...
...
@@ -123,9 +129,10 @@ const Header = () => {
to=
"/archived"
id=
"header-archived"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
@@ -136,9 +143,10 @@ const Header = () => {
to=
"/setting"
id=
"header-setting"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
@@ -154,9 +162,10 @@ const Header = () => {
to=
"/auth"
id=
"header-auth"
className=
{
({
isActive
})
=>
`${
isActive && "bg-white dark:bg-zinc-700 border-gray-200 dark:border-zinc-600"
} px-4 pr-5 py-2 rounded-full border border-transparent 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`
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"
)
}
>
<>
...
...
web/src/components/Memo
sChat/Memos
ChatInput.tsx
→
web/src/components/Memo
Chat/
ChatInput.tsx
View file @
01f47806
...
...
@@ -2,20 +2,15 @@ import Icon from "@/components/Icon";
import
Textarea
from
"@mui/joy/Textarea/Textarea"
;
import
{
useTranslation
}
from
"react-i18next"
;
interface
MemosChatInput
Props
{
interface
Props
{
question
:
string
;
handleQuestionTextareaChange
:
any
;
setIsInIME
:
any
;
handleKeyDown
:
any
;
handleSendQuestionButtonClick
:
any
;
}
const
MemosChatInput
=
({
question
,
handleQuestionTextareaChange
,
setIsInIME
,
handleKeyDown
,
handleSendQuestionButtonClick
,
}:
MemosChatInputProps
)
=>
{
const
ChatInput
=
({
question
,
handleQuestionTextareaChange
,
setIsInIME
,
handleKeyDown
,
handleSendQuestionButtonClick
}:
Props
)
=>
{
const
{
t
}
=
useTranslation
();
return
(
...
...
@@ -39,4 +34,4 @@ const MemosChatInput = ({
);
};
export
default
Memos
ChatInput
;
export
default
ChatInput
;
web/src/components/Memo
sChat/Memos
ChatMessage.tsx
→
web/src/components/Memo
Chat/
ChatMessage.tsx
View file @
01f47806
...
...
@@ -7,7 +7,7 @@ interface MessageProps {
message
:
Message
;
}
const
Memos
ChatMessage
=
({
index
,
message
}:
MessageProps
)
=>
{
const
ChatMessage
=
({
index
,
message
}:
MessageProps
)
=>
{
return
(
<
div
key=
{
index
}
className=
"w-full flex flex-col justify-start items-start space-y-2"
>
{
message
.
role
===
"user"
?
(
...
...
@@ -28,4 +28,4 @@ const MemosChatMessage = ({ index, message }: MessageProps) => {
);
};
export
default
Memos
ChatMessage
;
export
default
ChatMessage
;
web/src/components/Memo
s
Chat/ConversationTab.tsx
→
web/src/components/MemoChat/ConversationTab.tsx
View file @
01f47806
File moved
web/src/components/MemoEditor/index.tsx
View file @
01f47806
import
{
Button
}
from
"@mui/joy"
;
import
{
isNumber
,
last
,
uniq
}
from
"lodash-es"
;
import
React
,
{
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
...
...
@@ -421,9 +422,9 @@ const MemoEditor = (props: Props) => {
<
div
className=
"editor-footer-container"
>
<
MemoVisibilitySelector
value=
{
state
.
memoVisibility
}
onChange=
{
handleMemoVisibilityChange
}
/>
<
div
className=
"buttons-container"
>
<
button
className=
"action-btn confirm-btn"
disabled=
{
!
allowSave
}
onClick=
{
handleSaveBtnClick
}
>
<
Button
disabled=
{
!
allowSave
}
onClick=
{
handleSaveBtnClick
}
>
{
t
(
"editor.save"
)
}
</
b
utton
>
</
B
utton
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/MemoList.tsx
View file @
01f47806
...
...
@@ -76,7 +76,7 @@ const MemoList = () => {
return shouldShow;
}
)
: memos
).filter((memo) =
>
memo.creatorId === currentUserId);
).filter((memo) =
>
memo.creatorId === currentUserId
&&
memo.rowStatus === "NORMAL"
);
const pinnedMemos = shownMemos.filter((m) =
>
m.pinned);
const unpinnedMemos = shownMemos.filter((m) =
>
!m.pinned);
...
...
web/src/locales/en.json
View file @
01f47806
...
...
@@ -326,6 +326,14 @@
"and"
:
"And"
,
"or"
:
"Or"
},
"amount-text"
:
{
"memo_one"
:
"MEMO"
,
"memo_other"
:
"MEMOS"
,
"tag_one"
:
"TAG"
,
"tag_other"
:
"TAGS"
,
"day_one"
:
"TAG"
,
"day_other"
:
"TAGE"
},
"message"
:
{
"no-data"
:
"Maybe no data was found, maybe it should be another option."
,
"memos-ready"
:
"all memos are ready 🎉"
,
...
...
web/src/pages/Auth.tsx
View file @
01f47806
import
{
Button
,
Divider
}
from
"@mui/joy"
;
import
{
Button
,
Divider
,
Input
}
from
"@mui/joy"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
...
@@ -131,71 +131,44 @@ const Auth = () => {
<
div
className=
"flex flex-row justify-center items-center w-full h-full dark:bg-zinc-800"
>
<
div
className=
"w-80 max-w-full h-full py-4 flex flex-col justify-start items-center"
>
<
div
className=
"w-full py-4 grow flex flex-col justify-center items-center"
>
<
div
className=
"flex flex-col justify-start items-start w-full mb-4"
>
<
div
className=
"w-full flex flex-row justify-start items-center mb-2"
>
<
img
className=
"h-12 w-auto rounded-lg mr-1"
src=
{
systemStatus
.
customizedProfile
.
logoUrl
}
alt=
""
/>
<
p
className=
"text-6xl tracking-wide text-black opacity-80 dark:text-gray-200"
>
{
systemStatus
.
customizedProfile
.
name
}
</
p
>
</
div
>
<
p
className=
"text-sm text-gray-700 dark:text-gray-300"
>
{
systemStatus
.
customizedProfile
.
description
||
t
(
"common.memos-slogan"
)
}
</
p
>
<
div
className=
"w-full flex flex-col justify-center items-center mb-2"
>
<
img
className=
"h-20 w-auto rounded-full shadow mr-1"
src=
{
systemStatus
.
customizedProfile
.
logoUrl
}
alt=
""
/>
<
p
className=
"text-3xl text-black opacity-80 dark:text-gray-200"
>
{
systemStatus
.
customizedProfile
.
name
}
</
p
>
</
div
>
<
form
className=
"w-full"
onSubmit=
{
handleFormSubmit
}
>
<
div
className=
{
`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading && "opacity-80"}`
}
>
<
div
className=
"flex flex-col justify-start items-start relative w-full text-base mt-2 py-2"
>
<
span
className=
{
`absolute top-3 left-3 px-1 leading-10 shrink-0 text-base cursor-text text-gray-400 transition-all select-none pointer-events-none ${
username ? "!text-sm !top-0 !z-10 !leading-4 bg-white dark:bg-zinc-800 rounded" : ""
}`
}
>
{
t
(
"common.username"
)
}
</
span
>
<
input
className=
"input-text w-full py-3 px-3 text-base rounded-lg dark:bg-zinc-800"
type=
"text"
value=
{
username
}
onChange=
{
handleUsernameInputChanged
}
required
/>
</
div
>
<
div
className=
"flex flex-col justify-start items-start relative w-full text-base mt-2 py-2"
>
<
span
className=
{
`absolute top-3 left-3 px-1 leading-10 shrink-0 text-base cursor-text text-gray-400 transition-all select-none pointer-events-none ${
password ? "!text-sm !top-0 !z-10 !leading-4 bg-white dark:bg-zinc-800 rounded" : ""
}`
}
>
{
t
(
"common.password"
)
}
</
span
>
<
input
className=
"input-text w-full py-3 px-3 text-base rounded-lg dark:bg-zinc-800"
type=
"password"
value=
{
password
}
onChange=
{
handlePasswordInputChanged
}
required
/>
</
div
>
<
form
className=
"w-full mt-4"
onSubmit=
{
handleFormSubmit
}
>
<
div
className=
"flex flex-col justify-start items-start w-full gap-4"
>
<
Input
className=
"w-full"
size=
"lg"
type=
"text"
placeholder=
{
t
(
"common.username"
)
}
value=
{
username
}
onChange=
{
handleUsernameInputChanged
}
required
/>
<
Input
className=
"w-full"
size=
"lg"
type=
"password"
placeholder=
{
t
(
"common.password"
)
}
value=
{
password
}
onChange=
{
handlePasswordInputChanged
}
required
/>
</
div
>
<
div
className=
"flex flex-row justify-end items-center w-full mt-
2
"
>
<
div
className=
"flex flex-row justify-end items-center w-full mt-
6
"
>
{
actionBtnLoadingState
.
isLoading
&&
<
Icon
.
Loader
className=
"w-4 h-auto mr-2 animate-spin dark:text-gray-300"
/>
}
{
systemStatus
?.
allowSignUp
&&
(
<>
<
button
type=
"button"
className=
{
`btn-text ${actionBtnLoadingState.isLoading ? "cursor-wait opacity-80" : ""}`
}
onClick=
{
handleSignUpButtonClick
}
>
<
Button
variant=
{
"plain"
}
loading=
{
actionBtnLoadingState
.
isLoading
}
onClick=
{
handleSignUpButtonClick
}
>
{
t
(
"common.sign-up"
)
}
</
b
utton
>
</
B
utton
>
<
span
className=
"mr-2 font-mono text-gray-200"
>
/
</
span
>
</>
)
}
<
button
type=
"submit"
className=
{
`btn-primary ${actionBtnLoadingState.isLoading ? "cursor-wait opacity-80" : ""}`
}
onClick=
{
handleSignInButtonClick
}
>
<
Button
type=
"submit"
loading=
{
actionBtnLoadingState
.
isLoading
}
onClick=
{
handleSignInButtonClick
}
>
{
t
(
"common.sign-in"
)
}
</
b
utton
>
</
B
utton
>
</
div
>
</
form
>
{
identityProviderList
.
length
>
0
&&
(
...
...
web/src/pages/Explore.tsx
View file @
01f47806
...
...
@@ -11,19 +11,13 @@ import Memo from "@/components/Memo";
import
MobileHeader
from
"@/components/MobileHeader"
;
import
Empty
from
"@/components/Empty"
;
interface
State
{
memos
:
Memo
[];
}
const
Explore
=
()
=>
{
const
t
=
useTranslate
();
const
location
=
useLocation
();
const
filterStore
=
useFilterStore
();
const
memoStore
=
useMemoStore
();
const
filter
=
filterStore
.
state
;
const
[
state
,
setState
]
=
useState
<
State
>
({
memos
:
[],
});
const
memos
=
memoStore
.
state
.
memos
;
const
[
isComplete
,
setIsComplete
]
=
useState
<
boolean
>
(
false
);
const
loadingState
=
useLoading
();
...
...
@@ -32,9 +26,6 @@ const Explore = () => {
if
(
memos
.
length
<
DEFAULT_MEMO_LIMIT
)
{
setIsComplete
(
true
);
}
setState
({
memos
,
});
loadingState
.
setFinish
();
});
},
[
location
]);
...
...
@@ -43,7 +34,7 @@ const Explore = () => {
const
showMemoFilter
=
Boolean
(
tagQuery
||
textQuery
);
const
shownMemos
=
showMemoFilter
?
state
.
memos
.
filter
((
memo
)
=>
{
?
memos
.
filter
((
memo
)
=>
{
let
shouldShow
=
true
;
if
(
tagQuery
)
{
...
...
@@ -64,21 +55,17 @@ const Explore = () => {
}
return
shouldShow
;
})
:
state
.
memos
;
const
sortedMemos
=
shownMemos
.
filter
((
m
)
=>
m
.
rowStatus
===
"NORMAL"
);
:
memos
;
const
sortedMemos
=
shownMemos
.
filter
((
m
)
=>
m
.
rowStatus
===
"NORMAL"
&&
m
.
visibility
!==
"PRIVATE"
);
const
handleFetchMoreClick
=
async
()
=>
{
try
{
const
fetchedMemos
=
await
memoStore
.
fetchAllMemos
(
DEFAULT_MEMO_LIMIT
,
state
.
memos
.
length
);
const
fetchedMemos
=
await
memoStore
.
fetchAllMemos
(
DEFAULT_MEMO_LIMIT
,
memos
.
length
);
if
(
fetchedMemos
.
length
<
DEFAULT_MEMO_LIMIT
)
{
setIsComplete
(
true
);
}
else
{
setIsComplete
(
false
);
}
setState
({
memos
:
state
.
memos
.
concat
(
fetchedMemos
),
});
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toast
.
error
(
error
.
response
.
data
.
message
);
...
...
@@ -95,7 +82,7 @@ const Explore = () => {
return
<
Memo
key=
{
`${memo.id}-${memo.displayTs}`
}
memo=
{
memo
}
showCreator
/>;
})
}
{
isComplete
?
(
state
.
memos
.
length
===
0
&&
(
memos
.
length
===
0
&&
(
<
div
className=
"w-full mt-16 mb-8 flex flex-col justify-center items-center italic"
>
<
Empty
/>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
...
...
web/src/pages/Memo
s
Chat.tsx
→
web/src/pages/MemoChat.tsx
View file @
01f47806
import
{
Button
,
Stack
}
from
"@mui/joy"
;
import
{
head
}
from
"lodash-es"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useTranslation
}
from
"react-i18next"
;
...
...
@@ -9,27 +10,23 @@ import { Conversation, useConversationStore } from "@/store/zustand/conversation
import
Icon
from
"@/components/Icon"
;
import
{
generateUUID
}
from
"@/utils/uuid"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
MemosChatMessage
from
"@/components/MemosChat/MemosChatMessage"
;
import
MemosChatInput
from
"@/components/MemosChat/MemosChatInput"
;
import
head
from
"lodash-es/head"
;
import
ConversationTab
from
"@/components/MemosChat/ConversationTab"
;
import
ChatMessage
from
"@/components/MemoChat/ChatMessage"
;
import
ChatInput
from
"@/components/MemoChat/ChatInput"
;
import
ConversationTab
from
"@/components/MemoChat/ConversationTab"
;
import
Empty
from
"@/components/Empty"
;
const
Memo
s
Chat
=
()
=>
{
const
MemoChat
=
()
=>
{
const
{
t
}
=
useTranslation
();
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
// The state didn't show in component, just for trigger re-render
const
[
message
,
setMessage
]
=
useState
<
string
>
(
""
);
useEffect
(()
=>
{
...
...
@@ -170,7 +167,7 @@ const MemosChat = () => {
</
div
>
)
}
{
messageList
.
map
((
message
,
index
)
=>
(
<
Memos
ChatMessage
key=
{
index
}
message=
{
message
}
index=
{
index
}
/>
<
ChatMessage
key=
{
index
}
message=
{
message
}
index=
{
index
}
/>
))
}
</
Stack
>
{
fetchingState
.
isLoading
&&
(
...
...
@@ -185,7 +182,7 @@ const MemosChat = () => {
</
div
>
)
}
<
Memos
ChatInput
<
ChatInput
question=
{
question
}
handleQuestionTextareaChange=
{
handleQuestionTextareaChange
}
setIsInIME=
{
setIsInIME
}
...
...
@@ -198,4 +195,4 @@ const MemosChat = () => {
);
};
export
default
Memo
s
Chat
;
export
default
MemoChat
;
web/src/pages/MemoDetail.tsx
View file @
01f47806
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
Link
,
useLocation
,
useParams
}
from
"react-router-dom"
;
import
{
UNKNOWN_ID
}
from
"@/helpers/consts"
;
import
{
useGlobalStore
,
useMemoStore
}
from
"@/store/module"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
Icon
from
"@/components/Icon"
;
import
Memo
from
"@/components/Memo"
;
interface
State
{
memo
:
Memo
;
}
const
MemoDetail
=
()
=>
{
const
t
=
useTranslate
();
const
params
=
useParams
();
const
location
=
useLocation
();
const
globalStore
=
useGlobalStore
();
const
memoStore
=
useMemoStore
();
const
[
state
,
setState
]
=
useState
<
State
>
({
memo
:
{
id
:
UNKNOWN_ID
,
}
as
Memo
,
});
const
loadingState
=
useLoading
();
const
customizedProfile
=
globalStore
.
state
.
systemStatus
.
customizedProfile
;
const
memoId
=
Number
(
params
.
memoId
);
const
memo
=
memoStore
.
state
.
memos
.
find
((
memo
)
=>
memo
.
id
===
memoId
);
useEffect
(()
=>
{
const
memoId
=
Number
(
params
.
memoId
);
if
(
memoId
&&
!
isNaN
(
memoId
))
{
memoStore
.
fetchMemoById
(
memoId
)
.
then
((
memo
)
=>
{
setState
({
memo
,
});
.
then
(()
=>
{
loadingState
.
setFinish
();
})
.
catch
((
error
)
=>
{
...
...
@@ -53,21 +41,26 @@ const MemoDetail = () => {
<
p
className=
"detail-name text-4xl tracking-wide text-black dark:text-white"
>
{
customizedProfile
.
name
}
</
p
>
</
div
>
</
div
>
{
!
loadingState
.
isLoading
&&
(
<>
<
main
className=
"relative flex-grow max-w-2xl w-full min-h-full flex flex-col justify-start items-start px-4"
>
<
Memo
memo=
{
state
.
memo
}
showCreator
showRelatedMemos
/>
</
main
>
<
div
className=
"mt-4 w-full flex flex-row justify-center items-center gap-2"
>
<
Link
to=
"/"
className=
"flex flex-row justify-center items-center text-gray-600 dark:text-gray-300 text-sm px-3 hover:opacity-80 hover:underline"
>
<
Icon
.
Home
className=
"w-4 h-auto mr-1 -mt-0.5"
/>
{
t
(
"router.back-to-home"
)
}
</
Link
>
</
div
>
</>
)
}
{
!
loadingState
.
isLoading
&&
(
memo
?
(
<>
<
main
className=
"relative flex-grow max-w-2xl w-full min-h-full flex flex-col justify-start items-start px-4"
>
<
Memo
memo=
{
memo
}
showCreator
showRelatedMemos
/>
</
main
>
<
div
className=
"mt-4 w-full flex flex-row justify-center items-center gap-2"
>
<
Link
to=
"/"
className=
"flex flex-row justify-center items-center text-gray-600 dark:text-gray-300 text-sm px-3 hover:opacity-80 hover:underline"
>
<
Icon
.
Home
className=
"w-4 h-auto mr-1 -mt-0.5"
/>
{
t
(
"router.back-to-home"
)
}
</
Link
>
</
div
>
</>
)
:
(
<>
<
p
>
Not found
</
p
>
</>
))
}
</
div
>
</
section
>
);
...
...
web/src/router/index.tsx
View file @
01f47806
...
...
@@ -16,7 +16,7 @@ const Home = lazy(() => import("@/pages/Home"));
const
MemoDetail
=
lazy
(()
=>
import
(
"@/pages/MemoDetail"
));
const
EmbedMemo
=
lazy
(()
=>
import
(
"@/pages/EmbedMemo"
));
const
NotFound
=
lazy
(()
=>
import
(
"@/pages/NotFound"
));
const
Memo
sChat
=
lazy
(()
=>
import
(
"@/pages/Memos
Chat"
));
const
Memo
Chat
=
lazy
(()
=>
import
(
"@/pages/Memo
Chat"
));
const
initialGlobalStateLoader
=
(()
=>
{
let
done
=
false
;
...
...
@@ -150,7 +150,7 @@ const router = createBrowserRouter([
},
{
path
:
"memo-chat"
,
element
:
<
Memo
s
Chat
/>,
element
:
<
MemoChat
/>,
loader
:
async
()
=>
{
await
initialGlobalStateLoader
();
...
...
web/src/store/module/memo.ts
View file @
01f47806
...
...
@@ -23,6 +23,7 @@ export const useMemoStore = () => {
const
fetchMemoById
=
async
(
memoId
:
MemoId
)
=>
{
const
{
data
}
=
await
api
.
getMemoById
(
memoId
);
const
memo
=
convertResponseModelMemo
(
data
);
store
.
dispatch
(
upsertMemos
([
memo
]));
return
memo
;
};
...
...
@@ -62,6 +63,7 @@ export const useMemoStore = () => {
const
{
data
}
=
await
api
.
getAllMemos
(
memoFind
);
const
fetchedMemos
=
data
.
map
((
m
)
=>
convertResponseModelMemo
(
m
));
store
.
dispatch
(
upsertMemos
(
fetchedMemos
));
for
(
const
m
of
fetchedMemos
)
{
memoCacheStore
.
setMemoCache
(
m
);
...
...
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