Skip to content

Commit

Permalink
Merge pull request #2742 from daostack/CW-instant-chat-message-edit
Browse files Browse the repository at this point in the history
Instant chat message edit
  • Loading branch information
MeyerPV authored Oct 11, 2024
2 parents ade8ab8 + 94de9b9 commit 983a905
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 10 deletions.
35 changes: 30 additions & 5 deletions src/shared/components/Chat/ChatMessage/ChatMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const ChatMessage = ({
}>();
const [isEditMode, setEditMode] = useState(false);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [parsedMessage, setParsedMessage] = useState(discussionMessage.parsedText);
const [isMessageEditLoading, setIsMessageEditLoading] = useState(false);
const isTabletView = useIsTabletView();
const isUserDiscussionMessage =
Expand All @@ -133,6 +134,9 @@ const ChatMessage = ({
: null;
const isNotCurrentUserMessage =
!isUserDiscussionMessage || userId !== discussionMessageUserId;
const initialEditedAtDate = new Date(
(discussionMessage.editedAt?.seconds ?? 0) * 1000,
);

const [replyMessageText, setReplyMessageText] = useState<
(string | JSX.Element)[]
Expand Down Expand Up @@ -177,9 +181,7 @@ const ChatMessage = ({
]);

const createdAtDate = new Date(discussionMessage.createdAt.seconds * 1000);
const editedAtDate = new Date(
(discussionMessage.editedAt?.seconds ?? 0) * 1000,
);
const [editedAtDate, setEditedAtDate] = useState(initialEditedAtDate);

const handleUserClick = () => {
if (onUserClick && discussionMessageUserId && !isBotMessage) {
Expand Down Expand Up @@ -258,6 +260,8 @@ const ChatMessage = ({
handleEditModeClose();
} else {
notify("Something went wrong");
setParsedMessage(discussionMessage.parsedText);
setEditedAtDate(initialEditedAtDate);
}
},
}),
Expand All @@ -276,17 +280,38 @@ const ChatMessage = ({
handleEditModeClose();
} catch (err) {
notify("Something went wrong");
setParsedMessage(discussionMessage.parsedText);
setEditedAtDate(initialEditedAtDate);
} finally {
setIsMessageEditLoading(false);
}
};

const updateMessage = (message: TextEditorValue) => {
const updateMessage = async (message: TextEditorValue) => {
try {
if (chatType === ChatType.ChatMessages) {
updateChatMessage(message);
} else {
updateDiscussionMessage(message);
}
const parsedText = await getTextFromTextEditorString({
userId,
ownerId: discussionMessageUserId,
textEditorString: JSON.stringify(message),
users,
commonId: discussionMessage.commonId,
directParent,
onUserClick,
onFeedItemClick,
onInternalLinkClick,
});

setParsedMessage(parsedText);
setEditedAtDate(new Date());
handleEditModeClose();
} catch(err) {
setIsMessageEditLoading(false);
}
};
updateMessageRef.current = {
updateMessage,
Expand Down Expand Up @@ -520,7 +545,7 @@ const ChatMessage = ({
<ChatMessageLinkify
onInternalLinkClick={handleInternalLinkClick}
>
{discussionMessage.parsedText.map((text) => text)}
{(parsedMessage ?? []).map((text) => text)}
</ChatMessageLinkify>
{!isSystemMessage && (
<Time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

.editedTimeWrapper {
font-size: $xxsmall;
min-width: 5rem;
}

.creationTimeWrapper {
Expand Down
15 changes: 13 additions & 2 deletions src/shared/components/Chat/EditMessageInput/EditMessageInput.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from "react";
import React, { useEffect, useMemo, useState, useRef, useLayoutEffect } from "react";
import classNames from "classnames";
import { useCommonMembers } from "@/pages/OldCommon/hooks";
import { Loader } from "@/shared/components";
Expand All @@ -13,6 +13,7 @@ import {
import { parseStringToTextEditorValue } from "@/shared/ui-kit/TextEditor/utils";
import { emptyFunction } from "@/shared/utils";
import styles from "./EditMessageInput.module.scss";
import { BaseTextEditorHandles } from "@/shared/ui-kit/TextEditor/BaseTextEditor";

interface Props {
discussionMessage: DiscussionMessage;
Expand All @@ -29,13 +30,20 @@ export default function EditMessageInput({
isLoading,
updateMessage,
}: Props) {
const textInputRef = useRef<BaseTextEditorHandles>(null);
const editorRef = useRef<HTMLElement>(null);
const inputContainerRef = useRef<HTMLDivElement>(null);
const [message, setMessage] = useState(() =>
parseStringToTextEditorValue(discussionMessage.text),
);
const { data: commonMembers, fetchCommonMembers } = useCommonMembers({
commonId: discussionMessage.commonId,
});

useLayoutEffect(() => {
textInputRef?.current?.focus?.();
},[discussionMessage]);

const handleMessageUpdate = () => {
updateMessage(message);
};
Expand All @@ -53,8 +61,9 @@ export default function EditMessageInput({
}, [commonMember, commonMembers]);

return (
<div className={styles.container}>
<div ref={inputContainerRef} className={styles.container}>
<BaseTextEditor
ref={textInputRef}
className={styles.input}
emojiPickerContainerClassName={styles.pickerContainer}
emojiContainerClassName={styles.emojiContainer}
Expand All @@ -64,6 +73,8 @@ export default function EditMessageInput({
shouldReinitializeEditor={false}
onClearFinished={emptyFunction}
size={TextEditorSize.Auto}
inputContainerRef={inputContainerRef}
editorRef={editorRef}
/>

<div className={styles.buttonContainer}>
Expand Down
1 change: 1 addition & 0 deletions src/shared/ui-kit/TextEditor/BaseTextEditor.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
position: relative;
width: 100%;
height: 100%;
scroll-behavior: smooth;
}
26 changes: 23 additions & 3 deletions src/shared/ui-kit/TextEditor/BaseTextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,18 @@ const BaseTextEditor = forwardRef<BaseTextEditorHandles, TextEditorProps>((props
useImperativeHandle(ref, () => ({
focus: () => {
if (editorRef) {
const end = EditorSlate.end(editor, []);

// Move the selection to the end
Transforms.select(editor, end);

// Focus the editor DOM node
const editorEl = ReactEditor.toDOMNode(editor, editor);
editorEl.focus();
}

// Ensure the editor itself is focused programmatically
ReactEditor.focus(editor);
}
},
clear: () => {
clearInput();
Expand Down Expand Up @@ -265,7 +274,8 @@ const BaseTextEditor = forwardRef<BaseTextEditorHandles, TextEditorProps>((props
event.preventDefault();
setShouldFocusTarget(true);
} else {
onKeyDown && onKeyDown(event);
// event.stopPropagation();
onKeyDown && onKeyDown(event); // Call any custom onKeyDown handler
if (event.key === KeyboardKeys.Enter && !isMobile()) {
onToggleIsMessageSent();
}
Expand Down Expand Up @@ -349,6 +359,16 @@ const BaseTextEditor = forwardRef<BaseTextEditorHandles, TextEditorProps>((props
[onChange, value, handleMentionSelectionChange],
);

const customScrollSelectionIntoView = ( ) => {
if (inputContainerRef && 'current' in inputContainerRef && inputContainerRef?.current) {
inputContainerRef.current?.scrollIntoView({
behavior: "smooth",
block: "end",
inline: "nearest",
});
}
}

return (
<div ref={inputContainerRef} className={styles.container}>
<Slate editor={editor} initialValue={value} onChange={handleOnChange}>
Expand All @@ -367,7 +387,7 @@ const BaseTextEditor = forwardRef<BaseTextEditorHandles, TextEditorProps>((props
disabled={disabled}
onBlur={onBlur}
onKeyDown={handleKeyDown}
scrollSelectionIntoView={scrollSelectionIntoView}
scrollSelectionIntoView={scrollSelectionIntoView ?? customScrollSelectionIntoView}
elementStyles={elementStyles}
/>
<EmojiPicker
Expand Down

0 comments on commit 983a905

Please sign in to comment.