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
d71bfce1
Unverified
Commit
d71bfce1
authored
Apr 02, 2023
by
boojack
Committed by
GitHub
Apr 02, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: add usage into heatmap (#1443)
parent
1ea65c0b
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
86 additions
and
102 deletions
+86
-102
MemoEditor.tsx
web/src/components/MemoEditor.tsx
+0
-1
PreviewImageDialog.tsx
web/src/components/PreviewImageDialog.tsx
+7
-29
ShareMemoDialog.tsx
web/src/components/ShareMemoDialog.tsx
+9
-10
ShortcutList.tsx
web/src/components/ShortcutList.tsx
+1
-1
TagList.tsx
web/src/components/TagList.tsx
+1
-1
UsageHeatMap.tsx
web/src/components/UsageHeatMap.tsx
+60
-44
share-memo-dialog.less
web/src/less/share-memo-dialog.less
+2
-2
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+1
-1
ResourcesDashboard.tsx
web/src/pages/ResourcesDashboard.tsx
+5
-13
No files found.
web/src/components/MemoEditor.tsx
View file @
d71bfce1
...
@@ -474,7 +474,6 @@ const MemoEditor = () => {
...
@@ -474,7 +474,6 @@ const MemoEditor = () => {
disabled=
{
!
(
allowSave
||
editorState
.
resourceList
.
length
>
0
)
||
state
.
isUploadingResource
||
state
.
isRequesting
}
disabled=
{
!
(
allowSave
||
editorState
.
resourceList
.
length
>
0
)
||
state
.
isUploadingResource
||
state
.
isRequesting
}
onClick=
{
handleSaveBtnClick
}
onClick=
{
handleSaveBtnClick
}
>
>
<
img
className=
"w-5 -ml-0.5 mr-0.5 h-auto"
src=
"/logo.webp"
/>
{
t
(
"editor.save"
)
}
{
t
(
"editor.save"
)
}
</
button
>
</
button
>
</
div
>
</
div
>
...
...
web/src/components/PreviewImageDialog.tsx
View file @
d71bfce1
...
@@ -14,14 +14,12 @@ interface Props extends DialogProps {
...
@@ -14,14 +14,12 @@ interface Props extends DialogProps {
}
}
interface
State
{
interface
State
{
angle
:
number
;
scale
:
number
;
scale
:
number
;
originX
:
number
;
originX
:
number
;
originY
:
number
;
originY
:
number
;
}
}
const
defaultState
:
State
=
{
const
defaultState
:
State
=
{
angle
:
0
,
scale
:
1
,
scale
:
1
,
originX
:
-
1
,
originX
:
-
1
,
originY
:
-
1
,
originY
:
-
1
,
...
@@ -104,36 +102,22 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
...
@@ -104,36 +102,22 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
}
}
};
};
const
handleImgRotate
=
(
event
:
React
.
MouseEvent
,
angle
:
number
)
=>
{
const
curImgAngle
=
(
state
.
angle
+
angle
+
360
)
%
360
;
setState
({
...
state
,
originX
:
-
1
,
originY
:
-
1
,
angle
:
curImgAngle
,
});
};
const
handleImgContainerScroll
=
(
event
:
React
.
WheelEvent
)
=>
{
const
handleImgContainerScroll
=
(
event
:
React
.
WheelEvent
)
=>
{
const
offsetX
=
event
.
nativeEvent
.
offsetX
;
const
offsetX
=
event
.
nativeEvent
.
offsetX
;
const
offsetY
=
event
.
nativeEvent
.
offsetY
;
const
offsetY
=
event
.
nativeEvent
.
offsetY
;
const
sign
=
event
.
deltaY
<
0
?
1
:
-
1
;
const
sign
=
event
.
deltaY
<
0
?
1
:
-
1
;
const
curAng
le
=
Math
.
max
(
MIN_SCALE
,
Math
.
min
(
MAX_SCALE
,
state
.
scale
+
sign
*
SCALE_UNIT
));
const
sca
le
=
Math
.
max
(
MIN_SCALE
,
Math
.
min
(
MAX_SCALE
,
state
.
scale
+
sign
*
SCALE_UNIT
));
setState
({
setState
({
...
state
,
...
state
,
originX
:
offsetX
,
originX
:
offsetX
,
originY
:
offsetY
,
originY
:
offsetY
,
scale
:
curAng
le
,
scale
:
sca
le
,
});
});
};
};
const
getImageComputedStyle
=
()
=>
{
const
imageComputedStyle
=
{
return
{
transform
:
`scale(
${
state
.
scale
}
)`
,
transform
:
`scale(
${
state
.
scale
}
) rotate(
${
state
.
angle
}
deg)`
,
transformOrigin
:
`
${
state
.
originX
===
-
1
?
"center"
:
`
${
state
.
originX
}
px`
}
${
state
.
originY
===
-
1
?
"center"
:
`
${
state
.
originY
}
px`
}
`
,
transformOrigin
:
`
${
state
.
originX
===
-
1
?
"center"
:
`
${
state
.
originX
}
px`
}
${
state
.
originY
===
-
1
?
"center"
:
`
${
state
.
originY
}
px`
}
`
,
};
};
};
return
(
return
(
...
@@ -145,22 +129,16 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
...
@@ -145,22 +129,16 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
<
button
className=
"btn"
onClick=
{
handleDownloadBtnClick
}
>
<
button
className=
"btn"
onClick=
{
handleDownloadBtnClick
}
>
<
Icon
.
Download
className=
"icon-img"
/>
<
Icon
.
Download
className=
"icon-img"
/>
</
button
>
</
button
>
<
button
className=
"btn"
onClick=
{
(
e
)
=>
handleImgRotate
(
e
,
-
90
)
}
>
<
Icon
.
RotateCcw
className=
"icon-img"
/>
</
button
>
<
button
className=
"btn"
onClick=
{
(
e
)
=>
handleImgRotate
(
e
,
90
)
}
>
<
Icon
.
RotateCw
className=
"icon-img"
/>
</
button
>
</
div
>
</
div
>
<
div
className=
"img-container"
onClick=
{
handleImgContainerClick
}
>
<
div
className=
"img-container"
onClick=
{
handleImgContainerClick
}
>
<
img
<
img
style=
{
imageComputedStyle
}
src=
{
imgUrls
[
currentIndex
]
}
onClick=
{
(
e
)
=>
e
.
stopPropagation
()
}
onClick=
{
(
e
)
=>
e
.
stopPropagation
()
}
onTouchStart=
{
handleTouchStart
}
onTouchStart=
{
handleTouchStart
}
onTouchMove=
{
handleTouchMove
}
onTouchMove=
{
handleTouchMove
}
onTouchEnd=
{
handleTouchEnd
}
onTouchEnd=
{
handleTouchEnd
}
src=
{
imgUrls
[
currentIndex
]
}
onWheel=
{
handleImgContainerScroll
}
onWheel=
{
handleImgContainerScroll
}
style=
{
getImageComputedStyle
()
}
/>
/>
</
div
>
</
div
>
</>
</>
...
...
web/src/components/ShareMemoDialog.tsx
View file @
d71bfce1
...
@@ -131,7 +131,7 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
...
@@ -131,7 +131,7 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
</
div
>
</
div
>
<
div
className=
"watermark-container"
>
<
div
className=
"watermark-container"
>
<
div
className=
"logo-container"
>
<
div
className=
"logo-container"
>
<
img
className=
"
logo-im
g"
src=
{
`${systemStatus.customizedProfile.logoUrl || "/logo.webp"}`
}
alt=
""
/>
<
img
className=
"
h-10 w-auto rounded-l
g"
src=
{
`${systemStatus.customizedProfile.logoUrl || "/logo.webp"}`
}
alt=
""
/>
</
div
>
</
div
>
<
div
className=
"userinfo-container"
>
<
div
className=
"userinfo-container"
>
<
span
className=
"name-text"
>
{
user
.
nickname
||
user
.
username
}
</
span
>
<
span
className=
"name-text"
>
{
user
.
nickname
||
user
.
username
}
</
span
>
...
@@ -141,10 +141,9 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
...
@@ -141,10 +141,9 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
</
div
>
</
div
>
<
QRCodeSVG
<
QRCodeSVG
value=
{
`${window.location.origin}/m/${memo.id}`
}
value=
{
`${window.location.origin}/m/${memo.id}`
}
size=
{
64
}
size=
{
40
}
bgColor=
{
"#F3F4F6"
}
bgColor=
{
"#F3F4F6"
}
fgColor=
{
"#4B5563"
}
fgColor=
{
"#4B5563"
}
level=
{
"L"
}
includeMargin=
{
false
}
includeMargin=
{
false
}
/>
/>
</
div
>
</
div
>
...
@@ -166,17 +165,17 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
...
@@ -166,17 +165,17 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
))
}
))
}
</
Select
>
</
Select
>
<
div
className=
"flex flex-row justify-end items-center"
>
<
div
className=
"flex flex-row justify-end items-center"
>
<
button
disabled=
{
createLoadingState
.
isLoading
}
className=
"btn-normal mr-2"
onClick=
{
handleDownloadBtnClick
}
>
<
button
disabled=
{
createLoadingState
.
isLoading
}
className=
"btn-normal
h-8
mr-2"
onClick=
{
handleDownloadBtnClick
}
>
{
createLoadingState
.
isLoading
?
(
{
createLoadingState
.
isLoading
?
(
<
Icon
.
Loader
className=
"w-4 h-auto mr-1 animate-spin"
/>
<
Icon
.
Loader
className=
"w-4 h-auto
sm:
mr-1 animate-spin"
/>
)
:
(
)
:
(
<
Icon
.
Download
className=
"w-4 h-auto mr-1"
/>
<
Icon
.
Download
className=
"w-4 h-auto
sm:
mr-1"
/>
)
}
)
}
<
span
>
{
t
(
"common.image"
)
}
</
span
>
<
span
className=
"hidden sm:block"
>
{
t
(
"common.image"
)
}
</
span
>
</
button
>
</
button
>
<
button
className=
"btn-normal"
onClick=
{
handleCopyLinkBtnClick
}
>
<
button
className=
"btn-normal
h-8
"
onClick=
{
handleCopyLinkBtnClick
}
>
<
Icon
.
Link
className=
"w-4 h-auto mr-1"
/>
<
Icon
.
Link
className=
"w-4 h-auto
sm:
mr-1"
/>
<
span
>
{
t
(
"common.link"
)
}
</
span
>
<
span
className=
"hidden sm:block"
>
{
t
(
"common.link"
)
}
</
span
>
</
button
>
</
button
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/ShortcutList.tsx
View file @
d71bfce1
...
@@ -36,7 +36,7 @@ const ShortcutList = () => {
...
@@ -36,7 +36,7 @@ const ShortcutList = () => {
},
[]);
},
[]);
return
(
return
(
<
div
className=
"flex flex-col justify-start items-start w-full
py-0 px-1
mt-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-col justify-start items-start w-full mt-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-row justify-start items-center w-full px-4"
>
<
div
className=
"flex flex-row justify-start items-center w-full px-4"
>
<
span
className=
"text-sm leading-6 font-mono text-gray-400"
>
{
t
(
"common.shortcuts"
)
}
</
span
>
<
span
className=
"text-sm leading-6 font-mono text-gray-400"
>
{
t
(
"common.shortcuts"
)
}
</
span
>
<
button
<
button
...
...
web/src/components/TagList.tsx
View file @
d71bfce1
...
@@ -68,7 +68,7 @@ const TagList = () => {
...
@@ -68,7 +68,7 @@ const TagList = () => {
},
[
tagsText
]);
},
[
tagsText
]);
return
(
return
(
<
div
className=
"flex flex-col justify-start items-start w-full
py-0 px-1
mt-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-col justify-start items-start w-full mt-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-row justify-start items-center w-full px-4"
>
<
div
className=
"flex flex-row justify-start items-center w-full px-4"
>
<
span
className=
"text-sm leading-6 font-mono text-gray-400"
>
{
t
(
"common.tags"
)
}
</
span
>
<
span
className=
"text-sm leading-6 font-mono text-gray-400"
>
{
t
(
"common.tags"
)
}
</
span
>
<
button
<
button
...
...
web/src/components/UsageHeatMap.tsx
View file @
d71bfce1
...
@@ -38,13 +38,23 @@ const UsageHeatMap = () => {
...
@@ -38,13 +38,23 @@ const UsageHeatMap = () => {
const
usedDaysAmount
=
(
tableConfig
.
width
-
1
)
*
tableConfig
.
height
+
todayDay
;
const
usedDaysAmount
=
(
tableConfig
.
width
-
1
)
*
tableConfig
.
height
+
todayDay
;
const
beginDayTimestamp
=
todayTimeStamp
-
usedDaysAmount
*
DAILY_TIMESTAMP
;
const
beginDayTimestamp
=
todayTimeStamp
-
usedDaysAmount
*
DAILY_TIMESTAMP
;
const
memos
=
memoStore
.
state
.
memos
;
const
memos
=
memoStore
.
state
.
memos
;
const
[
memoAmount
,
setMemoAmount
]
=
useState
(
0
);
const
[
createdDays
,
setCreatedDays
]
=
useState
(
0
);
const
[
allStat
,
setAllStat
]
=
useState
<
DailyUsageStat
[]
>
(
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestamp
));
const
[
allStat
,
setAllStat
]
=
useState
<
DailyUsageStat
[]
>
(
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestamp
));
const
[
currentStat
,
setCurrentStat
]
=
useState
<
DailyUsageStat
|
null
>
(
null
);
const
[
currentStat
,
setCurrentStat
]
=
useState
<
DailyUsageStat
|
null
>
(
null
);
const
containerElRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
containerElRef
=
useRef
<
HTMLDivElement
>
(
null
);
useEffect
(()
=>
{
if
(
!
userStore
.
state
.
user
)
{
return
;
}
setCreatedDays
(
Math
.
ceil
((
Date
.
now
()
-
utils
.
getTimeStampByDate
(
userStore
.
state
.
user
.
createdTs
))
/
1000
/
3600
/
24
));
},
[
userStore
.
state
.
user
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
getMemoStats
(
userStore
.
getCurrentUserId
())
getMemoStats
(
userStore
.
getCurrentUserId
())
.
then
(({
data
:
{
data
}
})
=>
{
.
then
(({
data
:
{
data
}
})
=>
{
setMemoAmount
(
data
.
length
);
const
newStat
:
DailyUsageStat
[]
=
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestamp
);
const
newStat
:
DailyUsageStat
[]
=
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestamp
);
for
(
const
record
of
data
)
{
for
(
const
record
of
data
)
{
const
index
=
(
utils
.
getDateStampByDate
(
record
*
1000
)
-
beginDayTimestamp
)
/
(
1000
*
3600
*
24
)
-
1
;
const
index
=
(
utils
.
getDateStampByDate
(
record
*
1000
)
-
beginDayTimestamp
)
/
(
1000
*
3600
*
24
)
-
1
;
...
@@ -97,6 +107,7 @@ const UsageHeatMap = () => {
...
@@ -97,6 +107,7 @@ const UsageHeatMap = () => {
},
[]);
},
[]);
return
(
return
(
<>
<
div
className=
"usage-heat-map-wrapper"
ref=
{
containerElRef
}
>
<
div
className=
"usage-heat-map-wrapper"
ref=
{
containerElRef
}
>
<
div
className=
"usage-heat-map"
>
<
div
className=
"usage-heat-map"
>
{
allStat
.
map
((
v
,
i
)
=>
{
{
allStat
.
map
((
v
,
i
)
=>
{
...
@@ -144,6 +155,11 @@ const UsageHeatMap = () => {
...
@@ -144,6 +155,11 @@ const UsageHeatMap = () => {
<
span
className=
"tip-text"
>
{
t
(
"days.sat"
)
}
</
span
>
<
span
className=
"tip-text"
>
{
t
(
"days.sat"
)
}
</
span
>
</
div
>
</
div
>
</
div
>
</
div
>
<
p
className=
"w-full pl-4 text-xs -mt-2 mb-3 text-gray-400 dark:text-zinc-400"
>
<
span
className=
"font-medium text-gray-500 dark:text-zinc-300"
>
{
memoAmount
}
</
span
>
memos in
{
" "
}
<
span
className=
"font-medium text-gray-500 dark:text-zinc-300"
>
{
createdDays
}
</
span
>
days
</
p
>
</>
);
);
};
};
...
...
web/src/less/share-memo-dialog.less
View file @
d71bfce1
...
@@ -56,7 +56,7 @@
...
@@ -56,7 +56,7 @@
}
}
> .watermark-container {
> .watermark-container {
@apply flex flex-row justify-between items-center w-full bg-gray-100 dark:bg-zinc-700 py-
2
px-6;
@apply flex flex-row justify-between items-center w-full bg-gray-100 dark:bg-zinc-700 py-
3
px-6;
> .userinfo-container {
> .userinfo-container {
@apply w-auto grow truncate flex mr-2 flex-col justify-center items-start;
@apply w-auto grow truncate flex mr-2 flex-col justify-center items-start;
...
@@ -70,7 +70,7 @@
...
@@ -70,7 +70,7 @@
}
}
}
}
> .logo-container{
> .logo-container
{
@apply mr-2;
@apply mr-2;
> .logo-img {
> .logo-img {
...
...
web/src/pages/MemoDetail.tsx
View file @
d71bfce1
...
@@ -53,7 +53,7 @@ const MemoDetail = () => {
...
@@ -53,7 +53,7 @@ const MemoDetail = () => {
<
div
className=
"page-container"
>
<
div
className=
"page-container"
>
<
div
className=
"page-header"
>
<
div
className=
"page-header"
>
<
div
className=
"title-container"
>
<
div
className=
"title-container"
>
<
img
className=
"
logo-img
"
src=
{
customizedProfile
.
logoUrl
}
alt=
""
/>
<
img
className=
"
h-10 w-auto rounded-lg mr-2
"
src=
{
customizedProfile
.
logoUrl
}
alt=
""
/>
<
p
className=
"logo-text"
>
{
customizedProfile
.
name
}
</
p
>
<
p
className=
"logo-text"
>
{
customizedProfile
.
name
}
</
p
>
</
div
>
</
div
>
<
div
className=
"action-button-container"
>
<
div
className=
"action-button-container"
>
...
...
web/src/pages/ResourcesDashboard.tsx
View file @
d71bfce1
...
@@ -346,20 +346,12 @@ const ResourcesDashboard = () => {
...
@@ -346,20 +346,12 @@ const ResourcesDashboard = () => {
</
div
>
</
div
>
)
}
)
}
</
div
>
</
div
>
<
div
className=
"flex flex-col justify-start items-center w-full
my-6
"
>
<
div
className=
"flex flex-col justify-start items-center w-full"
>
<
p
className=
"text-sm text-gray-400 italic"
>
<
p
className=
"text-sm text-gray-400 italic"
>
{
isComplete
?
(
{
!
isComplete
&&
(
resources
.
length
===
0
?
(
<
span
className=
"cursor-pointer my-6 hover:text-green-600"
onClick=
{
handleFetchMoreResourceBtnClick
}
>
t
(
"message.no-resource"
)
)
:
(
t
(
"message.resource-ready"
)
)
)
:
(
<>
<
span
className=
"cursor-pointer hover:text-green-600"
onClick=
{
handleFetchMoreResourceBtnClick
}
>
{
t
(
"memo-list.fetch-more"
)
}
{
t
(
"memo-list.fetch-more"
)
}
</
span
>
</
span
>
</>
)
}
)
}
</
p
>
</
p
>
</
div
>
</
div
>
...
...
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