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
308adef9
Commit
308adef9
authored
Jan 11, 2022
by
email
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: editor tools
parent
9a6e2d10
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
38 additions
and
47 deletions
+38
-47
Editor.tsx
web/src/components/Editor/Editor.tsx
+5
-14
MemoEditor.tsx
web/src/components/MemoEditor.tsx
+30
-32
OnlyWhen.tsx
web/src/components/common/OnlyWhen.tsx
+3
-1
No files found.
web/src/components/Editor/Editor.tsx
View file @
308adef9
import
{
forwardRef
,
useCallback
,
useContext
,
useEffect
,
useImperativeHandle
,
useRef
}
from
"react"
;
import
{
forwardRef
,
ReactNode
,
useCallback
,
useContext
,
useEffect
,
useImperativeHandle
,
useRef
}
from
"react"
;
import
TinyUndo
from
"tiny-undo"
;
import
appContext
from
"../../stores/appContext"
;
import
{
storage
}
from
"../../helpers/storage"
;
...
...
@@ -14,17 +14,15 @@ export interface EditorRefActions {
getContent
:
()
=>
string
;
}
export
interface
EditorProps
{
interface
EditorProps
{
className
:
string
;
initialContent
:
string
;
placeholder
:
string
;
showConfirmBtn
:
boolean
;
showCancelBtn
:
boolean
;
showTools
:
boolean
;
tools
?:
ReactNode
;
onConfirmBtnClick
:
(
content
:
string
)
=>
void
;
onCancelBtnClick
:
()
=>
void
;
onTagTextBtnClick
:
()
=>
void
;
onUploadFileBtnClick
:
()
=>
void
;
onContentChange
:
(
content
:
string
)
=>
void
;
}
...
...
@@ -39,15 +37,13 @@ const Editor = forwardRef((props: EditorProps, ref: React.ForwardedRef<EditorRef
placeholder
,
showConfirmBtn
,
showCancelBtn
,
showTools
,
onConfirmBtnClick
:
handleConfirmBtnClickCallback
,
onCancelBtnClick
:
handleCancelBtnClickCallback
,
onTagTextBtnClick
:
handleTagTextBtnClickCallback
,
onUploadFileBtnClick
:
handleUploadFileBtnClickCallback
,
onContentChange
:
handleContentChangeCallback
,
}
=
props
;
const
editorRef
=
useRef
<
HTMLTextAreaElement
>
(
null
);
const
tinyUndoRef
=
useRef
<
TinyUndo
|
null
>
(
null
);
// NOTE: auto-justify textarea height
const
refresh
=
useRefresh
();
useEffect
(()
=>
{
...
...
@@ -175,12 +171,7 @@ const Editor = forwardRef((props: EditorProps, ref: React.ForwardedRef<EditorRef
></
textarea
>
<
div
className=
"common-tools-wrapper"
>
<
div
className=
"common-tools-container"
>
<
Only
when=
{
showTools
}
>
<>
<
img
className=
"action-btn file-upload"
src=
"/icons/tag.svg"
onClick=
{
handleTagTextBtnClickCallback
}
/>
<
img
className=
"action-btn file-upload"
src=
"/icons/image.svg"
onClick=
{
handleUploadFileBtnClickCallback
}
/>
</>
</
Only
>
<
Only
when=
{
props
.
tools
!==
undefined
}
>
{
props
.
tools
}
</
Only
>
</
div
>
<
div
className=
"btns-container"
>
<
Only
when=
{
showCancelBtn
}
>
...
...
web/src/components/MemoEditor.tsx
View file @
308adef9
...
...
@@ -5,7 +5,7 @@ import utils from "../helpers/utils";
import
{
storage
}
from
"../helpers/storage"
;
import
useToggle
from
"../hooks/useToggle"
;
import
toastHelper
from
"./Toast"
;
import
Editor
,
{
Editor
Props
,
Editor
RefActions
}
from
"./Editor/Editor"
;
import
Editor
,
{
EditorRefActions
}
from
"./Editor/Editor"
;
import
"../less/memo-editor.less"
;
const
getCursorPostion
=
(
input
:
HTMLTextAreaElement
)
=>
{
...
...
@@ -20,7 +20,6 @@ const getCursorPostion = (input: HTMLTextAreaElement) => {
div
.
style
.
visibility
=
"hidden"
;
div
.
style
.
whiteSpace
=
"pre-wrap"
;
// we need a character that will replace whitespace when filling our dummy element if it's a single line <input/>
const
swap
=
"."
;
const
inputValue
=
input
.
tagName
===
"INPUT"
?
input
.
value
.
replace
(
/ /g
,
swap
)
:
input
.
value
;
const
textContent
=
inputValue
.
substring
(
0
,
selectionPoint
||
0
);
...
...
@@ -100,9 +99,7 @@ const MemoEditor: React.FC<Props> = () => {
};
const
handleClickEvent
=
()
=>
{
setTimeout
(()
=>
{
handleContentChange
(
editorRef
.
current
?.
element
.
value
??
""
);
});
handleContentChange
(
editorRef
.
current
?.
element
.
value
??
""
);
};
const
handleKeyDownEvent
=
()
=>
{
...
...
@@ -184,20 +181,18 @@ const MemoEditor: React.FC<Props> = () => {
setEditorContentCache
(
content
);
if
(
editorRef
.
current
)
{
const
currentValue
=
editorRef
.
current
.
getContent
();
const
selectionStart
=
editorRef
.
current
.
element
.
selectionStart
;
const
prevString
=
currentValue
.
slice
(
0
,
selectionStart
);
const
prevString
=
content
.
slice
(
0
,
selectionStart
);
const
nextString
=
content
.
slice
(
selectionStart
);
if
(
prevString
.
endsWith
(
"#"
))
{
if
(
prevString
.
endsWith
(
"#"
)
&&
(
nextString
.
startsWith
(
" "
)
||
nextString
===
""
)
)
{
toggleTagSeletor
(
true
);
updateTagSelectorPopupPosition
();
}
else
{
toggleTagSeletor
(
false
);
}
setTimeout
(()
=>
{
editorRef
.
current
?.
focus
();
});
editorRef
.
current
?.
focus
();
}
},
[]);
...
...
@@ -219,16 +214,10 @@ const MemoEditor: React.FC<Props> = () => {
cursorIndex
=
prevString
.
length
-
1
;
}
setTimeout
(()
=>
{
if
(
!
editorRef
.
current
)
{
return
;
}
editorRef
.
current
.
element
.
value
=
nextValue
;
editorRef
.
current
.
element
.
setSelectionRange
(
cursorIndex
,
cursorIndex
);
editorRef
.
current
.
focus
();
handleContentChange
(
editorRef
.
current
.
element
.
value
);
});
editorRef
.
current
.
element
.
value
=
nextValue
;
editorRef
.
current
.
element
.
setSelectionRange
(
cursorIndex
,
cursorIndex
);
editorRef
.
current
.
focus
();
handleContentChange
(
editorRef
.
current
.
element
.
value
);
},
[]);
const
updateTagSelectorPopupPosition
=
useCallback
(()
=>
{
...
...
@@ -236,13 +225,15 @@ const MemoEditor: React.FC<Props> = () => {
return
;
}
const
seletorPopupWidth
=
128
;
const
editorWidth
=
editorRef
.
current
.
element
.
clientWidth
;
const
{
x
,
y
}
=
getCursorPostion
(
editorRef
.
current
.
element
);
if
(
x
+
128
+
16
>
editorRef
.
current
.
element
.
clientWidth
)
{
tagSeletorRef
.
current
.
style
.
left
=
`
${
editorRef
.
current
.
element
.
clientWidth
+
20
-
128
}
px`
;
}
else
{
tagSeletorRef
.
current
.
style
.
left
=
`
${
x
+
2
}
px`
;
}
tagSeletorRef
.
current
.
style
.
top
=
`
${
y
+
32
+
6
}
px`
;
const
left
=
x
+
seletorPopupWidth
+
16
>
editorWidth
?
editorWidth
+
20
-
seletorPopupWidth
:
x
+
2
;
const
top
=
y
+
32
+
6
;
tagSeletorRef
.
current
.
scroll
(
0
,
0
)
;
tagSeletorRef
.
current
.
style
.
left
=
`
${
left
}
px`
;
tagSeletorRef
.
current
.
style
.
top
=
`
${
top
}
px`
;
},
[]);
const
handleUploadFileBtnClick
=
useCallback
(()
=>
{
...
...
@@ -267,23 +258,21 @@ const MemoEditor: React.FC<Props> = () => {
const
handleTagSeletorClick
=
useCallback
((
event
:
React
.
MouseEvent
)
=>
{
if
(
tagSeletorRef
.
current
!==
event
.
target
&&
tagSeletorRef
.
current
?.
contains
(
event
.
target
as
Node
))
{
editorRef
.
current
?.
insertText
((
event
.
target
as
HTMLElement
).
textContent
??
""
);
toggleTagSeletor
(
false
);
}
},
[]);
const
showEditStatus
=
Boolean
(
globalState
.
editMemoId
);
const
editorConfig
:
EditorProps
=
useMemo
(
const
editorConfig
=
useMemo
(
()
=>
({
className
:
"memo-editor"
,
initialContent
:
getEditorContentCache
(),
placeholder
:
"现在的想法是..."
,
showConfirmBtn
:
true
,
showCancelBtn
:
showEditStatus
,
showTools
:
true
,
onConfirmBtnClick
:
handleSaveBtnClick
,
onCancelBtnClick
:
handleCancelBtnClick
,
onTagTextBtnClick
:
handleTagTextBtnClick
,
onUploadFileBtnClick
:
handleUploadFileBtnClick
,
onContentChange
:
handleContentChange
,
}),
[
showEditStatus
]
...
...
@@ -292,7 +281,16 @@ const MemoEditor: React.FC<Props> = () => {
return
(
<
div
className=
{
"memo-editor-wrapper "
+
(
showEditStatus
?
"edit-ing"
:
""
)
}
>
<
p
className=
{
"tip-text "
+
(
showEditStatus
?
""
:
"hidden"
)
}
>
正在修改中...
</
p
>
<
Editor
ref=
{
editorRef
}
{
...
editorConfig
}
/>
<
Editor
ref=
{
editorRef
}
{
...
editorConfig
}
tools=
{
<>
<
img
className=
"action-btn file-upload"
src=
"/icons/tag.svg"
onClick=
{
handleTagTextBtnClick
}
/>
<
img
className=
"action-btn file-upload"
src=
"/icons/image.svg"
onClick=
{
handleUploadFileBtnClick
}
/>
</>
}
/>
<
div
ref=
{
tagSeletorRef
}
className=
{
`tag-list ${isTagSeletorShown && tags.length > 0 ? "" : "hidden"}`
}
...
...
web/src/components/common/OnlyWhen.tsx
View file @
308adef9
import
{
ReactNode
}
from
"react"
;
interface
OnlyWhenProps
{
children
:
React
.
ReactElement
;
children
:
React
Node
;
when
:
boolean
;
}
...
...
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