feat: message draft
This commit is contained in:
@@ -12,6 +12,8 @@ const initialState = {
|
||||
fileListView: Views.grid,
|
||||
uploadFiles: {},
|
||||
selectMessages: {},
|
||||
draftMarkdown: {},
|
||||
draftMixedText: {},
|
||||
};
|
||||
const uiSlice = createSlice({
|
||||
name: "ui",
|
||||
@@ -35,6 +37,14 @@ const uiSlice = createSlice({
|
||||
updateFileListView(state, action) {
|
||||
state.fileListView = action.payload;
|
||||
},
|
||||
updateDraftMarkdown(state, action) {
|
||||
const { key, value } = action.payload;
|
||||
state.draftMarkdown[key] = value;
|
||||
},
|
||||
updateDraftMixedText(state, action) {
|
||||
const { key, value } = action.payload;
|
||||
state.draftMixedText[key] = value;
|
||||
},
|
||||
updateUserGuide(state, action) {
|
||||
const obj = action.payload || {};
|
||||
Object.keys(obj).forEach((key) => {
|
||||
@@ -146,5 +156,7 @@ export const {
|
||||
updateUploadFiles,
|
||||
updateSelectMessages,
|
||||
updateUserGuide,
|
||||
updateDraftMarkdown,
|
||||
updateDraftMixedText,
|
||||
} = uiSlice.actions;
|
||||
export default uiSlice.reducer;
|
||||
|
||||
@@ -11,6 +11,8 @@ import useUploadFile from "../../hook/useUploadFile";
|
||||
import Button from "../../component/styled/Button";
|
||||
|
||||
function MarkdownEditor({
|
||||
updateDraft = null,
|
||||
initialValue = "",
|
||||
height = "50vh",
|
||||
placeholder,
|
||||
sendMarkdown,
|
||||
@@ -33,6 +35,11 @@ function MarkdownEditor({
|
||||
return () => {
|
||||
if (editor) {
|
||||
const editorInstance = editor.getInstance();
|
||||
const md = editorInstance.getMarkdown();
|
||||
if (updateDraft) {
|
||||
updateDraft(md);
|
||||
}
|
||||
console.log("mmmm", md);
|
||||
editorInstance.destroy();
|
||||
}
|
||||
};
|
||||
@@ -49,6 +56,7 @@ function MarkdownEditor({
|
||||
return (
|
||||
<StyledWrapper className="input">
|
||||
<Editor
|
||||
initialValue={initialValue}
|
||||
plugins={[codeSyntaxHighlight]}
|
||||
placeholder={placeholder}
|
||||
// onChange={handleChange}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
createPlugins,
|
||||
ELEMENT_PARAGRAPH,
|
||||
getPlateEditorRef,
|
||||
|
||||
// usePlateEditorRef,
|
||||
// ELEMENT_IMAGE,
|
||||
MentionCombobox,
|
||||
@@ -37,8 +38,10 @@ let components = createPlateUI({
|
||||
// [ELEMENT_IMAGE]: ImageElement,
|
||||
// customize your components by plugin key
|
||||
});
|
||||
const initialValue = [{ type: ELEMENT_PARAGRAPH, children: [{ text: "" }] }];
|
||||
const initials = [{ type: ELEMENT_PARAGRAPH, children: [{ text: "" }] }];
|
||||
const Plugins = ({
|
||||
updateDraft = null,
|
||||
initialValue = initials,
|
||||
id = "",
|
||||
placeholder = "Write some markdown...",
|
||||
sendMessages,
|
||||
@@ -48,6 +51,7 @@ const Plugins = ({
|
||||
const enableMentions = members.length > 0;
|
||||
const filesRef = useRef([]);
|
||||
const contactData = useSelector((store) => store.contacts.byId);
|
||||
const [originalValue, setOriginalValue] = useState(initialValue);
|
||||
const [msgs, setMsgs] = useState([]);
|
||||
const [cmdKey, setCmdKey] = useState(false);
|
||||
const editableRef = useRef(null);
|
||||
@@ -78,6 +82,9 @@ const Plugins = ({
|
||||
};
|
||||
// window.addEventListener("paste")
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
updateDraft(originalValue);
|
||||
}, [originalValue]);
|
||||
|
||||
useKey(
|
||||
"Enter",
|
||||
@@ -147,6 +154,7 @@ const Plugins = ({
|
||||
|
||||
const handleChange = useCallback(
|
||||
async (val) => {
|
||||
setOriginalValue(val);
|
||||
console.log("tmps changed", val);
|
||||
const tmps = [];
|
||||
const getMixedText = (children) => {
|
||||
|
||||
@@ -17,6 +17,7 @@ import EmojiPicker from "./EmojiPicker";
|
||||
|
||||
import MarkdownEditor from "../MarkdownEditor";
|
||||
import MixedInput, { useMixedEditor } from "../MixedInput";
|
||||
import useDraft from "../../hook/useDraft";
|
||||
const Types = {
|
||||
channel: "#",
|
||||
user: "@",
|
||||
@@ -30,6 +31,7 @@ function Send({
|
||||
context = "channel",
|
||||
id = "",
|
||||
}) {
|
||||
const { getDraft, getUpdateDraft } = useDraft({ context, id });
|
||||
const editor = useMixedEditor(`${context}_${id}`);
|
||||
const [markdownEditor, setMarkdownEditor] = useState(null);
|
||||
const [markdownFullscreen, setMarkdownFullscreen] = useState(false);
|
||||
@@ -155,6 +157,8 @@ function Send({
|
||||
<EmojiPicker selectEmoji={insertEmoji} />
|
||||
{mode == Modes.text && (
|
||||
<MixedInput
|
||||
updateDraft={getUpdateDraft()}
|
||||
initialValue={getDraft()}
|
||||
members={members}
|
||||
id={`${context}_${id}`}
|
||||
placeholder={placeholder}
|
||||
@@ -171,6 +175,8 @@ function Send({
|
||||
/>
|
||||
{mode == Modes.markdown && (
|
||||
<MarkdownEditor
|
||||
updateDraft={getUpdateDraft("markdown")}
|
||||
initialValue={getDraft("markdown")}
|
||||
height={markdownFullscreen ? `calc(100vh - 168px)` : `30vh`}
|
||||
placeholder={placeholder}
|
||||
setEditorInstance={setMarkdownEditor}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// import React from 'react'
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { updateDraftMarkdown, updateDraftMixedText } from "../../app/slices/ui";
|
||||
export default function useDraft({ context = "", id = "" }) {
|
||||
const dispatch = useDispatch();
|
||||
const _key = `${context}_${id}`;
|
||||
const { draftMarkdown, draftMixedText } = useSelector((store) => {
|
||||
return {
|
||||
draftMarkdown: store.ui.draftMarkdown,
|
||||
draftMixedText: store.ui.draftMixedText,
|
||||
};
|
||||
});
|
||||
|
||||
const getUpdateDraft = (type = "mixed") => {
|
||||
const update = type == "mixed" ? updateDraftMixedText : updateDraftMarkdown;
|
||||
return (value) => {
|
||||
dispatch(update({ key: _key, value }));
|
||||
};
|
||||
};
|
||||
const getDraft = (type = "mixed") => {
|
||||
return type == "mixed" ? draftMixedText[_key] : draftMarkdown[_key];
|
||||
};
|
||||
return { getDraft, getUpdateDraft };
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import styled from "styled-components";
|
||||
import FavoritedMessage from "../../common/component/Message/FavoritedMessage";
|
||||
import IconSurprise from "../../assets/icons/emoji.suprise.svg";
|
||||
// import IconForward from "../../../assets/icons/forward.svg";
|
||||
import IconBookmark from "../../assets/icons/bookmark.svg";
|
||||
import IconRemove from "../../assets/icons/close.svg";
|
||||
import useFavMessage from "../../common/hook/useFavMessage";
|
||||
const Styled = styled.div`
|
||||
padding: 16px;
|
||||
@@ -58,8 +58,8 @@ const Styled = styled.div`
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
padding: 4px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-radius: 6px;
|
||||
@@ -68,10 +68,11 @@ const Styled = styled.div`
|
||||
background: none;
|
||||
border: none;
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
path {
|
||||
fill: #d92d20;
|
||||
fill: #667085;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +117,7 @@ export default function FavList({ cid = null, uid = null }) {
|
||||
<IconForward />
|
||||
</button> */}
|
||||
<button className="btn" data-id={id} onClick={handleRemove}>
|
||||
<IconBookmark />
|
||||
<IconRemove />
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user