diff --git a/src/plugins/messageLogger/HistoryModal.tsx b/src/plugins/messageLogger/HistoryModal.tsx index 44128a0fcd..e50f73431e 100644 --- a/src/plugins/messageLogger/HistoryModal.tsx +++ b/src/plugins/messageLogger/HistoryModal.tsx @@ -32,9 +32,11 @@ export function openHistoryModal(message: any) { } export function HistoryModal({ modalProps, message }: { modalProps: ModalProps; message: any; }) { - const [currentTab, setCurrentTab] = useState(message.editHistory.length); - const timestamps = [message.firstEditTimestamp, ...message.editHistory.map(m => m.timestamp)]; - const contents = [...message.editHistory.map(m => m.content), message.content]; + const filteredEditHistory = message.editHistory.filter(edit => edit.attachmentsEdited === false); + + const [currentTab, setCurrentTab] = useState(filteredEditHistory.length); + const timestamps = [message.firstEditTimestamp, ...filteredEditHistory.map(m => m.timestamp)]; + const contents = [...filteredEditHistory.map(m => m.content), message.content]; return ( diff --git a/src/plugins/messageLogger/deleteStyleOverlay.css b/src/plugins/messageLogger/deleteStyleOverlay.css index 3da3fa998c..41ee5eb470 100644 --- a/src/plugins/messageLogger/deleteStyleOverlay.css +++ b/src/plugins/messageLogger/deleteStyleOverlay.css @@ -1,3 +1,7 @@ .messagelogger-deleted { + transition: 150ms background-color ease-in-out; +} + +.messagelogger-deleted:not(.messagelogger-highlight-bypass) { background-color: hsl(var(--red-430-hsl, 0 85% 61%) / 15%) !important; } \ No newline at end of file diff --git a/src/plugins/messageLogger/deleteStyleText.css b/src/plugins/messageLogger/deleteStyleText.css index e12261b704..2221ce3500 100644 --- a/src/plugins/messageLogger/deleteStyleText.css +++ b/src/plugins/messageLogger/deleteStyleText.css @@ -1,4 +1,4 @@ -.messagelogger-deleted { +.messagelogger-deleted:not(.messagelogger-highlight-bypass) { --text-default: var(--status-danger, #f04747); --interactive-icon-default: var(--status-danger, #f04747); --text-muted: var(--status-danger, #f04747); diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx index 67e88a8fad..efde9e6637 100644 --- a/src/plugins/messageLogger/index.tsx +++ b/src/plugins/messageLogger/index.tsx @@ -38,7 +38,7 @@ import { openHistoryModal } from "./HistoryModal"; interface MLMessage extends Message { deleted?: boolean; - editHistory?: { timestamp: Date; content: string; }[]; + editHistory?: { timestamp: Date; content: string; attachmentsEdited: boolean; }[]; firstEditTimestamp?: Date; } @@ -58,12 +58,14 @@ const REMOVE_HISTORY_ID = "ml-remove-history"; const TOGGLE_DELETE_STYLE_ID = "ml-toggle-style"; const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) => { const { message } = props; - const { deleted, editHistory, id, channel_id } = message; + const { deleted, editHistory, attachments, id, channel_id } = message; - if (!deleted && !editHistory?.length) return; + const hasDeletedAttachments = attachments.some(a => a.deleted); + + if (!deleted && !hasDeletedAttachments && !editHistory?.length) return; toggle: { - if (!deleted) break toggle; + if (!deleted && !hasDeletedAttachments) break toggle; const domElement = document.getElementById(`chat-messages-${channel_id}-${id}`); if (!domElement) break toggle; @@ -73,7 +75,17 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = id={TOGGLE_DELETE_STYLE_ID} key={TOGGLE_DELETE_STYLE_ID} label="Toggle Deleted Highlight" - action={() => domElement.classList.toggle("messagelogger-deleted")} + action={() => { + const hasClass = domElement.classList.toggle("messagelogger-highlight-bypass"); + + for (const attachment of domElement.querySelectorAll(".messagelogger-deleted-attachment")) { + if (hasClass) { + attachment.classList.add("messagelogger-highlight-bypass"); + } else { + attachment.classList.remove("messagelogger-highlight-bypass"); + } + } + }} /> )); } @@ -93,7 +105,10 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = mlDeleted: true }); } else { - updateMessage(channel_id, id, { editHistory: [] }); + updateMessage(channel_id, id, { + editHistory: [], + attachments: message.attachments.filter(a => !a.deleted) + }); } }} /> @@ -121,7 +136,8 @@ const patchChannelContextMenu: NavContextMenuPatchCallback = (children, { channe }); else updateMessage(channel.id, msg.id, { - editHistory: [] + editHistory: [], + attachments: msg.attachments.filter((a: any) => !a.deleted) }); }); }} @@ -145,7 +161,7 @@ export default definePlugin({ name: "MessageLogger", description: "Temporarily logs deleted and edited messages.", tags: ["Chat", "Utility"], - authors: [Devs.rushii, Devs.Ven, Devs.AutumnVN, Devs.Nickyux, Devs.Kyuuhachi], + authors: [Devs.rushii, Devs.Ven, Devs.AutumnVN, Devs.Nickyux, Devs.Kyuuhachi, Devs.xNasuni], dependencies: ["MessageUpdaterAPI"], contextMenus: { @@ -156,8 +172,19 @@ export default definePlugin({ "gdm-context": patchChannelContextMenu }, + onMessageDeleteCallback({ channelId, id }) { + document.getElementById(`chat-messages-${channelId}-${id}`) + ?.querySelectorAll(".messagelogger-highlight-bypass") + .forEach(el => el.classList.remove("messagelogger-highlight-bypass")); + }, + start() { addDeleteStyle(); + FluxDispatcher.subscribe("MESSAGE_DELETE", this.onMessageDeleteCallback); + }, + + stop() { + FluxDispatcher.unsubscribe("MESSAGE_DELETE", this.onMessageDeleteCallback); }, renderEdits: ErrorBoundary.wrap(({ message: { id: messageId, channel_id: channelId } }: { message: Message; }) => { @@ -170,7 +197,7 @@ export default definePlugin({ return Settings.plugins.MessageLogger.inlineEdits && ( <> - {message.editHistory?.map((edit, idx) => ( + {message.editHistory?.map((edit, idx) => !edit.attachmentsEdited && (
{parseEditContent(edit.content, message)} !a.deleted)?.length || 0) !== (newMessage.attachments?.filter(a => !a.deleted)?.length || 0) }; }, @@ -307,6 +335,10 @@ export default definePlugin({ } }, + isMessageModified(oldMessage: any, newMessage: any) { + return oldMessage.content !== newMessage.content || oldMessage.attachments.length !== newMessage.attachments.length; + }, + EditMarker({ message, className, children, ...props }: any) { return ( - (($2.message.flags & 64) === 64 || $self.shouldIgnore($2.message, true)) ? m : - $2.message.edited_timestamp && $2.message.content !== m.content ? - m.set('editHistory',[...(m.editHistory || []), $self.makeEdit($2.message, m)]) : - m + match: /(MESSAGE_UPDATE:function\((\i)\).+?)(\i)=(\i)\.update\((\i)/, + replace: `$1$3=$4 + .update($5,m => + (($2.message.flags & 64) === 64 || $self.shouldIgnore($2.message, true)) ? m : + $2.message.edited_timestamp && $self.isMessageModified(m, $2.message) ? (() => { + if (m.attachments && m.attachments.length > 0) { + const newAttachmentIds = new Set($2.message.attachments.map(a => a.id)); + const updatedAttachments = m.attachments.map(a => + newAttachmentIds.has(a.id) ? a : { ...a, deleted: true } + ); + $2.message.attachments = updatedAttachments; + $3 = $3.update(m.id, m => m.set('attachments', updatedAttachments)); + } + return m.set('editHistory',[...(m.editHistory || []), $self.makeEdit($2.message, m)]); + })() + : m ) - .update($3 - ` + .update($5` }, { // fix up key (edit last message) attempting to edit a deleted message @@ -442,7 +481,7 @@ export default definePlugin({ // Preserve deleted attribute on attachments match: /(\((\i)\){return null==\2\.attachments.+?)spoiler:/, replace: - "$1deleted: arguments[0]?.deleted," + + "$1deleted: arguments[0]?.deleted || e?.deleted," + "spoiler:" } ] @@ -453,8 +492,8 @@ export default definePlugin({ find: "#{intl::REMOVE_ATTACHMENT_TOOLTIP_TEXT}", replacement: [ { - match: /\.SPOILER,(?=\[\i\.\i\]:)/, - replace: '$&"messagelogger-deleted-attachment":arguments[0]?.item?.originalItem?.deleted,' + match: /item:(\i),message:\i,getObscureReason:.+?\.SPOILER,(?=\[\i\.\i\]:)/, + replace: '$&"messagelogger-deleted-attachment":$1?.originalItem?.deleted,"messagelogger-deleted-attachment-overlay":$1?.originalItem?.deleted,' } ] }, diff --git a/src/plugins/messageLogger/messageLogger.css b/src/plugins/messageLogger/messageLogger.css index 652fbc6e2a..42d013fd61 100644 --- a/src/plugins/messageLogger/messageLogger.css +++ b/src/plugins/messageLogger/messageLogger.css @@ -2,28 +2,7 @@ display: none; } -.messagelogger-deleted -:is( - .messagelogger-deleted-attachment, - .emoji, - [data-type="sticker"], - [class*="embedIframe"], - [class*="embedSpotify"], - [class*="imageContainer"] -) { - filter: grayscale(1) !important; - transition: 150ms filter ease-in-out; - - &[class*="hiddenMosaicItem"] { - filter: grayscale(1) blur(var(--custom-message-attachment-spoiler-blur-radius, 44px)) !important; - } - - &:hover { - filter: grayscale(0) !important; - } -} - -.messagelogger-deleted [class*="spoilerWarning"] { +.messagelogger-deleted:not(.messagelogger-highlight-bypass) [class*="spoilerWarning"] { color: var(--status-danger); } @@ -48,3 +27,25 @@ flex-wrap: wrap; gap: 16px; } + +.messagelogger-deleted-attachment-overlay:not(.messagelogger-highlight-bypass) { + --border-subtle: #360f13; +} + +.messagelogger-deleted-attachment-overlay::after { + transition: 150ms opacity ease-in-out; + position: absolute; + pointer-events: none; + content: ""; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: hsl(var(--red-430-hsl, 0 85% 61%) / 75%); + opacity: 0; + border-radius: 8px; +} + +.messagelogger-deleted-attachment-overlay:not(.messagelogger-highlight-bypass)::after { + opacity: 0.2; +} \ No newline at end of file diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c3b784716d..a3441297f2 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -629,6 +629,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ name: "prism", id: 390884143749136386n, }, + xNasuni: { + name: "xNasuni", + id: 515356922585677834n + } } satisfies Record); // iife so #__PURE__ works correctly