From fab9ba62ccd1bfa514a15a94438c003d8f7b24bc Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 29 Jul 2024 17:31:49 -0700 Subject: [PATCH] feat(MessageItem): better editing experience --- .../MessageSequencer/AddMessageBox.tsx | 6 ++- .../MessageSequencer/MessageItem.tsx | 53 +++++++++++++------ .../MessageSequencer/MessageList.tsx | 2 +- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/popup/Accordions/MessageSequencer/AddMessageBox.tsx b/src/popup/Accordions/MessageSequencer/AddMessageBox.tsx index 1914b23..47b6545 100644 --- a/src/popup/Accordions/MessageSequencer/AddMessageBox.tsx +++ b/src/popup/Accordions/MessageSequencer/AddMessageBox.tsx @@ -61,11 +61,13 @@ export const AddMessageBox = () => { label='Message Content' placeholder='Hello, how are you?' onKeyDown={(e) => { + if (!appData.addMessageText.trim()) return; + // Allow pressing Enter + Shift to create new lines. - if (!loading && e.key === 'Enter' && !e.shiftKey && appData.addMessageText.trim()) { + if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); - handleAddMessage(appData.addMessageText); + if (!loading) handleAddMessage(appData.addMessageText); } }} value={inputText} diff --git a/src/popup/Accordions/MessageSequencer/MessageItem.tsx b/src/popup/Accordions/MessageSequencer/MessageItem.tsx index f5fde38..65b26fa 100644 --- a/src/popup/Accordions/MessageSequencer/MessageItem.tsx +++ b/src/popup/Accordions/MessageSequencer/MessageItem.tsx @@ -1,6 +1,7 @@ -import { IconButton, List, ListItem, ListItemProps, ListItemText, TextField, Tooltip, styled } from '@mui/material'; -import React, { useEffect, useState, useContext, createContext } from 'react'; +import { IconButton, ListItem, ListItemProps, ListItemText, Tooltip, styled } from '@mui/material'; +import { useState, useContext } from 'react'; import DeleteIcon from '@mui/icons-material/Delete'; +import EditOffIcon from '@mui/icons-material/EditOff'; import { messageStore } from '../../../storage'; import { sanitize } from '../../../utils'; import { MessageSequenceContext } from '../../context/MessageSequenceProvider'; @@ -24,7 +25,7 @@ export const MessageItem = ({ message, ...props }: { message: Message } & ListIt /** * Optionally pass a replacement {@link Message} to delete & replace. */ - const handleDelete = async (updated?: Partial) => { + const handleUpdate = async (updated?: Partial) => { const index = messages.findIndex(({ id }) => id === message.id); if (index === -1) return; @@ -32,47 +33,67 @@ export const MessageItem = ({ message, ...props }: { message: Message } & ListIt const clone = [...messages]; + // Replace the current message item with the updated one if (updated) clone.splice(index, 1, { ...clone[index], ...updated }); + // Or remove the item entirely else clone.splice(index, 1); + // Rewrite the entire message list await messageStore.write(clone); setLoading(false); }; return ( - + { const editedText = (e.target as HTMLSpanElement).textContent || ''; + if (!editing || !editedText.trim()) return; - if (editing && e.key === 'Enter' && !e.shiftKey && editedText.trim()) { + // Enter + Shift for new lines + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); setEditing(false); - handleDelete({ content: sanitize(editedText) }); + handleUpdate({ content: sanitize(editedText) }); } }} contentEditable={editing} // Unable to double-click to edit during loading - onDoubleClick={() => !loading && setEditing(true)} + onDoubleClick={() => { + if (!loading) { + setEditing(true); + } + }} + ref={(elem) => { + if (editing) (elem as HTMLDivElement)?.focus(); + }} sx={{ flex: 1, wordWrap: 'break-word', userSelect: 'none', + whiteSpace: 'pre-wrap', }} /> - + - handleDelete()}> - - + {editing ? ( + setEditing(false)}> + + + ) : ( + handleUpdate()}> + + + )} diff --git a/src/popup/Accordions/MessageSequencer/MessageList.tsx b/src/popup/Accordions/MessageSequencer/MessageList.tsx index f3b7beb..2085c28 100644 --- a/src/popup/Accordions/MessageSequencer/MessageList.tsx +++ b/src/popup/Accordions/MessageSequencer/MessageList.tsx @@ -47,7 +47,7 @@ export const MessageList = () => { handleRearrange(+e.dataTransfer.getData('text/plain'), +e.currentTarget.dataset.index!); }} - draggable={!loading} + draggable={!loading && messages.length > 1} key={`message-${message.id}`} message={message} // Display divider only for the final item