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
fbbfb119
Commit
fbbfb119
authored
Sep 28, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: adjust memo elements
parent
c54febd0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
92 additions
and
50 deletions
+92
-50
Memo.tsx
web/src/components/Memo.tsx
+51
-11
PreferencesSection.tsx
web/src/components/Settings/PreferencesSection.tsx
+1
-1
consts.ts
web/src/helpers/consts.ts
+3
-3
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+37
-35
No files found.
web/src/components/Memo.tsx
View file @
fbbfb119
import
{
Divider
}
from
"@mui/joy"
;
import
{
Divider
,
Select
,
Tooltip
,
Option
}
from
"@mui/joy"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
UNKNOWN_ID
}
from
"@/helpers/consts"
;
import
{
UNKNOWN_ID
,
VISIBILITY_SELECTOR_ITEMS
}
from
"@/helpers/consts"
;
import
{
getRelativeTimeString
}
from
"@/helpers/datetime"
;
import
{
getRelativeTimeString
}
from
"@/helpers/datetime"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
...
@@ -90,6 +90,14 @@ const Memo: React.FC<Props> = (props: Props) => {
...
@@ -90,6 +90,14 @@ const Memo: React.FC<Props> = (props: Props) => {
return
<
div
className=
{
`memo-wrapper min-h-[128px] ${"memos-" + memo.id}`
}
ref=
{
memoContainerRef
}
></
div
>;
return
<
div
className=
{
`memo-wrapper min-h-[128px] ${"memos-" + memo.id}`
}
ref=
{
memoContainerRef
}
></
div
>;
}
}
const
handleMemoVisibilityOptionChanged
=
async
(
value
:
string
)
=>
{
const
visibilityValue
=
value
as
Visibility
;
await
memoStore
.
patchMemo
({
id
:
memo
.
id
,
visibility
:
visibilityValue
,
});
};
const
handleGotoMemoDetailPage
=
(
event
:
React
.
MouseEvent
<
HTMLDivElement
>
)
=>
{
const
handleGotoMemoDetailPage
=
(
event
:
React
.
MouseEvent
<
HTMLDivElement
>
)
=>
{
if
(
event
.
altKey
)
{
if
(
event
.
altKey
)
{
showChangeMemoCreatedTsDialog
(
memo
.
id
);
showChangeMemoCreatedTsDialog
(
memo
.
id
);
...
@@ -227,15 +235,6 @@ const Memo: React.FC<Props> = (props: Props) => {
...
@@ -227,15 +235,6 @@ const Memo: React.FC<Props> = (props: Props) => {
<
div
className=
{
`memo-wrapper ${"memos-" + memo.id} ${memo.pinned && !readonly ? "pinned" : ""}`
}
ref=
{
memoContainerRef
}
>
<
div
className=
{
`memo-wrapper ${"memos-" + memo.id} ${memo.pinned && !readonly ? "pinned" : ""}`
}
ref=
{
memoContainerRef
}
>
<
div
className=
"memo-top-wrapper"
>
<
div
className=
"memo-top-wrapper"
>
<
div
className=
"w-full max-w-[calc(100%-20px)] flex flex-row justify-start items-center mr-1"
>
<
div
className=
"w-full max-w-[calc(100%-20px)] flex flex-row justify-start items-center mr-1"
>
{
creator
&&
(
<>
<
Link
className=
"flex flex-row justify-start items-center"
to=
{
`/u/${encodeURIComponent(memo.creatorUsername)}`
}
>
<
UserAvatar
className=
"!w-5 !h-auto mr-1"
avatarUrl=
{
creator
.
avatarUrl
}
/>
<
span
className=
"text-sm text-gray-600 max-w-[8em] truncate dark:text-gray-400"
>
{
creator
.
nickname
}
</
span
>
</
Link
>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
</>
)
}
<
span
className=
"text-sm text-gray-400 select-none"
onClick=
{
handleGotoMemoDetailPage
}
>
<
span
className=
"text-sm text-gray-400 select-none"
onClick=
{
handleGotoMemoDetailPage
}
>
{
displayTime
}
{
displayTime
}
</
span
>
</
span
>
...
@@ -282,6 +281,47 @@ const Memo: React.FC<Props> = (props: Props) => {
...
@@ -282,6 +281,47 @@ const Memo: React.FC<Props> = (props: Props) => {
/>
/>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
MemoRelationListView
relationList=
{
memo
.
relationList
}
/>
<
MemoRelationListView
relationList=
{
memo
.
relationList
}
/>
<
div
className=
"mt-4 w-full flex flex-row justify-between items-center gap-2"
>
<
div
className=
"flex flex-row justify-start items-center"
>
{
creator
&&
(
<>
<
Link
className=
"flex flex-row justify-start items-center"
to=
{
`/m/${memo.id}`
}
>
<
Tooltip
title=
{
"The identifier of memo"
}
placement=
"top"
>
<
span
className=
"text-sm text-gray-500 dark:text-gray-400"
>
#
{
memo
.
id
}
</
span
>
</
Tooltip
>
</
Link
>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
<
Link
className=
"flex flex-row justify-start items-center"
to=
{
`/u/${encodeURIComponent(memo.creatorUsername)}`
}
>
<
UserAvatar
className=
"!w-5 !h-auto mr-1"
avatarUrl=
{
creator
.
avatarUrl
}
/>
<
span
className=
"text-sm text-gray-600 max-w-[8em] truncate dark:text-gray-400"
>
{
creator
.
nickname
}
</
span
>
</
Link
>
{
props
.
showVisibility
&&
(
<>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
<
Tooltip
title=
{
"The visibility of memo"
}
placement=
"top"
>
<
Select
className=
"w-auto text-sm"
variant=
"plain"
value=
{
memo
.
visibility
}
onChange=
{
(
_
,
visibility
)
=>
{
if
(
visibility
)
{
handleMemoVisibilityOptionChanged
(
visibility
);
}
}
}
>
{
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
(
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
{
item
.
text
}
</
Option
>
))
}
</
Select
>
</
Tooltip
>
</>
)
}
</>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</>
</>
);
);
...
...
web/src/components/Settings/PreferencesSection.tsx
View file @
fbbfb119
...
@@ -19,7 +19,7 @@ const PreferencesSection = () => {
...
@@ -19,7 +19,7 @@ const PreferencesSection = () => {
const
visibilitySelectorItems
=
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
{
const
visibilitySelectorItems
=
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
{
return
{
return
{
value
:
item
.
value
,
value
:
item
.
value
,
text
:
t
(
`memo.visibility.
${
item
.
text
.
toLowerCase
()
as
Lowercase
<
typeof
item
.
text
>
}
`
),
text
:
t
(
`memo.visibility.
${
item
.
value
.
toLowerCase
()
as
Lowercase
<
typeof
item
.
value
>
}
`
),
};
};
});
});
...
...
web/src/helpers/consts.ts
View file @
fbbfb119
...
@@ -9,9 +9,9 @@ export const ANIMATION_DURATION = 200;
...
@@ -9,9 +9,9 @@ export const ANIMATION_DURATION = 200;
export
const
DAILY_TIMESTAMP
=
3600
*
24
*
1000
;
export
const
DAILY_TIMESTAMP
=
3600
*
24
*
1000
;
export
const
VISIBILITY_SELECTOR_ITEMS
=
[
export
const
VISIBILITY_SELECTOR_ITEMS
=
[
{
text
:
"P
RIVATE
"
,
value
:
"PRIVATE"
},
{
text
:
"P
rivate
"
,
value
:
"PRIVATE"
},
{
text
:
"
PROTECTED
"
,
value
:
"PROTECTED"
},
{
text
:
"
Workspace
"
,
value
:
"PROTECTED"
},
{
text
:
"P
UBLIC
"
,
value
:
"PUBLIC"
},
{
text
:
"P
ublic
"
,
value
:
"PUBLIC"
},
]
as
const
;
]
as
const
;
// space width for tab action in editor
// space width for tab action in editor
...
...
web/src/pages/MemoDetail.tsx
View file @
fbbfb119
import
{
Divider
,
Select
,
Tooltip
,
Option
,
IconButton
}
from
"@mui/joy"
;
import
{
Divider
,
Select
,
Tooltip
,
Option
,
IconButton
}
from
"@mui/joy"
;
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
{
toLower
}
from
"lodash-es"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
useParams
}
from
"react-router-dom"
;
import
{
Link
,
useParams
}
from
"react-router-dom"
;
import
FloatingNavButton
from
"@/components/FloatingNavButton"
;
import
FloatingNavButton
from
"@/components/FloatingNavButton"
;
import
Icon
from
"@/components/Icon"
;
import
Icon
from
"@/components/Icon"
;
import
MemoContent
from
"@/components/MemoContent"
;
import
MemoContent
from
"@/components/MemoContent"
;
...
@@ -16,7 +15,7 @@ import { VISIBILITY_SELECTOR_ITEMS } from "@/helpers/consts";
...
@@ -16,7 +15,7 @@ import { VISIBILITY_SELECTOR_ITEMS } from "@/helpers/consts";
import
{
getDateTimeString
}
from
"@/helpers/datetime"
;
import
{
getDateTimeString
}
from
"@/helpers/datetime"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
useMemoStore
}
from
"@/store/module"
;
import
{
use
GlobalStore
,
use
MemoStore
}
from
"@/store/module"
;
import
{
useUserV1Store
}
from
"@/store/v1"
;
import
{
useUserV1Store
}
from
"@/store/v1"
;
import
{
User
}
from
"@/types/proto/api/v2/user_service"
;
import
{
User
}
from
"@/types/proto/api/v2/user_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -25,10 +24,12 @@ const MemoDetail = () => {
...
@@ -25,10 +24,12 @@ const MemoDetail = () => {
const
params
=
useParams
();
const
params
=
useParams
();
const
navigateTo
=
useNavigateTo
();
const
navigateTo
=
useNavigateTo
();
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
globalStore
=
useGlobalStore
();
const
memoStore
=
useMemoStore
();
const
memoStore
=
useMemoStore
();
const
userV1Store
=
useUserV1Store
();
const
userV1Store
=
useUserV1Store
();
const
currentUser
=
useCurrentUser
();
const
currentUser
=
useCurrentUser
();
const
[
user
,
setUser
]
=
useState
<
User
>
();
const
[
user
,
setUser
]
=
useState
<
User
>
();
const
{
systemStatus
}
=
globalStore
.
state
;
const
memoId
=
Number
(
params
.
memoId
);
const
memoId
=
Number
(
params
.
memoId
);
const
memo
=
memoStore
.
state
.
memos
.
find
((
memo
)
=>
memo
.
id
===
memoId
);
const
memo
=
memoStore
.
state
.
memos
.
find
((
memo
)
=>
memo
.
id
===
memoId
);
const
allowEdit
=
memo
?.
creatorUsername
===
currentUser
?.
username
;
const
allowEdit
=
memo
?.
creatorUsername
===
currentUser
?.
username
;
...
@@ -54,13 +55,6 @@ const MemoDetail = () => {
...
@@ -54,13 +55,6 @@ const MemoDetail = () => {
return
null
;
return
null
;
}
}
const
memoVisibilityOptionSelectorItems
=
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
{
return
{
value
:
item
.
value
,
text
:
t
(
`memo.visibility.
${
toLower
(
item
.
value
)
as
Lowercase
<
typeof
item
.
value
>
}
`
),
};
});
const
handleMemoVisibilityOptionChanged
=
async
(
value
:
string
)
=>
{
const
handleMemoVisibilityOptionChanged
=
async
(
value
:
string
)
=>
{
const
visibilityValue
=
value
as
Visibility
;
const
visibilityValue
=
value
as
Visibility
;
await
memoStore
.
patchMemo
({
await
memoStore
.
patchMemo
({
...
@@ -85,42 +79,50 @@ const MemoDetail = () => {
...
@@ -85,42 +79,50 @@ const MemoDetail = () => {
<
section
className=
"relative top-0 w-full min-h-full overflow-x-hidden bg-white dark:bg-zinc-800"
>
<
section
className=
"relative top-0 w-full min-h-full overflow-x-hidden bg-white dark:bg-zinc-800"
>
<
div
className=
"relative w-full min-h-full mx-auto flex flex-col justify-start items-center pb-6"
>
<
div
className=
"relative w-full min-h-full mx-auto flex flex-col justify-start items-center pb-6"
>
<
div
className=
"w-full flex flex-col justify-start items-center py-8"
>
<
div
className=
"w-full flex flex-col justify-start items-center py-8"
>
<
UserAvatar
className=
"!w-20 h-auto mb-4 drop-shadow"
avatarUrl=
{
user
?.
avatarUrl
}
/>
<
UserAvatar
className=
"!w-20 h-auto mb-2 drop-shadow"
avatarUrl=
{
systemStatus
.
customizedProfile
.
logoUrl
}
/>
<
div
>
<
p
className=
"text-3xl text-black opacity-80 dark:text-gray-200"
>
{
systemStatus
.
customizedProfile
.
name
}
</
p
>
<
p
className=
"text-2xl font-bold text-gray-700 dark:text-gray-300"
>
{
user
?.
nickname
}
</
p
>
</
div
>
</
div
>
</
div
>
<
div
className=
"relative flex-grow max-w-2xl w-full min-h-full flex flex-col justify-start items-start px-4"
>
<
div
className=
"relative flex-grow max-w-2xl w-full min-h-full flex flex-col justify-start items-start px-4"
>
<
div
className=
"w-full mb-4 flex flex-row justify-start items-center mr-1"
>
<
span
className=
"text-gray-400 select-none"
>
{
getDateTimeString
(
memo
.
displayTs
)
}
</
span
>
</
div
>
<
MemoContent
content=
{
memo
.
content
}
/>
<
MemoContent
content=
{
memo
.
content
}
/>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
MemoRelationListView
relationList=
{
memo
.
relationList
}
/>
<
MemoRelationListView
relationList=
{
memo
.
relationList
}
/>
<
Divider
className=
"!my-6"
/>
<
Divider
className=
"!my-6"
/>
<
div
className=
"w-full flex flex-col sm:flex-row justify-start sm:justify-between sm:items-center gap-2"
>
<
div
className=
"w-full flex flex-col sm:flex-row justify-start sm:justify-between sm:items-center gap-2"
>
<
div
className=
"flex flex-row justify-start items-center"
>
<
div
className=
"flex flex-row justify-start items-center"
>
<
span
className=
"text-sm text-gray-500 dark:text-gray-400"
>
{
getDateTimeString
(
memo
.
displayTs
)
}
</
span
>
<
span
className=
"mx-1 font-mono opacity-80 text-gray-400"
>
·
</
span
>
<
Tooltip
title=
{
"The identifier of memo"
}
placement=
"top"
>
<
Tooltip
title=
{
"The identifier of memo"
}
placement=
"top"
>
<
span
className=
"text-sm text-gray-500 dark:text-gray-400"
>
#
{
memo
.
id
}
</
span
>
<
span
className=
"text-sm text-gray-500 dark:text-gray-400"
>
#
{
memo
.
id
}
</
span
>
</
Tooltip
>
</
Tooltip
>
<
span
className=
"mx-1 font-mono opacity-80 text-gray-400"
>
·
</
span
>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
<
Tooltip
title=
{
"The visibility of memo"
}
placement=
"top"
>
<
Link
className=
"flex flex-row justify-start items-center"
to=
{
`/u/${encodeURIComponent(memo.creatorUsername)}`
}
>
<
Select
<
UserAvatar
className=
"!w-5 !h-auto mr-1"
avatarUrl=
{
user
?.
avatarUrl
}
/>
className=
"w-auto text-sm"
<
span
className=
"text-sm text-gray-600 max-w-[8em] truncate dark:text-gray-400"
>
{
user
?.
nickname
}
</
span
>
variant=
"plain"
</
Link
>
value=
{
memo
.
visibility
}
{
allowEdit
&&
(
onChange=
{
(
_
,
visibility
)
=>
{
<>
if
(
visibility
)
{
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
handleMemoVisibilityOptionChanged
(
visibility
);
<
Tooltip
title=
{
"The visibility of memo"
}
placement=
"top"
>
}
<
Select
}
}
className=
"w-auto text-sm"
>
variant=
"plain"
{
memoVisibilityOptionSelectorItems
.
map
((
item
)
=>
(
value=
{
memo
.
visibility
}
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
onChange=
{
(
_
,
visibility
)
=>
{
{
item
.
text
}
if
(
visibility
)
{
</
Option
>
handleMemoVisibilityOptionChanged
(
visibility
);
))
}
}
</
Select
>
}
}
</
Tooltip
>
>
{
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
(
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
{
item
.
text
}
</
Option
>
))
}
</
Select
>
</
Tooltip
>
</>
)
}
</
div
>
</
div
>
<
div
className=
"flex flex-row sm:justify-end items-center"
>
<
div
className=
"flex flex-row sm:justify-end items-center"
>
{
allowEdit
&&
(
{
allowEdit
&&
(
...
...
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