|
|
@ -35,10 +35,9 @@ interface State {
|
|
|
|
isUploadingResource: boolean;
|
|
|
|
isUploadingResource: boolean;
|
|
|
|
resourceList: Resource[];
|
|
|
|
resourceList: Resource[];
|
|
|
|
shouldShowEmojiPicker: boolean;
|
|
|
|
shouldShowEmojiPicker: boolean;
|
|
|
|
isEditorFocused: boolean;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const MemoEditor: React.FC = () => {
|
|
|
|
const MemoEditor = () => {
|
|
|
|
const { t, i18n } = useTranslation();
|
|
|
|
const { t, i18n } = useTranslation();
|
|
|
|
const user = useAppSelector((state) => state.user.user as User);
|
|
|
|
const user = useAppSelector((state) => state.user.user as User);
|
|
|
|
const setting = user.setting;
|
|
|
|
const setting = user.setting;
|
|
|
@ -49,7 +48,6 @@ const MemoEditor: React.FC = () => {
|
|
|
|
fullscreen: false,
|
|
|
|
fullscreen: false,
|
|
|
|
shouldShowEmojiPicker: false,
|
|
|
|
shouldShowEmojiPicker: false,
|
|
|
|
resourceList: [],
|
|
|
|
resourceList: [],
|
|
|
|
isEditorFocused: false,
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const [allowSave, setAllowSave] = useState<boolean>(false);
|
|
|
|
const [allowSave, setAllowSave] = useState<boolean>(false);
|
|
|
|
const prevGlobalStateRef = useRef(editorState);
|
|
|
|
const prevGlobalStateRef = useRef(editorState);
|
|
|
@ -155,9 +153,11 @@ const MemoEditor: React.FC = () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
resourceList: [...state.resourceList, ...resourceList],
|
|
|
|
...state,
|
|
|
|
|
|
|
|
resourceList: [...state.resourceList, ...resourceList],
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -168,18 +168,22 @@ const MemoEditor: React.FC = () => {
|
|
|
|
const file = event.clipboardData.files[0];
|
|
|
|
const file = event.clipboardData.files[0];
|
|
|
|
const resource = await handleUploadResource(file);
|
|
|
|
const resource = await handleUploadResource(file);
|
|
|
|
if (resource) {
|
|
|
|
if (resource) {
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
resourceList: [...state.resourceList, resource],
|
|
|
|
...state,
|
|
|
|
|
|
|
|
resourceList: [...state.resourceList, resource],
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleUploadResource = async (file: File) => {
|
|
|
|
const handleUploadResource = async (file: File) => {
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
isUploadingResource: true,
|
|
|
|
...state,
|
|
|
|
|
|
|
|
isUploadingResource: true,
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
let resource = undefined;
|
|
|
|
let resource = undefined;
|
|
|
@ -191,9 +195,11 @@ const MemoEditor: React.FC = () => {
|
|
|
|
toastHelper.error(error.response.data.message);
|
|
|
|
toastHelper.error(error.response.data.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
isUploadingResource: false,
|
|
|
|
...state,
|
|
|
|
|
|
|
|
isUploadingResource: false,
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return resource;
|
|
|
|
return resource;
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -232,10 +238,12 @@ const MemoEditor: React.FC = () => {
|
|
|
|
toastHelper.error(error.response.data.message);
|
|
|
|
toastHelper.error(error.response.data.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
fullscreen: false,
|
|
|
|
...state,
|
|
|
|
resourceList: [],
|
|
|
|
fullscreen: false,
|
|
|
|
|
|
|
|
resourceList: [],
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setEditorContentCache("");
|
|
|
|
setEditorContentCache("");
|
|
|
|
storage.remove(["editingMemoVisibilityCache"]);
|
|
|
|
storage.remove(["editingMemoVisibilityCache"]);
|
|
|
@ -314,9 +322,11 @@ const MemoEditor: React.FC = () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
resourceList: [...state.resourceList, ...resourceList],
|
|
|
|
...state,
|
|
|
|
|
|
|
|
resourceList: [...state.resourceList, ...resourceList],
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
document.body.removeChild(inputEl);
|
|
|
|
document.body.removeChild(inputEl);
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -324,9 +334,11 @@ const MemoEditor: React.FC = () => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleFullscreenBtnClick = () => {
|
|
|
|
const handleFullscreenBtnClick = () => {
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
fullscreen: !state.fullscreen,
|
|
|
|
...state,
|
|
|
|
|
|
|
|
fullscreen: !state.fullscreen,
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -354,9 +366,11 @@ const MemoEditor: React.FC = () => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleDeleteResource = async (resourceId: ResourceId) => {
|
|
|
|
const handleDeleteResource = async (resourceId: ResourceId) => {
|
|
|
|
setState({
|
|
|
|
setState((state) => {
|
|
|
|
...state,
|
|
|
|
return {
|
|
|
|
resourceList: state.resourceList.filter((resource) => resource.id !== resourceId),
|
|
|
|
...state,
|
|
|
|
|
|
|
|
resourceList: state.resourceList.filter((resource) => resource.id !== resourceId),
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (editorState.editMemoId) {
|
|
|
|
if (editorState.editMemoId) {
|
|
|
@ -372,17 +386,10 @@ const MemoEditor: React.FC = () => {
|
|
|
|
|
|
|
|
|
|
|
|
const handleEditorFocus = () => {
|
|
|
|
const handleEditorFocus = () => {
|
|
|
|
editorRef.current?.focus();
|
|
|
|
editorRef.current?.focus();
|
|
|
|
setState({
|
|
|
|
|
|
|
|
...state,
|
|
|
|
|
|
|
|
isEditorFocused: true,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleEditorBlur = () => {
|
|
|
|
const handleEditorBlur = () => {
|
|
|
|
setState({
|
|
|
|
// do nth
|
|
|
|
...state,
|
|
|
|
|
|
|
|
isEditorFocused: false,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const isEditing = Boolean(editorState.editMemoId && editorState.editMemoId !== UNKNOWN_ID);
|
|
|
|
const isEditing = Boolean(editorState.editMemoId && editorState.editMemoId !== UNKNOWN_ID);
|
|
|
@ -409,12 +416,6 @@ const MemoEditor: React.FC = () => {
|
|
|
|
onBlur={handleEditorBlur}
|
|
|
|
onBlur={handleEditorBlur}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<div className="editor-header-container">
|
|
|
|
<div className="editor-header-container">
|
|
|
|
<Selector
|
|
|
|
|
|
|
|
className={`visibility-selector ${state.isEditorFocused || allowSave ? "" : "!hidden"}`}
|
|
|
|
|
|
|
|
value={editorState.memoVisibility}
|
|
|
|
|
|
|
|
dataSource={memoVisibilityOptionSelectorItems}
|
|
|
|
|
|
|
|
handleValueChanged={handleMemoVisibilityOptionChanged}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div className={`editing-container ${isEditing ? "" : "!hidden"}`}>
|
|
|
|
<div className={`editing-container ${isEditing ? "" : "!hidden"}`}>
|
|
|
|
<span className="tip-text">{t("editor.editing")}</span>
|
|
|
|
<span className="tip-text">{t("editor.editing")}</span>
|
|
|
|
<button className="cancel-btn" onClick={handleCancelEdit}>
|
|
|
|
<button className="cancel-btn" onClick={handleCancelEdit}>
|
|
|
@ -465,12 +466,6 @@ const MemoEditor: React.FC = () => {
|
|
|
|
onShouldShowEmojiPickerChange={handleChangeShouldShowEmojiPicker}
|
|
|
|
onShouldShowEmojiPickerChange={handleChangeShouldShowEmojiPicker}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="btns-container">
|
|
|
|
|
|
|
|
<button className="action-btn confirm-btn" disabled={!allowSave || state.isUploadingResource} onClick={handleSaveBtnClick}>
|
|
|
|
|
|
|
|
{t("editor.save")}
|
|
|
|
|
|
|
|
<img className="icon-img" src="/logo.webp" />
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{state.resourceList.length > 0 && (
|
|
|
|
{state.resourceList.length > 0 && (
|
|
|
|
<div className="resource-list-wrapper">
|
|
|
|
<div className="resource-list-wrapper">
|
|
|
@ -485,6 +480,20 @@ const MemoEditor: React.FC = () => {
|
|
|
|
})}
|
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
|
|
|
|
<div className="editor-footer-container">
|
|
|
|
|
|
|
|
<Selector
|
|
|
|
|
|
|
|
className={`visibility-selector`}
|
|
|
|
|
|
|
|
value={editorState.memoVisibility}
|
|
|
|
|
|
|
|
dataSource={memoVisibilityOptionSelectorItems}
|
|
|
|
|
|
|
|
handleValueChanged={handleMemoVisibilityOptionChanged}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div className="buttons-container">
|
|
|
|
|
|
|
|
<button className="action-btn confirm-btn" disabled={!allowSave || state.isUploadingResource} onClick={handleSaveBtnClick}>
|
|
|
|
|
|
|
|
{t("editor.save")}
|
|
|
|
|
|
|
|
<img className="icon-img w-4 h-auto" src="/logo.webp" />
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
};
|
|
|
|
};
|
|
|
|