Edit last message with up arrow key (#774)

This commit is contained in:
Ajay Bura 2022-08-21 19:41:48 +05:30 committed by GitHub
parent 80aa55b706
commit b3bff6b43f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 10 deletions

View file

@ -714,9 +714,9 @@ function getEditedBody(editedMEvent) {
} }
function Message({ 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 roomId = mEvent.getRoomId();
const { editedTimeline, reactionTimeline } = roomTimeline ?? {}; const { editedTimeline, reactionTimeline } = roomTimeline ?? {};
@ -731,7 +731,7 @@ function Message({
const avatarSrc = mEvent.sender?.getAvatarUrl(initMatrix.matrixClient.baseUrl, 36, 36, 'crop') ?? null; const avatarSrc = mEvent.sender?.getAvatarUrl(initMatrix.matrixClient.baseUrl, 36, 36, 'crop') ?? null;
const edit = useCallback(() => { const edit = useCallback(() => {
setIsEditing(true); setEdit(eventId);
}, []); }, []);
const reply = useCallback(() => { const reply = useCallback(() => {
replyTo(senderId, mEvent.getId(), body); replyTo(senderId, mEvent.getId(), body);
@ -788,7 +788,7 @@ function Message({
eventId={mEvent.replyEventId} eventId={mEvent.replyEventId}
/> />
)} )}
{!isEditing && ( {!isEdit && (
<MessageBody <MessageBody
senderName={username} senderName={username}
isCustomHTML={isCustomHTML} isCustomHTML={isCustomHTML}
@ -797,22 +797,22 @@ function Message({
isEdited={isEdited} isEdited={isEdited}
/> />
)} )}
{isEditing && ( {isEdit && (
<MessageEdit <MessageEdit
body={body} body={body}
onSave={(newBody) => { onSave={(newBody) => {
if (newBody !== body) { if (newBody !== body) {
initMatrix.roomsInput.sendEditedMessage(roomId, mEvent, newBody); initMatrix.roomsInput.sendEditedMessage(roomId, mEvent, newBody);
} }
setIsEditing(false); cancelEdit();
}} }}
onCancel={() => setIsEditing(false)} onCancel={cancelEdit}
/> />
)} )}
{haveReactions && ( {haveReactions && (
<MessageReactionGroup roomTimeline={roomTimeline} mEvent={mEvent} /> <MessageReactionGroup roomTimeline={roomTimeline} mEvent={mEvent} />
)} )}
{roomTimeline && !isEditing && ( {roomTimeline && !isEdit && (
<MessageOptions <MessageOptions
roomTimeline={roomTimeline} roomTimeline={roomTimeline}
mEvent={mEvent} mEvent={mEvent}
@ -829,6 +829,9 @@ Message.defaultProps = {
focus: false, focus: false,
roomTimeline: null, roomTimeline: null,
fullTime: false, fullTime: false,
isEdit: false,
setEdit: null,
cancelEdit: null,
}; };
Message.propTypes = { Message.propTypes = {
mEvent: PropTypes.shape({}).isRequired, mEvent: PropTypes.shape({}).isRequired,
@ -836,6 +839,9 @@ Message.propTypes = {
roomTimeline: PropTypes.shape({}), roomTimeline: PropTypes.shape({}),
focus: PropTypes.bool, focus: PropTypes.bool,
fullTime: PropTypes.bool, fullTime: PropTypes.bool,
isEdit: PropTypes.bool,
setEdit: PropTypes.func,
cancelEdit: PropTypes.func,
}; };
export { Message, MessageReply, PlaceholderMessage }; export { Message, MessageReply, PlaceholderMessage };

View file

@ -229,6 +229,8 @@
padding: var(--sp-extra-tight) 0; padding: var(--sp-extra-tight) 0;
&-btns button { &-btns button {
margin: var(--sp-tight) 0 0 0; margin: var(--sp-tight) 0 0 0;
padding: var(--sp-ultra-tight) var(--sp-tight);
min-width: 0;
@include dir.side(margin, 0, var(--sp-tight)); @include dir.side(margin, 0, var(--sp-tight));
} }
} }

View file

@ -118,7 +118,15 @@ function handleOnClickCapture(e) {
} }
} }
function renderEvent(roomTimeline, mEvent, prevMEvent, isFocus = false) { function renderEvent(
roomTimeline,
mEvent,
prevMEvent,
isFocus,
isEdit,
setEdit,
cancelEdit,
) {
const isBodyOnly = (prevMEvent !== null const isBodyOnly = (prevMEvent !== null
&& prevMEvent.getSender() === mEvent.getSender() && prevMEvent.getSender() === mEvent.getSender()
&& prevMEvent.getType() !== 'm.room.member' && prevMEvent.getType() !== 'm.room.member'
@ -147,6 +155,9 @@ function renderEvent(roomTimeline, mEvent, prevMEvent, isFocus = false) {
roomTimeline={roomTimeline} roomTimeline={roomTimeline}
focus={isFocus} focus={isFocus}
fullTime={false} fullTime={false}
isEdit={isEdit}
setEdit={setEdit}
cancelEdit={cancelEdit}
/> />
); );
} }
@ -386,6 +397,8 @@ function RoomViewContent({ eventId, roomTimeline }) {
const timelineSVRef = useRef(null); const timelineSVRef = useRef(null);
const timelineScrollRef = useRef(null); const timelineScrollRef = useRef(null);
const eventLimitRef = useRef(null); const eventLimitRef = useRef(null);
const [editEventId, setEditEventId] = useState(null);
const cancelEdit = () => setEditEventId(null);
const readUptoEvtStore = useStore(roomTimeline); const readUptoEvtStore = useStore(roomTimeline);
const [onLimitUpdate, forceUpdateLimit] = useForceUpdate(); const [onLimitUpdate, forceUpdateLimit] = useForceUpdate();
@ -470,6 +483,42 @@ function RoomViewContent({ eventId, roomTimeline }) {
} }
}, [newEvent]); }, [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 handleTimelineScroll = (event) => {
const timelineScroll = timelineScrollRef.current; const timelineScroll = timelineScrollRef.current;
if (!event.target) return; if (!event.target) return;
@ -535,7 +584,15 @@ function RoomViewContent({ eventId, roomTimeline }) {
const isFocus = focusId === mEvent.getId(); const isFocus = focusId === mEvent.getId();
if (isFocus) jumpToItemIndex = itemCountIndex; 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; itemCountIndex += 1;
} }
if (roomTimeline.canPaginateForward() || limit.length < timeline.length) { if (roomTimeline.canPaginateForward() || limit.length < timeline.length) {