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
a997e1d1
Unverified
Commit
a997e1d1
authored
Feb 12, 2023
by
boojack
Committed by
GitHub
Feb 12, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: simplify memo editor component (#1079)
parent
c28d35d8
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
45 additions
and
114 deletions
+45
-114
CreateTagDialog.tsx
web/src/components/CreateTagDialog.tsx
+1
-1
MemoEditor.tsx
web/src/components/MemoEditor.tsx
+38
-105
MemoResource.tsx
web/src/components/MemoResource.tsx
+2
-2
storage.ts
web/src/helpers/storage.ts
+0
-2
memo-editor.less
web/src/less/memo-editor.less
+4
-4
No files found.
web/src/components/CreateTagDialog.tsx
View file @
a997e1d1
...
@@ -31,7 +31,7 @@ const CreateTagDialog: React.FC<Props> = (props: Props) => {
...
@@ -31,7 +31,7 @@ const CreateTagDialog: React.FC<Props> = (props: Props) => {
getTagSuggestionList
().
then
(({
data
})
=>
{
getTagSuggestionList
().
then
(({
data
})
=>
{
setSuggestTagNameList
(
data
.
data
.
filter
((
tag
)
=>
validateTagName
(
tag
)));
setSuggestTagNameList
(
data
.
data
.
filter
((
tag
)
=>
validateTagName
(
tag
)));
});
});
},
[]);
},
[
tagNameList
]);
const
handleTagNameInputKeyDown
=
(
event
:
React
.
KeyboardEvent
)
=>
{
const
handleTagNameInputKeyDown
=
(
event
:
React
.
KeyboardEvent
)
=>
{
if
(
event
.
key
===
"Enter"
)
{
if
(
event
.
key
===
"Enter"
)
{
...
...
web/src/components/MemoEditor.tsx
View file @
a997e1d1
...
@@ -17,7 +17,6 @@ import "../less/memo-editor.less";
...
@@ -17,7 +17,6 @@ import "../less/memo-editor.less";
const
listItemSymbolList
=
[
"- [ ] "
,
"- [x] "
,
"- [X] "
,
"* "
,
"- "
];
const
listItemSymbolList
=
[
"- [ ] "
,
"- [x] "
,
"- [X] "
,
"* "
,
"- "
];
const
emptyOlReg
=
/^
(\d
+
)\.
$/
;
const
emptyOlReg
=
/^
(\d
+
)\.
$/
;
const
pairSymbols
=
[
"[]"
,
"()"
,
'""'
,
"''"
,
"{}"
,
"``"
,
"”“"
,
"‘‘"
,
"【】"
,
"()"
,
"《》"
];
const
getEditorContentCache
=
():
string
=>
{
const
getEditorContentCache
=
():
string
=>
{
return
storage
.
get
([
"editorContentCache"
]).
editorContentCache
??
""
;
return
storage
.
get
([
"editorContentCache"
]).
editorContentCache
??
""
;
...
@@ -29,12 +28,6 @@ const setEditorContentCache = (content: string) => {
...
@@ -29,12 +28,6 @@ const setEditorContentCache = (content: string) => {
});
});
};
};
const
setEditingMemoVisibilityCache
=
(
visibility
:
Visibility
)
=>
{
storage
.
set
({
editingMemoVisibilityCache
:
visibility
,
});
};
interface
State
{
interface
State
{
fullscreen
:
boolean
;
fullscreen
:
boolean
;
isUploadingResource
:
boolean
;
isUploadingResource
:
boolean
;
...
@@ -51,8 +44,8 @@ const MemoEditor = () => {
...
@@ -51,8 +44,8 @@ const MemoEditor = () => {
const
resourceStore
=
useResourceStore
();
const
resourceStore
=
useResourceStore
();
const
[
state
,
setState
]
=
useState
<
State
>
({
const
[
state
,
setState
]
=
useState
<
State
>
({
isUploadingResource
:
false
,
fullscreen
:
false
,
fullscreen
:
false
,
isUploadingResource
:
false
,
isRequesting
:
false
,
isRequesting
:
false
,
});
});
const
[
allowSave
,
setAllowSave
]
=
useState
<
boolean
>
(
false
);
const
[
allowSave
,
setAllowSave
]
=
useState
<
boolean
>
(
false
);
...
@@ -62,7 +55,6 @@ const MemoEditor = () => {
...
@@ -62,7 +55,6 @@ const MemoEditor = () => {
const
tagSelectorRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
tagSelectorRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
user
=
userStore
.
state
.
user
as
User
;
const
user
=
userStore
.
state
.
user
as
User
;
const
setting
=
user
.
setting
;
const
setting
=
user
.
setting
;
const
localSetting
=
user
.
localSetting
;
const
tags
=
tagStore
.
state
.
tags
;
const
tags
=
tagStore
.
state
.
tags
;
const
memoVisibilityOptionSelectorItems
=
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
{
const
memoVisibilityOptionSelectorItems
=
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
{
return
{
return
{
...
@@ -72,12 +64,9 @@ const MemoEditor = () => {
...
@@ -72,12 +64,9 @@ const MemoEditor = () => {
});
});
useEffect
(()
=>
{
useEffect
(()
=>
{
const
{
editingMemoIdCache
,
editingMemoVisibilityCache
}
=
storage
.
get
([
"editingMemoIdCache"
,
"editingMemoVisibility
Cache"
]);
const
{
editingMemoIdCache
}
=
storage
.
get
([
"editingMemoId
Cache"
]);
if
(
editingMemoIdCache
)
{
if
(
editingMemoIdCache
)
{
editorStore
.
setEditMemoWithId
(
editingMemoIdCache
);
editorStore
.
setEditMemoWithId
(
editingMemoIdCache
);
}
if
(
editingMemoVisibilityCache
)
{
editorStore
.
setMemoVisibility
(
editingMemoVisibilityCache
as
"PUBLIC"
|
"PROTECTED"
|
"PRIVATE"
);
}
else
{
}
else
{
editorStore
.
setMemoVisibility
(
setting
.
memoVisibility
);
editorStore
.
setMemoVisibility
(
setting
.
memoVisibility
);
}
}
...
@@ -109,8 +98,7 @@ const MemoEditor = () => {
...
@@ -109,8 +98,7 @@ const MemoEditor = () => {
}
}
const
isMetaKey
=
event
.
ctrlKey
||
event
.
metaKey
;
const
isMetaKey
=
event
.
ctrlKey
||
event
.
metaKey
;
const
isShiftKey
=
event
.
shiftKey
;
if
(
isMetaKey
)
{
if
(
!
isShiftKey
&&
isMetaKey
)
{
if
(
event
.
key
===
"Enter"
)
{
if
(
event
.
key
===
"Enter"
)
{
handleSaveBtnClick
();
handleSaveBtnClick
();
return
;
return
;
...
@@ -141,8 +129,7 @@ const MemoEditor = () => {
...
@@ -141,8 +129,7 @@ const MemoEditor = () => {
}
}
}
}
}
}
if
(
event
.
key
===
"Enter"
)
{
if
(
!
isShiftKey
&&
event
.
key
===
"Enter"
)
{
const
cursorPosition
=
editorRef
.
current
.
getCursorPosition
();
const
cursorPosition
=
editorRef
.
current
.
getCursorPosition
();
const
contentBeforeCursor
=
editorRef
.
current
.
getContent
().
slice
(
0
,
cursorPosition
);
const
contentBeforeCursor
=
editorRef
.
current
.
getContent
().
slice
(
0
,
cursorPosition
);
const
rowValue
=
last
(
contentBeforeCursor
.
split
(
"
\n
"
));
const
rowValue
=
last
(
contentBeforeCursor
.
split
(
"
\n
"
));
...
@@ -179,7 +166,7 @@ const MemoEditor = () => {
...
@@ -179,7 +166,7 @@ const MemoEditor = () => {
}
}
return
;
return
;
}
}
if
(
!
isShiftKey
&&
event
.
key
===
"Escape"
)
{
if
(
event
.
key
===
"Escape"
)
{
if
(
state
.
fullscreen
)
{
if
(
state
.
fullscreen
)
{
handleFullscreenBtnClick
();
handleFullscreenBtnClick
();
}
}
...
@@ -190,57 +177,37 @@ const MemoEditor = () => {
...
@@ -190,57 +177,37 @@ const MemoEditor = () => {
const
tabSpace
=
" "
.
repeat
(
TAB_SPACE_WIDTH
);
const
tabSpace
=
" "
.
repeat
(
TAB_SPACE_WIDTH
);
const
cursorPosition
=
editorRef
.
current
.
getCursorPosition
();
const
cursorPosition
=
editorRef
.
current
.
getCursorPosition
();
const
selectedContent
=
editorRef
.
current
.
getSelectedContent
();
const
selectedContent
=
editorRef
.
current
.
getSelectedContent
();
if
(
isShiftKey
)
{
const
beforeContent
=
editorRef
.
current
.
getContent
().
slice
(
0
,
cursorPosition
);
for
(
let
i
=
beforeContent
.
length
-
1
;
i
>=
0
;
i
--
)
{
if
(
beforeContent
[
i
]
!==
"
\n
"
)
{
continue
;
}
const
rowStart
=
i
+
1
;
const
isTabSpace
=
beforeContent
.
substring
(
rowStart
,
i
+
TAB_SPACE_WIDTH
+
1
)
===
tabSpace
;
const
isSpace
=
beforeContent
.
substring
(
rowStart
,
i
+
2
)
===
" "
;
if
(
!
isTabSpace
&&
!
isSpace
)
{
break
;
}
const
removeLength
=
isTabSpace
?
TAB_SPACE_WIDTH
:
1
;
editorRef
.
current
.
removeText
(
rowStart
,
removeLength
);
const
startPos
=
cursorPosition
-
removeLength
;
let
endPos
=
startPos
;
if
(
selectedContent
)
{
endPos
+=
selectedContent
.
length
;
}
editorRef
.
current
.
setCursorPosition
(
startPos
,
endPos
);
}
return
;
}
else
{
editorRef
.
current
.
insertText
(
tabSpace
);
editorRef
.
current
.
insertText
(
tabSpace
);
if
(
selectedContent
)
{
if
(
selectedContent
)
{
editorRef
.
current
.
setCursorPosition
(
cursorPosition
+
TAB_SPACE_WIDTH
);
editorRef
.
current
.
setCursorPosition
(
cursorPosition
+
TAB_SPACE_WIDTH
);
}
}
return
;
return
;
}
}
}
};
if
(
localSetting
.
enablePowerfulEditor
)
{
const
handleUploadResource
=
async
(
file
:
File
)
=>
{
for
(
const
symbol
of
pairSymbols
)
{
setState
((
state
)
=>
{
if
(
event
.
key
===
symbol
[
0
])
{
return
{
event
.
preventDefault
();
...
state
,
editorRef
.
current
.
insertText
(
""
,
symbol
[
0
],
symbol
[
1
]);
isUploadingResource
:
true
,
return
;
};
}
});
}
if
(
event
.
key
===
"Backspace"
)
{
let
resource
=
undefined
;
const
cursor
=
editorRef
.
current
.
getCursorPosition
();
try
{
const
content
=
editorRef
.
current
.
getContent
();
resource
=
await
resourceStore
.
createResourceWithBlob
(
file
);
const
deleteChar
=
content
?.
slice
(
cursor
-
1
,
cursor
);
}
catch
(
error
:
any
)
{
const
nextChar
=
content
?.
slice
(
cursor
,
cursor
+
1
);
console
.
error
(
error
);
if
(
pairSymbols
.
includes
(
`
${
deleteChar
}${
nextChar
}
`
))
{
toastHelper
.
error
(
error
.
response
.
data
.
message
);
event
.
preventDefault
();
editorRef
.
current
.
removeText
(
cursor
-
1
,
2
);
}
return
;
}
}
}
setState
((
state
)
=>
{
return
{
...
state
,
isUploadingResource
:
false
,
};
});
return
resource
;
};
};
const
uploadMultiFiles
=
async
(
files
:
FileList
)
=>
{
const
uploadMultiFiles
=
async
(
files
:
FileList
)
=>
{
...
@@ -274,32 +241,6 @@ const MemoEditor = () => {
...
@@ -274,32 +241,6 @@ const MemoEditor = () => {
}
}
};
};
const
handleUploadResource
=
async
(
file
:
File
)
=>
{
setState
((
state
)
=>
{
return
{
...
state
,
isUploadingResource
:
true
,
};
});
let
resource
=
undefined
;
try
{
resource
=
await
resourceStore
.
createResourceWithBlob
(
file
);
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
setState
((
state
)
=>
{
return
{
...
state
,
isUploadingResource
:
false
,
};
});
return
resource
;
};
const
scrollToEditingMemo
=
useCallback
(()
=>
{
const
scrollToEditingMemo
=
useCallback
(()
=>
{
if
(
editorState
.
editMemoId
)
{
if
(
editorState
.
editMemoId
)
{
const
memoElements
=
document
.
getElementsByClassName
(
`memos-
${
editorState
.
editMemoId
}
`
);
const
memoElements
=
document
.
getElementsByClassName
(
`memos-
${
editorState
.
editMemoId
}
`
);
...
@@ -369,9 +310,7 @@ const MemoEditor = () => {
...
@@ -369,9 +310,7 @@ const MemoEditor = () => {
});
});
editorStore
.
clearResourceList
();
editorStore
.
clearResourceList
();
setEditorContentCache
(
""
);
setEditorContentCache
(
""
);
storage
.
remove
([
"editingMemoVisibilityCache"
]);
editorRef
.
current
?.
setContent
(
""
);
editorRef
.
current
?.
setContent
(
""
);
scrollToEditingMemo
();
scrollToEditingMemo
();
};
};
...
@@ -381,10 +320,8 @@ const MemoEditor = () => {
...
@@ -381,10 +320,8 @@ const MemoEditor = () => {
editorStore
.
clearResourceList
();
editorStore
.
clearResourceList
();
editorRef
.
current
?.
setContent
(
""
);
editorRef
.
current
?.
setContent
(
""
);
setEditorContentCache
(
""
);
setEditorContentCache
(
""
);
storage
.
remove
([
"editingMemoVisibilityCache"
]);
}
scrollToEditingMemo
();
scrollToEditingMemo
();
}
};
};
const
handleContentChange
=
(
content
:
string
)
=>
{
const
handleContentChange
=
(
content
:
string
)
=>
{
...
@@ -439,11 +376,8 @@ const MemoEditor = () => {
...
@@ -439,11 +376,8 @@ const MemoEditor = () => {
});
});
};
};
const
handleTagSelectorClick
=
useCallback
((
event
:
React
.
MouseEvent
)
=>
{
const
handleTagSelectorClick
=
useCallback
((
tag
:
string
)
=>
{
if
(
tagSelectorRef
.
current
!==
event
.
target
&&
tagSelectorRef
.
current
?.
contains
(
event
.
target
as
Node
))
{
editorRef
.
current
?.
insertText
(
`#
${
tag
}
`
);
editorRef
.
current
?.
insertText
(
`#
${(
event
.
target
as
HTMLElement
).
textContent
}
`
??
""
);
editorRef
.
current
?.
scrollToCursor
();
}
},
[]);
},
[]);
const
handleDeleteResource
=
async
(
resourceId
:
ResourceId
)
=>
{
const
handleDeleteResource
=
async
(
resourceId
:
ResourceId
)
=>
{
...
@@ -456,7 +390,6 @@ const MemoEditor = () => {
...
@@ -456,7 +390,6 @@ const MemoEditor = () => {
const
handleMemoVisibilityOptionChanged
=
async
(
value
:
string
)
=>
{
const
handleMemoVisibilityOptionChanged
=
async
(
value
:
string
)
=>
{
const
visibilityValue
=
value
as
Visibility
;
const
visibilityValue
=
value
as
Visibility
;
editorStore
.
setMemoVisibility
(
visibilityValue
);
editorStore
.
setMemoVisibility
(
visibilityValue
);
setEditingMemoVisibilityCache
(
visibilityValue
);
};
};
const
handleEditorFocus
=
()
=>
{
const
handleEditorFocus
=
()
=>
{
...
@@ -495,12 +428,12 @@ const MemoEditor = () => {
...
@@ -495,12 +428,12 @@ const MemoEditor = () => {
<
div
className=
"common-tools-container"
>
<
div
className=
"common-tools-container"
>
<
div
className=
"action-btn tag-action"
>
<
div
className=
"action-btn tag-action"
>
<
Icon
.
Hash
className=
"icon-img"
/>
<
Icon
.
Hash
className=
"icon-img"
/>
<
div
ref=
{
tagSelectorRef
}
className=
"tag-list"
onClick=
{
handleTagSelectorClick
}
>
<
div
ref=
{
tagSelectorRef
}
className=
"tag-list"
>
{
tags
.
length
>
0
?
(
{
tags
.
length
>
0
?
(
tags
.
map
((
tag
)
=>
{
tags
.
map
((
tag
)
=>
{
return
(
return
(
<
span
className=
"item-container"
key=
{
tag
}
>
<
span
className=
"item-container"
onClick=
{
()
=>
handleTagSelectorClick
(
tag
)
}
key=
{
tag
}
>
{
tag
}
#
{
tag
}
</
span
>
</
span
>
);
);
})
})
...
...
web/src/components/MemoResource.tsx
View file @
a997e1d1
...
@@ -16,7 +16,7 @@ const MemoResource: React.FC<Props> = (props: Props) => {
...
@@ -16,7 +16,7 @@ const MemoResource: React.FC<Props> = (props: Props) => {
return
(
return
(
<>
<>
<
div
className=
{
`w-auto flex flex-row justify-start items-center ${className}`
}
>
<
div
className=
{
`w-auto flex flex-row justify-start items-center
hover:opacity-80
${className}`
}
>
{
resource
.
type
.
startsWith
(
"audio"
)
?
(
{
resource
.
type
.
startsWith
(
"audio"
)
?
(
<>
<>
<
audio
className=
"h-8"
src=
{
resourceUrl
}
controls
></
audio
>
<
audio
className=
"h-8"
src=
{
resourceUrl
}
controls
></
audio
>
...
@@ -24,7 +24,7 @@ const MemoResource: React.FC<Props> = (props: Props) => {
...
@@ -24,7 +24,7 @@ const MemoResource: React.FC<Props> = (props: Props) => {
)
:
(
)
:
(
<>
<>
<
Icon
.
FileText
className=
"w-4 h-auto mr-1 text-gray-500"
/>
<
Icon
.
FileText
className=
"w-4 h-auto mr-1 text-gray-500"
/>
<
span
className=
"text-gray-500 text-sm max-w-
xs
truncate font-mono cursor-pointer"
onClick=
{
handlePreviewBtnClick
}
>
<
span
className=
"text-gray-500 text-sm max-w-
[256px]
truncate font-mono cursor-pointer"
onClick=
{
handlePreviewBtnClick
}
>
{
resource
.
filename
}
{
resource
.
filename
}
</
span
>
</
span
>
</>
</>
...
...
web/src/helpers/storage.ts
View file @
a997e1d1
...
@@ -6,8 +6,6 @@ interface StorageData {
...
@@ -6,8 +6,6 @@ interface StorageData {
editorContentCache
:
string
;
editorContentCache
:
string
;
// Editing memo id cache
// Editing memo id cache
editingMemoIdCache
:
MemoId
;
editingMemoIdCache
:
MemoId
;
// Editing memo visibility
editingMemoVisibilityCache
:
Visibility
;
// locale
// locale
locale
:
Locale
;
locale
:
Locale
;
// appearance
// appearance
...
...
web/src/less/memo-editor.less
View file @
a997e1d1
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
@apply flex flex-row justify-start items-center;
@apply flex flex-row justify-start items-center;
> .action-btn {
> .action-btn {
@apply flex flex-row justify-center items-center p-1 w-auto h-auto mr-1 select-none rounded cursor-pointer
dark:text-gray-200 opacity-60 hover:opacity-9
0 hover:bg-gray-300 dark:hover:bg-zinc-800 hover:shadow;
@apply flex flex-row justify-center items-center p-1 w-auto h-auto mr-1 select-none rounded cursor-pointer
text-gray-600 dark:text-gray-20
0 hover:bg-gray-300 dark:hover:bg-zinc-800 hover:shadow;
&.tag-action {
&.tag-action {
@apply relative;
@apply relative;
...
@@ -49,14 +49,14 @@
...
@@ -49,14 +49,14 @@
}
}
> .tag-list {
> .tag-list {
@apply hidden flex-
col justify-start items-start absolute top-6 left-0 mt-1 p-1 z-1 rounded w-36 max-h-52 overflow-auto font-mono bg-black
;
@apply hidden flex-
row justify-start items-start flex-wrap absolute top-6 left-0 mt-1 p-1 z-1 rounded w-52 h-auto max-h-48 overflow-y-auto font-mono shadow bg-zinc-200 dark:bg-zinc-600
;
> .item-container {
> .item-container {
@apply w-
full text-white cursor-pointer rounded text-sm leading-6 px-2 truncate hover:bg-gray
-700 shrink-0;
@apply w-
auto max-w-full truncate text-black dark:text-gray-300 cursor-pointer rounded text-sm leading-6 px-2 truncate hover:bg-zinc-300 dark:hover:bg-zinc
-700 shrink-0;
}
}
> .tip-text {
> .tip-text {
@apply w-
full
text-sm text-gray-200 leading-6 px-2 cursor-default;
@apply w-
auto
text-sm text-gray-200 leading-6 px-2 cursor-default;
}
}
}
}
}
}
...
...
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