Skip to content

Commit 77d8e88

Browse files
f97boojack
andcommitted
feat: add emoji picker in editor (usememos#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 <[email protected]>
1 parent ed31f90 commit 77d8e88

6 files changed

Lines changed: 84 additions & 0 deletions

File tree

web/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<div id="root"></div>
1313
<script type="module" src="/src/main.tsx"></script>
1414
<script>
15+
var global = global || window;
1516
window.addEventListener("load", () => {
1617
if ("serviceWorker" in navigator) {
1718
navigator.serviceWorker.register("/sw.js");

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"axios": "^0.27.2",
1313
"copy-to-clipboard": "^3.3.2",
1414
"dayjs": "^1.11.3",
15+
"emoji-picker-react": "^3.6.2",
1516
"lodash-es": "^4.17.21",
1617
"qs": "^6.11.0",
1718
"react": "^18.1.0",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { forwardRef, useEffect } from "react";
2+
import Picker, { IEmojiPickerProps } from "emoji-picker-react";
3+
4+
export type EmojiPickerElement = HTMLDivElement;
5+
6+
interface Props {
7+
isShowEmojiPicker: boolean;
8+
onEmojiClick: IEmojiPickerProps["onEmojiClick"];
9+
handleChangeIsShowEmojiPicker: (status: boolean) => void;
10+
}
11+
12+
export const EmojiPicker = forwardRef<EmojiPickerElement, Props>((props: Props, ref) => {
13+
const { isShowEmojiPicker, onEmojiClick, handleChangeIsShowEmojiPicker } = props;
14+
15+
useEffect(() => {
16+
if (isShowEmojiPicker) {
17+
const handleClickOutside = (event: MouseEvent) => {
18+
const emojiWrapper = document.querySelector(".emoji-picker-react");
19+
const isContains = emojiWrapper?.contains(event.target as Node);
20+
if (!isContains) {
21+
handleChangeIsShowEmojiPicker(false);
22+
}
23+
};
24+
document.addEventListener("mousedown", handleClickOutside);
25+
return () => {
26+
// Unbind the event listener on clean up
27+
document.removeEventListener("mousedown", handleClickOutside);
28+
};
29+
}
30+
}, [isShowEmojiPicker]);
31+
32+
return (
33+
<div className="emoji-picker" ref={ref}>
34+
<Picker onEmojiClick={onEmojiClick} />
35+
</div>
36+
);
37+
});
38+
39+
EmojiPicker.displayName = "EmojiPicker";
40+
41+
export default EmojiPicker;

web/src/components/MemoEditor.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import * as storage from "../helpers/storage";
77
import Icon from "./Icon";
88
import toastHelper from "./Toast";
99
import Editor, { EditorRefActions } from "./Editor/Editor";
10+
import EmojiPicker from "./Editor/EmojiPicker";
1011
import "../less/memo-editor.less";
1112

1213
interface State {
1314
isUploadingResource: boolean;
1415
fullscreen: boolean;
16+
isShowEmojiPicker: boolean;
1517
}
1618

1719
const MemoEditor = () => {
@@ -22,6 +24,7 @@ const MemoEditor = () => {
2224
const [state, setState] = useState<State>({
2325
isUploadingResource: false,
2426
fullscreen: false,
27+
isShowEmojiPicker: false,
2528
});
2629
const editorRef = useRef<EditorRefActions>(null);
2730
const prevGlobalStateRef = useRef(editorState);
@@ -244,6 +247,21 @@ const MemoEditor = () => {
244247
}
245248
}, []);
246249

250+
const handleChangeIsShowEmojiPicker = (status: boolean) => {
251+
setState({
252+
...state,
253+
isShowEmojiPicker: status,
254+
});
255+
};
256+
257+
const handleEmojiClick = (event: any, emojiObject: any) => {
258+
if (!editorRef.current) {
259+
return;
260+
}
261+
editorRef.current?.insertText(`${emojiObject.emoji}`);
262+
handleChangeIsShowEmojiPicker(false);
263+
};
264+
247265
const isEditing = Boolean(editorState.editMemoId && editorState.editMemoId !== UNKNOWN_ID);
248266

249267
const editorConfig = useMemo(
@@ -296,6 +314,9 @@ const MemoEditor = () => {
296314
<button className="action-btn">
297315
<Icon.Code className="icon-img" onClick={handleCodeBlockBtnClick} />
298316
</button>
317+
<button className="action-btn">
318+
<Icon.Smile className="icon-img" onClick={() => handleChangeIsShowEmojiPicker(!state.isShowEmojiPicker)} />
319+
</button>
299320
<button className="action-btn">
300321
<Icon.Image className="icon-img" onClick={handleUploadFileBtnClick} />
301322
<span className={`tip-text ${state.isUploadingResource ? "!block" : ""}`}>Uploading</span>
@@ -306,6 +327,13 @@ const MemoEditor = () => {
306327
</>
307328
}
308329
/>
330+
{state.isShowEmojiPicker && (
331+
<EmojiPicker
332+
onEmojiClick={handleEmojiClick}
333+
isShowEmojiPicker={state.isShowEmojiPicker}
334+
handleChangeIsShowEmojiPicker={handleChangeIsShowEmojiPicker}
335+
/>
336+
)}
309337
</div>
310338
);
311339
};

web/src/less/memo-editor.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,12 @@
6262
}
6363
}
6464
}
65+
66+
.emoji-picker-react {
67+
@apply absolute;
68+
69+
li.emoji::before {
70+
@apply hidden;
71+
}
72+
}
6573
}

web/yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,11 @@ electron-to-chromium@^1.4.172:
885885
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.185.tgz#3432d7944f1c5fe20664bb45d9cced2151405ce2"
886886
integrity sha512-9kV/isoOGpKkBt04yYNaSWIBn3187Q5VZRtoReq8oz5NY/A4XmU6cAoqgQlDp7kKJCZMRjWZ8nsQyxfpFHvfyw==
887887

888+
emoji-picker-react@^3.6.2:
889+
version "3.6.2"
890+
resolved "https://registry.yarnpkg.com/emoji-picker-react/-/emoji-picker-react-3.6.2.tgz#e414971bf9421b0825484f3b82623fef995c3c4b"
891+
integrity sha512-PK3dfljGxeyN8fDz2FAsDYKPYGgo6/tkRyzJjLVaw0fksJg7jA3OJPIlHq2IIzTmlC/NKhcI/oaf0uEo5azYGA==
892+
888893
errno@^0.1.1:
889894
version "0.1.8"
890895
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"

0 commit comments

Comments
 (0)