feat: add emoji picker in editor (#221)

* feat: add vietnamese

* feat: add emoji picker in editor

* fix failing checks

* move emoji button before upload button

* move script to body index.html

* Update web/index.html

Co-authored-by: boojack <stevenlgtm@gmail.com>
This commit is contained in:
f97 2022-09-16 23:42:52 +07:00 committed by GitHub
parent 059080f194
commit e7db587a9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 0 deletions

View File

@ -12,6 +12,7 @@
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script>
var global = global || window;
window.addEventListener("load", () => {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js");

View File

@ -12,6 +12,7 @@
"axios": "^0.27.2",
"copy-to-clipboard": "^3.3.2",
"dayjs": "^1.11.3",
"emoji-picker-react": "^3.6.2",
"lodash-es": "^4.17.21",
"qs": "^6.11.0",
"react": "^18.1.0",

View File

@ -0,0 +1,41 @@
import { forwardRef, useEffect } from "react";
import Picker, { IEmojiPickerProps } from "emoji-picker-react";
export type EmojiPickerElement = HTMLDivElement;
interface Props {
isShowEmojiPicker: boolean;
onEmojiClick: IEmojiPickerProps["onEmojiClick"];
handleChangeIsShowEmojiPicker: (status: boolean) => void;
}
export const EmojiPicker = forwardRef<EmojiPickerElement, Props>((props: Props, ref) => {
const { isShowEmojiPicker, onEmojiClick, handleChangeIsShowEmojiPicker } = props;
useEffect(() => {
if (isShowEmojiPicker) {
const handleClickOutside = (event: MouseEvent) => {
const emojiWrapper = document.querySelector(".emoji-picker-react");
const isContains = emojiWrapper?.contains(event.target as Node);
if (!isContains) {
handleChangeIsShowEmojiPicker(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}
}, [isShowEmojiPicker]);
return (
<div className="emoji-picker" ref={ref}>
<Picker onEmojiClick={onEmojiClick} />
</div>
);
});
EmojiPicker.displayName = "EmojiPicker";
export default EmojiPicker;

View File

@ -7,11 +7,13 @@ import * as storage from "../helpers/storage";
import Icon from "./Icon";
import toastHelper from "./Toast";
import Editor, { EditorRefActions } from "./Editor/Editor";
import EmojiPicker from "./Editor/EmojiPicker";
import "../less/memo-editor.less";
interface State {
isUploadingResource: boolean;
fullscreen: boolean;
isShowEmojiPicker: boolean;
}
const MemoEditor = () => {
@ -22,6 +24,7 @@ const MemoEditor = () => {
const [state, setState] = useState<State>({
isUploadingResource: false,
fullscreen: false,
isShowEmojiPicker: false,
});
const editorRef = useRef<EditorRefActions>(null);
const prevGlobalStateRef = useRef(editorState);
@ -244,6 +247,21 @@ const MemoEditor = () => {
}
}, []);
const handleChangeIsShowEmojiPicker = (status: boolean) => {
setState({
...state,
isShowEmojiPicker: status,
});
};
const handleEmojiClick = (event: any, emojiObject: any) => {
if (!editorRef.current) {
return;
}
editorRef.current?.insertText(`${emojiObject.emoji}`);
handleChangeIsShowEmojiPicker(false);
};
const isEditing = Boolean(editorState.editMemoId && editorState.editMemoId !== UNKNOWN_ID);
const editorConfig = useMemo(
@ -296,6 +314,9 @@ const MemoEditor = () => {
<button className="action-btn">
<Icon.Code className="icon-img" onClick={handleCodeBlockBtnClick} />
</button>
<button className="action-btn">
<Icon.Smile className="icon-img" onClick={() => handleChangeIsShowEmojiPicker(!state.isShowEmojiPicker)} />
</button>
<button className="action-btn">
<Icon.Image className="icon-img" onClick={handleUploadFileBtnClick} />
<span className={`tip-text ${state.isUploadingResource ? "!block" : ""}`}>Uploading</span>
@ -306,6 +327,13 @@ const MemoEditor = () => {
</>
}
/>
{state.isShowEmojiPicker && (
<EmojiPicker
onEmojiClick={handleEmojiClick}
isShowEmojiPicker={state.isShowEmojiPicker}
handleChangeIsShowEmojiPicker={handleChangeIsShowEmojiPicker}
/>
)}
</div>
);
};

View File

@ -62,4 +62,12 @@
}
}
}
.emoji-picker-react {
@apply absolute;
li.emoji::before {
@apply hidden;
}
}
}

View File

@ -885,6 +885,11 @@ electron-to-chromium@^1.4.172:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.185.tgz#3432d7944f1c5fe20664bb45d9cced2151405ce2"
integrity sha512-9kV/isoOGpKkBt04yYNaSWIBn3187Q5VZRtoReq8oz5NY/A4XmU6cAoqgQlDp7kKJCZMRjWZ8nsQyxfpFHvfyw==
emoji-picker-react@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/emoji-picker-react/-/emoji-picker-react-3.6.2.tgz#e414971bf9421b0825484f3b82623fef995c3c4b"
integrity sha512-PK3dfljGxeyN8fDz2FAsDYKPYGgo6/tkRyzJjLVaw0fksJg7jA3OJPIlHq2IIzTmlC/NKhcI/oaf0uEo5azYGA==
errno@^0.1.1:
version "0.1.8"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"