From 3da1dfd3efab2478c637a7a608a83fd1a9e4dbbc Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Mon, 28 Sep 2026 17:54:27 -0400 Subject: [PATCH 1/5] feature: edit or delete your own chat messages for 10 minutes The message menu offers the author Edit Message and Delete Message on a line they sent from the website in the last ten minutes, in every room including direct conversations. Moderators keep their delete in group rooms, and nobody edits someone else's words. The window is checked when the menu opens rather than on a timer; a trigger left over from before the window closed goes away with a toast saying why. Editing happens in place: Enter saves, Esc cancels, Shift+Enter breaks the line, and the box counts down near the 2000 character cap like the composer. Only one editor is open across a list. An unchanged edit just closes, a failure keeps the editor open with a toast, and a closed window or a message that is gone closes it. The socket sends lobby:edit through the same request plumbing as a delete, applies the text on the ack, and listens for the room's `edited` event, which never creates a message and never revives a deleted one. A stale history snapshot keeps an edit it predates. Edited lines carry an "(edited)" marker with the edit time in a tooltip. Conversation badges now know which messages they counted, so a deleted direct message comes off the badge. --- components/chat/ChatInput.vue | 9 +- components/chat/ChatMessage.vue | 80 +++++- components/chat/ChatMessageActions.vue | 89 ++++-- components/chat/ChatMessageEditor.vue | 186 +++++++++++++ components/chat/ChatMessages.vue | 16 ++ composables/useChatTabSetup.ts | 14 +- composables/useIncomingDirectMessages.ts | 12 +- constants/chat.ts | 2 + i18n/locales/ar_SA.json | 9 + i18n/locales/da_DK.json | 9 + i18n/locales/de_DE.json | 9 + i18n/locales/en.json | 9 + i18n/locales/es_ES.json | 9 + i18n/locales/fr_FR.json | 9 + i18n/locales/it_IT.json | 9 + i18n/locales/ja_JP.json | 9 + i18n/locales/ko_KR.json | 9 + i18n/locales/pl_PL.json | 9 + i18n/locales/pt_BR.json | 9 + i18n/locales/ru_RU.json | 9 + i18n/locales/sv_SE.json | 9 + i18n/locales/tr_TR.json | 9 + i18n/locales/uk_UA.json | 9 + i18n/locales/zh_Hans.json | 9 + i18n/locales/zh_Hant.json | 9 + tests/components/ChatMessage.spec.ts | 255 +++++++++++++++++- tests/components/ChatMessageActions.spec.ts | 117 +++++++- tests/components/ChatMessages.spec.ts | 87 ++++++ .../useChatTabSetupDeletes.spec.ts | 86 ++++++ tests/utilities/chatErrors.spec.ts | 41 +++ tests/utilities/chatLobbyMessages.spec.ts | 109 ++++++++ tests/utilities/chatMessageActions.spec.ts | 113 +++++++- tests/web-sockets/SocketChatError.spec.ts | 230 ++++++++++++++++ utilities/chatErrors.ts | 26 +- utilities/chatLobbyMessages.ts | 91 ++++++- utilities/chatMessageActions.ts | 40 ++- web-sockets/Socket.ts | 113 ++++++-- 37 files changed, 1811 insertions(+), 58 deletions(-) create mode 100644 components/chat/ChatMessageEditor.vue create mode 100644 tests/components/ChatMessages.spec.ts diff --git a/components/chat/ChatInput.vue b/components/chat/ChatInput.vue index 0bc90492..9d1a78db 100644 --- a/components/chat/ChatInput.vue +++ b/components/chat/ChatInput.vue @@ -167,9 +167,10 @@ import { useForm } from "vee-validate"; import { toTypedSchema } from "~/utilities/vee-validate-zod"; import { chatEnterAction } from "~/utilities/chatInputKeys"; import { toastChatError } from "~/utilities/chatErrors"; -import { CHAT_MESSAGE_MAX_LENGTH } from "~/constants/chat"; - -const REMAINING_HINT_AT = 200; +import { + CHAT_MESSAGE_MAX_LENGTH, + CHAT_REMAINING_HINT_AT, +} from "~/constants/chat"; export interface ChatInputChannel { value: string; @@ -232,7 +233,7 @@ export default { return CHAT_MESSAGE_MAX_LENGTH - message.length; }, showRemaining(): boolean { - return this.remainingCharacters <= REMAINING_HINT_AT; + return this.remainingCharacters <= CHAT_REMAINING_HINT_AT; }, activeChannelValue() { return this.destination ?? this.channels[0]?.value; diff --git a/components/chat/ChatMessage.vue b/components/chat/ChatMessage.vue index d4ed9512..bf68bef1 100644 --- a/components/chat/ChatMessage.vue +++ b/components/chat/ChatMessage.vue @@ -3,6 +3,8 @@ import { dateLocale } from "~/utilities/dateLocale"; import TimeAgo from "~/components/TimeAgo.vue"; import PlayerDisplay from "~/components/PlayerDisplay.vue"; import ChatMessageActions from "~/components/chat/ChatMessageActions.vue"; +import ChatMessageEditor from "~/components/chat/ChatMessageEditor.vue"; +import FiveStackToolTip from "~/components/FiveStackToolTip.vue"; @@ -95,9 +125,11 @@ import ChatMessageActions from "~/components/chat/ChatMessageActions.vue"; + +