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
a7374cf9
Unverified
Commit
a7374cf9
authored
Dec 03, 2022
by
boojack
Committed by
GitHub
Dec 03, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: generate sharing memo image (#663)
parent
e3d76193
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
60 additions
and
87 deletions
+60
-87
Memo.tsx
web/src/components/Memo.tsx
+2
-2
ShareMemoDialog.tsx
web/src/components/ShareMemoDialog.tsx
+56
-51
tailwind.css
web/src/css/tailwind.css
+1
-1
share-memo-dialog.less
web/src/less/share-memo-dialog.less
+1
-33
No files found.
web/src/components/Memo.tsx
View file @
a7374cf9
...
...
@@ -8,7 +8,7 @@ import Icon from "./Icon";
import
toastHelper
from
"./Toast"
;
import
MemoContent
from
"./MemoContent"
;
import
MemoResources
from
"./MemoResources"
;
import
showShareMemo
ImageDialog
from
"./ShareMemoImage
Dialog"
;
import
showShareMemo
from
"./ShareMemo
Dialog"
;
import
showPreviewImageDialog
from
"./PreviewImageDialog"
;
import
showChangeMemoCreatedTsDialog
from
"./ChangeMemoCreatedTsDialog"
;
import
"../less/memo.less"
;
...
...
@@ -89,7 +89,7 @@ const Memo: React.FC<Props> = (props: Props) => {
};
const
handleGenMemoImageBtnClick
=
()
=>
{
showShareMemo
ImageDialog
(
memo
);
showShareMemo
(
memo
);
};
const
handleMemoContentClick
=
async
(
e
:
React
.
MouseEvent
)
=>
{
...
...
web/src/components/ShareMemo
Image
Dialog.tsx
→
web/src/components/ShareMemoDialog.tsx
View file @
a7374cf9
import
{
Select
,
Option
}
from
"@mui/joy"
;
import
React
,
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
copy
from
"copy-to-clipboard"
;
import
{
toLower
}
from
"lodash"
;
import
toImage
from
"../labs/html2image"
;
import
{
ANIMATION_DURATION
,
VISIBILITY_SELECTOR_ITEMS
}
from
"../helpers/consts"
;
import
{
VISIBILITY_SELECTOR_ITEMS
}
from
"../helpers/consts"
;
import
*
as
utils
from
"../helpers/utils"
;
import
{
getMemoStats
}
from
"../helpers/api"
;
import
{
memoService
,
userService
}
from
"../services"
;
...
...
@@ -13,8 +14,7 @@ import { generateDialog } from "./Dialog";
import
toastHelper
from
"./Toast"
;
import
MemoContent
from
"./MemoContent"
;
import
MemoResources
from
"./MemoResources"
;
import
Selector
from
"./common/Selector"
;
import
"../less/share-memo-image-dialog.less"
;
import
"../less/share-memo-dialog.less"
;
interface
Props
extends
DialogProps
{
memo
:
Memo
;
...
...
@@ -22,18 +22,18 @@ interface Props extends DialogProps {
interface
State
{
memoAmount
:
number
;
shortcutImgUrl
:
string
;
memoVisibility
:
string
;
generatedImgUrl
:
string
;
}
const
ShareMemo
Image
Dialog
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
ShareMemoDialog
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
{
memo
:
propsMemo
,
destroy
}
=
props
;
const
{
t
}
=
useTranslation
();
const
user
=
userService
.
getState
().
user
as
User
;
const
[
state
,
setState
]
=
useState
<
State
>
({
memoAmount
:
0
,
shortcutImgUrl
:
""
,
memoVisibility
:
propsMemo
.
visibility
,
generatedImgUrl
:
""
,
});
const
loadingState
=
useLoading
();
const
memoElRef
=
useRef
<
HTMLDivElement
>
(
null
);
...
...
@@ -64,26 +64,24 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
return
;
}
setTimeout
(()
=>
{
if
(
!
memoElRef
.
current
)
{
return
;
}
if
(
!
memoElRef
.
current
)
{
return
;
}
toImage
(
memoElRef
.
current
,
{
pixelRatio
:
window
.
devicePixelRatio
*
2
,
})
.
then
((
url
)
=>
{
setState
((
state
)
=>
{
return
{
...
state
,
shortcutImgUrl
:
url
,
};
});
})
.
catch
((
err
)
=>
{
console
.
error
(
err
);
toImage
(
memoElRef
.
current
,
{
pixelRatio
:
window
.
devicePixelRatio
*
2
,
})
.
then
((
url
)
=>
{
setState
((
state
)
=>
{
return
{
...
state
,
generatedImgUrl
:
url
,
};
});
},
ANIMATION_DURATION
);
})
.
catch
((
err
)
=>
{
console
.
error
(
err
);
});
},
[
loadingState
.
isLoading
]);
const
handleCloseBtnClick
=
()
=>
{
...
...
@@ -92,7 +90,7 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
const
handleDownloadBtnClick
=
()
=>
{
const
a
=
document
.
createElement
(
"a"
);
a
.
href
=
state
.
shortcut
ImgUrl
;
a
.
href
=
state
.
generated
ImgUrl
;
a
.
download
=
`memos-
${
utils
.
getDateTimeString
(
Date
.
now
())}
.png`
;
a
.
click
();
};
...
...
@@ -134,7 +132,7 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
</
div
>
<
div
className=
"dialog-content-container"
>
<
div
className=
"memo-container"
ref=
{
memoElRef
}
>
{
state
.
shortcutImgUrl
!==
""
&&
<
img
className=
"memo-shortcut-img"
src=
{
state
.
shortcut
ImgUrl
}
/>
}
{
state
.
generatedImgUrl
!==
""
&&
<
img
className=
"memo-shortcut-img"
src=
{
state
.
generated
ImgUrl
}
/>
}
<
span
className=
"time-text"
>
{
memo
.
createdAtStr
}
</
span
>
<
div
className=
"memo-content-wrapper"
>
<
MemoContent
content=
{
memo
.
content
}
displayConfig=
{
{
enableExpand
:
false
}
}
/>
...
...
@@ -150,28 +148,35 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
<
img
className=
"logo-img"
src=
"/logo.webp"
alt=
""
/>
</
div
>
</
div
>
<
div
className=
"share-actions-container"
>
<
div
className=
"visibility-selector"
>
<
Selector
className=
"visibility-selector"
value=
{
state
.
memoVisibility
}
dataSource=
{
memoVisibilityOptionSelectorItems
}
handleValueChanged=
{
handleMemoVisibilityOptionChanged
}
/>
</
div
>
<
div
className=
"share-btns-container"
>
<
div
className=
"buttons-wrapper"
>
<
div
className=
"share-btn share-image-btn"
onClick=
{
handleDownloadBtnClick
}
>
<
Icon
.
Download
className=
"icon-img"
/>
<
span
>
{
t
(
"common.image"
)
}
</
span
>
</
div
>
</
div
>
<
div
className=
"buttons-wrapper"
>
<
div
className=
"share-btn share-link-btn"
onClick=
{
handleCopyLinkBtnClick
}
>
<
Icon
.
Link
className=
"icon-img"
/>
<
span
>
{
t
(
"common.link"
)
}
</
span
>
</
div
>
</
div
>
<
div
className=
"px-4 py-3 w-full flex flex-row justify-between items-center"
>
<
Select
className=
"!min-w-[10rem] w-auto text-sm"
value=
{
state
.
memoVisibility
}
onChange=
{
(
_
,
visibility
)
=>
{
if
(
visibility
)
{
handleMemoVisibilityOptionChanged
(
visibility
);
}
}
}
>
{
memoVisibilityOptionSelectorItems
.
map
((
item
)
=>
(
<
Option
key=
{
item
.
value
}
value=
{
item
.
value
}
className=
"whitespace-nowrap"
>
{
item
.
text
}
</
Option
>
))
}
</
Select
>
<
div
className=
"flex flex-row justify-end items-center"
>
<
button
disabled=
{
state
.
generatedImgUrl
===
""
}
className=
"btn-normal mr-2"
onClick=
{
handleDownloadBtnClick
}
>
{
state
.
generatedImgUrl
===
""
?
(
<
Icon
.
Loader
className=
"w-4 h-auto mr-1 animate-spin"
/>
)
:
(
<
Icon
.
Download
className=
"w-4 h-auto mr-1"
/>
)
}
<
span
>
{
t
(
"common.image"
)
}
</
span
>
</
button
>
<
button
className=
"btn-normal"
onClick=
{
handleCopyLinkBtnClick
}
>
<
Icon
.
Link
className=
"w-4 h-auto mr-1"
/>
<
span
>
{
t
(
"common.link"
)
}
</
span
>
</
button
>
</
div
>
</
div
>
</
div
>
...
...
@@ -179,12 +184,12 @@ const ShareMemoImageDialog: React.FC<Props> = (props: Props) => {
);
};
export
default
function
showShareMemo
Image
Dialog
(
memo
:
Memo
):
void
{
export
default
function
showShareMemoDialog
(
memo
:
Memo
):
void
{
generateDialog
(
{
className
:
"share-memo-
image-
dialog"
,
className
:
"share-memo-dialog"
,
},
ShareMemo
Image
Dialog
,
ShareMemoDialog
,
{
memo
}
);
}
web/src/css/tailwind.css
View file @
a7374cf9
...
...
@@ -16,7 +16,7 @@
@layer
components
{
.btn-normal
{
@apply
select-none
inline-flex
border
dark
:
border-zinc-700
cursor-pointer
px-3
text-sm
leading-8
rounded-md
hover
:
opacity-80
hover
:
shadow
;
@apply
select-none
flex
flex-row
justify-center
items-center
border
dark
:
border-zinc-700
cursor-pointer
px-3
text-sm
leading-8
rounded-md
hover
:
opacity-80
hover
:
shadow
disabled
:
cursor-not-allowed
disabled
:
opacity-60
disabled
:
hover
:
shadow-none
;
}
.btn-primary
{
...
...
web/src/less/share-memo-
image-
dialog.less
→
web/src/less/share-memo-dialog.less
View file @
a7374cf9
.share-memo-
image-
dialog {
.share-memo-dialog {
> .dialog-container {
@apply w-96 p-0 bg-white dark:bg-zinc-800;
...
...
@@ -77,38 +77,6 @@
}
}
}
.share-actions-container {
@apply flex justify-between px-4 py-3 mb-0 w-full border-t dark:border-t-zinc-700;
> .visibility-selector {
@apply w-36;
> .selector-wrapper {
@apply h-10;
}
}
> .share-btns-container {
@apply flex justify-end;
> .buttons-wrapper {
@apply flex flex-row justify-start items-center;
> .share-btn {
@apply text-sm cursor-pointer px-3 py-2 rounded flex flex-row justify-center items-center border dark:border-zinc-700 hover:opacity-80;
> .icon-img {
@apply w-4 h-auto mr-1;
}
}
> .share-image-btn {
@apply mr-3;
}
}
}
}
}
}
}
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