From b3bff6b43ff964a88e185fb50ddb4dc74ac93cfa Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sun, 21 Aug 2022 19:41:48 +0530 Subject: [PATCH] Edit last message with up arrow key (#774) --- src/app/molecules/message/Message.jsx | 22 +++++--- src/app/molecules/message/Message.scss | 2 + src/app/organisms/room/RoomViewContent.jsx | 61 +++++++++++++++++++++- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/app/molecules/message/Message.jsx b/src/app/molecules/message/Message.jsx index 42344d7..7d3ee63 100644 --- a/src/app/molecules/message/Message.jsx +++ b/src/app/molecules/message/Message.jsx @@ -714,9 +714,9 @@ function getEditedBody(editedMEvent) { } function Message({ - mEvent, isBodyOnly, roomTimeline, focus, fullTime, + mEvent, isBodyOnly, roomTimeline, + focus, fullTime, isEdit, setEdit, cancelEdit, }) { - const [isEditing, setIsEditing] = useState(false); const roomId = mEvent.getRoomId(); const { editedTimeline, reactionTimeline } = roomTimeline ?? {}; @@ -731,7 +731,7 @@ function Message({ const avatarSrc = mEvent.sender?.getAvatarUrl(initMatrix.matrixClient.baseUrl, 36, 36, 'crop') ?? null; const edit = useCallback(() => { - setIsEditing(true); + setEdit(eventId); }, []); const reply = useCallback(() => { replyTo(senderId, mEvent.getId(), body); @@ -788,7 +788,7 @@ function Message({ eventId={mEvent.replyEventId} /> )} - {!isEditing && ( + {!isEdit && ( )} - {isEditing && ( + {isEdit && ( { if (newBody !== body) { initMatrix.roomsInput.sendEditedMessage(roomId, mEvent, newBody); } - setIsEditing(false); + cancelEdit(); }} - onCancel={() => setIsEditing(false)} + onCancel={cancelEdit} /> )} {haveReactions && ( )} - {roomTimeline && !isEditing && ( + {roomTimeline && !isEdit && ( ); } @@ -386,6 +397,8 @@ function RoomViewContent({ eventId, roomTimeline }) { const timelineSVRef = useRef(null); const timelineScrollRef = useRef(null); const eventLimitRef = useRef(null); + const [editEventId, setEditEventId] = useState(null); + const cancelEdit = () => setEditEventId(null); const readUptoEvtStore = useStore(roomTimeline); const [onLimitUpdate, forceUpdateLimit] = useForceUpdate(); @@ -470,6 +483,42 @@ function RoomViewContent({ eventId, roomTimeline }) { } }, [newEvent]); + const listenKeyboard = useCallback((event) => { + if (event.ctrlKey || event.altKey || event.metaKey) return; + if (event.key !== 'ArrowUp') return; + if (navigation.isRawModalVisible) return; + + if (document.activeElement.id !== 'message-textarea') return; + if (document.activeElement.value !== '') return; + + const { + timeline: tl, activeTimeline, liveTimeline, matrixClient: mx, + } = roomTimeline; + const limit = eventLimitRef.current; + if (activeTimeline !== liveTimeline) return; + if (tl.length > limit.length) return; + + const mTypes = ['m.text']; + for (let i = tl.length - 1; i >= 0; i -= 1) { + const mE = tl[i]; + if ( + mE.getSender() === mx.getUserId() + && mE.getType() === 'm.room.message' + && mTypes.includes(mE.getContent()?.msgtype) + ) { + setEditEventId(mE.getId()); + return; + } + } + }, [roomTimeline]); + + useEffect(() => { + document.body.addEventListener('keydown', listenKeyboard); + return () => { + document.body.removeEventListener('keydown', listenKeyboard); + }; + }, [listenKeyboard]); + const handleTimelineScroll = (event) => { const timelineScroll = timelineScrollRef.current; if (!event.target) return; @@ -535,7 +584,15 @@ function RoomViewContent({ eventId, roomTimeline }) { const isFocus = focusId === mEvent.getId(); if (isFocus) jumpToItemIndex = itemCountIndex; - tl.push(renderEvent(roomTimeline, mEvent, isNewEvent ? null : prevMEvent, isFocus)); + tl.push(renderEvent( + roomTimeline, + mEvent, + isNewEvent ? null : prevMEvent, + isFocus, + editEventId === mEvent.getId(), + setEditEventId, + cancelEdit, + )); itemCountIndex += 1; } if (roomTimeline.canPaginateForward() || limit.length < timeline.length) {