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
1d99dad4
Commit
1d99dad4
authored
May 08, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: update timeline page
parent
33133ea1
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
118 additions
and
229 deletions
+118
-229
ActivityCalendar.tsx
web/src/components/ActivityCalendar.tsx
+10
-5
ChangeMemoCreatedTsDialog.tsx
web/src/components/ChangeMemoCreatedTsDialog.tsx
+0
-105
TagsSection.tsx
web/src/components/HomeSidebar/TagsSection.tsx
+6
-2
MemoView.tsx
web/src/components/MemoView.tsx
+3
-8
Archived.tsx
web/src/pages/Archived.tsx
+9
-6
Explore.tsx
web/src/pages/Explore.tsx
+9
-6
Home.tsx
web/src/pages/Home.tsx
+9
-6
Timeline.tsx
web/src/pages/Timeline.tsx
+63
-76
UserProfile.tsx
web/src/pages/UserProfile.tsx
+9
-6
tag.ts
web/src/store/v1/tag.ts
+0
-9
No files found.
web/src/components/ActivityCalendar.tsx
View file @
1d99dad4
...
...
@@ -6,6 +6,7 @@ import { useTranslate } from "@/utils/i18n";
interface
Props
{
// Format: 2021-1
month
:
string
;
selectedDate
:
string
;
data
:
Record
<
string
,
number
>
;
onClick
?:
(
date
:
string
)
=>
void
;
}
...
...
@@ -28,8 +29,8 @@ const getCellAdditionalStyles = (count: number, maxCount: number) => {
const
ActivityCalendar
=
(
props
:
Props
)
=>
{
const
t
=
useTranslate
();
const
{
month
:
monthStr
,
data
,
onClick
}
=
props
;
const
year
=
new
Date
(
monthStr
).
get
UTC
FullYear
();
const
month
=
new
Date
(
monthStr
).
get
UTC
Month
()
+
1
;
const
year
=
new
Date
(
monthStr
).
getFullYear
();
const
month
=
new
Date
(
monthStr
).
getMonth
()
+
1
;
const
dayInMonth
=
new
Date
(
year
,
month
,
0
).
getDate
();
const
firstDay
=
new
Date
(
year
,
month
-
1
,
1
).
getDay
();
const
lastDay
=
new
Date
(
year
,
month
-
1
,
dayInMonth
).
getDay
();
...
...
@@ -55,15 +56,19 @@ const ActivityCalendar = (props: Props) => {
const
count
=
data
[
date
]
||
0
;
const
isToday
=
new
Date
().
toDateString
()
===
new
Date
(
date
).
toDateString
();
const
tooltipText
=
count
?
t
(
"memo.count-memos-in-date"
,
{
count
:
count
,
date
:
date
})
:
date
;
const
isSelected
=
new
Date
(
props
.
selectedDate
).
toDateString
()
===
new
Date
(
date
).
toDateString
();
return
day
?
(
<
Tooltip
className=
"shrink-0"
key=
{
`${date}-${index}`
}
title=
{
tooltipText
}
placement=
"top"
arrow
>
<
div
className=
{
clsx
(
"w-4 h-4 text-[9px] rounded-md flex justify-center items-center border
border-transparent
"
,
"w-4 h-4 text-[9px] rounded-md flex justify-center items-center border"
,
getCellAdditionalStyles
(
count
,
maxCount
),
isToday
&&
"border-gray-600 dark:!border-gray-500"
,
isToday
&&
"border-gray-600 dark:border-zinc-300"
,
isSelected
&&
"font-bold border-gray-600 dark:border-zinc-300"
,
!
isToday
&&
!
isSelected
&&
"border-transparent"
,
count
>
0
&&
"cursor-pointer"
,
)
}
onClick=
{
()
=>
count
&&
onClick
&&
onClick
(
date
)
}
onClick=
{
()
=>
count
&&
onClick
&&
onClick
(
new
Date
(
date
).
toDateString
()
)
}
>
{
day
}
</
div
>
...
...
web/src/components/ChangeMemoCreatedTsDialog.tsx
deleted
100644 → 0
View file @
33133ea1
import
{
Button
,
IconButton
,
Input
}
from
"@mui/joy"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
getNormalizedTimeString
}
from
"@/helpers/datetime"
;
import
{
MemoNamePrefix
,
useMemoStore
}
from
"@/store/v1"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
generateDialog
}
from
"./Dialog"
;
import
Icon
from
"./Icon"
;
interface
Props
extends
DialogProps
{
memoId
:
number
;
}
const
ChangeMemoCreatedTsDialog
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
t
=
useTranslate
();
const
{
destroy
,
memoId
}
=
props
;
const
memoStore
=
useMemoStore
();
const
[
createdAt
,
setCreatedAt
]
=
useState
(
""
);
const
maxDatetimeValue
=
getNormalizedTimeString
();
useEffect
(()
=>
{
memoStore
.
getOrFetchMemoByName
(
`
${
MemoNamePrefix
}${
memoId
}
`
).
then
((
memo
)
=>
{
if
(
memo
)
{
const
datetime
=
getNormalizedTimeString
(
memo
.
createTime
);
setCreatedAt
(
datetime
);
}
else
{
toast
.
error
(
t
(
"message.memo-not-found"
));
destroy
();
}
});
},
[]);
const
handleCloseBtnClick
=
()
=>
{
destroy
();
};
const
handleDatetimeInputChange
=
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
datetime
=
e
.
target
.
value
as
string
;
setCreatedAt
(
datetime
);
};
const
handleSaveBtnClick
=
async
()
=>
{
try
{
await
memoStore
.
updateMemo
(
{
name
:
`
${
MemoNamePrefix
}${
memoId
}
`
,
createTime
:
new
Date
(
createdAt
),
},
[
"created_ts"
],
);
toast
.
success
(
"Updated memo created time successfully."
);
handleCloseBtnClick
();
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toast
.
error
(
error
.
response
.
data
.
message
);
}
};
return
(
<>
<
div
className=
"dialog-header-container"
>
<
p
className=
"title-text"
>
{
t
(
"message.change-memo-created-time"
)
}
</
p
>
<
IconButton
size=
"sm"
onClick=
{
handleCloseBtnClick
}
>
<
Icon
.
X
className=
"w-5 h-auto"
/>
</
IconButton
>
</
div
>
<
div
className=
"flex flex-col justify-start items-start !w-72 max-w-full"
>
<
Input
className=
"w-full"
type=
"datetime-local"
value=
{
createdAt
}
slotProps=
{
{
input
:
{
max
:
maxDatetimeValue
,
},
}
}
onChange=
{
handleDatetimeInputChange
}
/>
<
div
className=
"flex flex-row justify-end items-center mt-4 w-full gap-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
{
t
(
"common.cancel"
)
}
</
Button
>
<
Button
color=
"primary"
onClick=
{
handleSaveBtnClick
}
>
{
t
(
"common.save"
)
}
</
Button
>
</
div
>
</
div
>
</>
);
};
function
showChangeMemoCreatedTsDialog
(
memoId
:
number
)
{
generateDialog
(
{
className
:
"change-memo-created-ts-dialog"
,
dialogName
:
"change-memo-created-ts-dialog"
,
},
ChangeMemoCreatedTsDialog
,
{
memoId
,
},
);
}
export
default
showChangeMemoCreatedTsDialog
;
web/src/components/HomeSidebar/TagsSection.tsx
View file @
1d99dad4
...
...
@@ -94,8 +94,12 @@ const TagContainer: React.FC<TagContainerProps> = (props: TagContainerProps) =>
style
:
"danger"
,
dialogName
:
"delete-tag-dialog"
,
onConfirm
:
async
()
=>
{
await
tagStore
.
deleteTag
(
tag
);
tagStore
.
fetchTags
({
skipCache
:
true
});
await
memoServiceClient
.
deleteMemoTag
({
parent
:
"memos/-"
,
tag
:
tag
,
});
await
tagStore
.
fetchTags
({
skipCache
:
true
});
toast
.
success
(
t
(
"message.deleted-successfully"
));
},
});
};
...
...
web/src/components/MemoView.tsx
View file @
1d99dad4
...
...
@@ -4,12 +4,11 @@ import { memo, useCallback, useEffect, useRef, useState } from "react";
import
{
Link
,
useLocation
}
from
"react-router-dom"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
extractMemoIdFromName
,
useUserStore
}
from
"@/store/v1"
;
import
{
useUserStore
}
from
"@/store/v1"
;
import
{
MemoRelation_Type
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
Memo
,
Visibility
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
convertVisibilityToString
}
from
"@/utils/memo"
;
import
showChangeMemoCreatedTsDialog
from
"./ChangeMemoCreatedTsDialog"
;
import
Icon
from
"./Icon"
;
import
MemoActionMenu
from
"./MemoActionMenu"
;
import
MemoContent
from
"./MemoContent"
;
...
...
@@ -56,12 +55,8 @@ const MemoView: React.FC<Props> = (props: Props) => {
})();
},
[]);
const
handleGotoMemoDetailPage
=
(
event
:
React
.
MouseEvent
<
HTMLDivElement
>
)
=>
{
if
(
event
.
altKey
)
{
showChangeMemoCreatedTsDialog
(
extractMemoIdFromName
(
memo
.
name
));
}
else
{
navigateTo
(
`/m/
${
memo
.
uid
}
`
);
}
const
handleGotoMemoDetailPage
=
()
=>
{
navigateTo
(
`/m/
${
memo
.
uid
}
`
);
};
const
handleMemoContentClick
=
useCallback
(
async
(
e
:
React
.
MouseEvent
)
=>
{
...
...
web/src/pages/Archived.tsx
View file @
1d99dad4
...
...
@@ -31,9 +31,14 @@ const Archived = () => {
.
sort
((
a
,
b
)
=>
getTimeStampByDate
(
b
.
displayTime
)
-
getTimeStampByDate
(
a
.
displayTime
));
useEffect
(()
=>
{
setIsRequesting
(
true
);
nextPageTokenRef
.
current
=
undefined
;
memoList
.
reset
();
fetchMemos
();
setTimeout
(
async
()
=>
{
memoList
.
reset
();
const
nextPageToken
=
await
fetchMemos
();
nextPageTokenRef
.
current
=
nextPageToken
;
setIsRequesting
(
false
);
});
},
[
tagQuery
,
textQuery
]);
const
fetchMemos
=
async
()
=>
{
...
...
@@ -48,14 +53,12 @@ const Archived = () => {
if
(
tagQuery
)
{
filters
.
push
(
`tag == "
${
tagQuery
}
"`
);
}
setIsRequesting
(
true
);
const
data
=
await
memoStore
.
fetchMemos
({
const
{
nextPageToken
}
=
await
memoStore
.
fetchMemos
({
pageSize
:
DEFAULT_LIST_MEMOS_PAGE_SIZE
,
filter
:
filters
.
join
(
" && "
),
pageToken
:
nextPageTokenRef
.
current
,
});
setIsRequesting
(
false
);
nextPageTokenRef
.
current
=
data
.
nextPageToken
;
return
nextPageToken
;
};
const
handleDeleteMemoClick
=
async
(
memo
:
Memo
)
=>
{
...
...
web/src/pages/Explore.tsx
View file @
1d99dad4
...
...
@@ -27,9 +27,14 @@ const Explore = () => {
const
sortedMemos
=
memoList
.
value
.
sort
((
a
,
b
)
=>
getTimeStampByDate
(
b
.
displayTime
)
-
getTimeStampByDate
(
a
.
displayTime
));
useEffect
(()
=>
{
setIsRequesting
(
true
);
nextPageTokenRef
.
current
=
undefined
;
memoList
.
reset
();
fetchMemos
();
setTimeout
(
async
()
=>
{
memoList
.
reset
();
const
nextPageToken
=
await
fetchMemos
();
nextPageTokenRef
.
current
=
nextPageToken
;
setIsRequesting
(
false
);
});
},
[
tagQuery
,
textQuery
]);
const
fetchMemos
=
async
()
=>
{
...
...
@@ -44,14 +49,12 @@ const Explore = () => {
if
(
tagQuery
)
{
filters
.
push
(
`tag == "
${
tagQuery
}
"`
);
}
setIsRequesting
(
true
);
const
data
=
await
memoStore
.
fetchMemos
({
const
{
nextPageToken
}
=
await
memoStore
.
fetchMemos
({
pageSize
:
DEFAULT_LIST_MEMOS_PAGE_SIZE
,
filter
:
filters
.
join
(
" && "
),
pageToken
:
nextPageTokenRef
.
current
,
});
setIsRequesting
(
false
);
nextPageTokenRef
.
current
=
data
.
nextPageToken
;
return
nextPageToken
;
};
return
(
...
...
web/src/pages/Home.tsx
View file @
1d99dad4
...
...
@@ -33,9 +33,14 @@ const Home = () => {
.
sort
((
a
,
b
)
=>
Number
(
b
.
pinned
)
-
Number
(
a
.
pinned
));
useEffect
(()
=>
{
setIsRequesting
(
true
);
nextPageTokenRef
.
current
=
undefined
;
memoList
.
reset
();
fetchMemos
();
setTimeout
(
async
()
=>
{
memoList
.
reset
();
const
nextPageToken
=
await
fetchMemos
();
nextPageTokenRef
.
current
=
nextPageToken
;
setIsRequesting
(
false
);
});
},
[
tagQuery
,
textQuery
]);
const
fetchMemos
=
async
()
=>
{
...
...
@@ -50,14 +55,12 @@ const Home = () => {
if
(
tagQuery
)
{
filters
.
push
(
`tag == "
${
tagQuery
}
"`
);
}
setIsRequesting
(
true
);
const
data
=
await
memoStore
.
fetchMemos
({
const
{
nextPageToken
}
=
await
memoStore
.
fetchMemos
({
pageSize
:
DEFAULT_LIST_MEMOS_PAGE_SIZE
,
filter
:
filters
.
join
(
" && "
),
pageToken
:
nextPageTokenRef
.
current
,
});
setIsRequesting
(
false
);
nextPageTokenRef
.
current
=
data
.
nextPageToken
;
return
nextPageToken
;
};
const
handleEditPrevious
=
useCallback
(()
=>
{
...
...
web/src/pages/Timeline.tsx
View file @
1d99dad4
This diff is collapsed.
Click to expand it.
web/src/pages/UserProfile.tsx
View file @
1d99dad4
...
...
@@ -59,9 +59,14 @@ const UserProfile = () => {
return
;
}
setIsRequesting
(
true
);
nextPageTokenRef
.
current
=
undefined
;
memoList
.
reset
();
fetchMemos
();
setTimeout
(
async
()
=>
{
memoList
.
reset
();
const
nextPageToken
=
await
fetchMemos
();
nextPageTokenRef
.
current
=
nextPageToken
;
setIsRequesting
(
false
);
});
},
[
user
,
tagQuery
,
textQuery
]);
const
fetchMemos
=
async
()
=>
{
...
...
@@ -80,14 +85,12 @@ const UserProfile = () => {
if
(
tagQuery
)
{
filters
.
push
(
`tag == "
${
tagQuery
}
"`
);
}
setIsRequesting
(
true
);
const
data
=
await
memoStore
.
fetchMemos
({
const
{
nextPageToken
}
=
await
memoStore
.
fetchMemos
({
pageSize
:
DEFAULT_LIST_MEMOS_PAGE_SIZE
,
filter
:
filters
.
join
(
" && "
),
pageToken
:
nextPageTokenRef
.
current
,
});
setIsRequesting
(
false
);
nextPageTokenRef
.
current
=
data
.
nextPageToken
;
return
nextPageToken
;
};
const
handleCopyProfileLink
=
()
=>
{
...
...
web/src/store/v1/tag.ts
View file @
1d99dad4
...
...
@@ -28,14 +28,5 @@ export const useTagStore = create(
const
{
tagAmounts
}
=
await
memoServiceClient
.
listMemoTags
({
parent
:
"memos/-"
});
set
({
tagAmounts
});
},
deleteTag
:
async
(
tagName
:
string
)
=>
{
await
memoServiceClient
.
deleteMemoTag
({
parent
:
"memos/-"
,
tag
:
tagName
,
});
const
{
tagAmounts
}
=
get
();
delete
tagAmounts
[
tagName
];
set
({
tagAmounts
});
},
})),
);
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