From 5bb1c42fa8268911dcc962e26f19643e47aedd99 Mon Sep 17 00:00:00 2001 From: Shirasawa <764798966@qq.com> Date: Sun, 1 Mar 2026 03:03:08 +0800 Subject: [PATCH] fix: Fix memory leaking of MessageInput (#21968) --- .../components/channel/MessageInput.svelte | 42 +++++++------ src/lib/components/chat/MessageInput.svelte | 60 ++++++++++--------- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/lib/components/channel/MessageInput.svelte b/src/lib/components/channel/MessageInput.svelte index 791f619600..3dcdcc69a2 100644 --- a/src/lib/components/channel/MessageInput.svelte +++ b/src/lib/components/channel/MessageInput.svelte @@ -2,7 +2,7 @@ import { toast } from 'svelte-sonner'; import { v4 as uuidv4 } from 'uuid'; - import { tick, getContext, onMount, onDestroy } from 'svelte'; + import { tick, getContext, onMount } from 'svelte'; const i18n = getContext('i18n'); @@ -510,7 +510,7 @@ } }; - const onDragOver = (e) => { + const onDragOver = (e: DragEvent) => { e.preventDefault(); // Check if a file is being draggedOver. @@ -525,7 +525,7 @@ draggedOver = false; }; - const onDrop = async (e) => { + const onDrop = async (e: DragEvent) => { e.preventDefault(); if (e.dataTransfer?.files && acceptFiles) { @@ -567,7 +567,7 @@ onChange(); } - onMount(async () => { + onMount(() => { suggestions = [ { char: '@', @@ -633,24 +633,32 @@ }, 100); window.addEventListener('keydown', handleKeyDown); - await tick(); - const dropzoneElement = document.getElementById('channel-container'); + let isDestroyed = false; + let dropzoneElement: HTMLElement | null = null; + const initialize = async () => { + await tick(); + if (isDestroyed) return; - dropzoneElement?.addEventListener('dragover', onDragOver); - dropzoneElement?.addEventListener('drop', onDrop); - dropzoneElement?.addEventListener('dragleave', onDragLeave); - }); + dropzoneElement = document.getElementById('channel-container'); + if (dropzoneElement) { + dropzoneElement.addEventListener('dragover', onDragOver); + dropzoneElement.addEventListener('drop', onDrop); + dropzoneElement.addEventListener('dragleave', onDragLeave); + } + } + initialize(); - onDestroy(() => { - window.removeEventListener('keydown', handleKeyDown); + return () => { + isDestroyed = true; - const dropzoneElement = document.getElementById('channel-container'); + window.removeEventListener('keydown', handleKeyDown); - if (dropzoneElement) { - dropzoneElement?.removeEventListener('dragover', onDragOver); - dropzoneElement?.removeEventListener('drop', onDrop); - dropzoneElement?.removeEventListener('dragleave', onDragLeave); + if (dropzoneElement) { + dropzoneElement.removeEventListener('dragover', onDragOver); + dropzoneElement.removeEventListener('drop', onDrop); + dropzoneElement.removeEventListener('dragleave', onDragLeave); + } } }); diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index cc9e05f3af..46932e30dc 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -11,7 +11,7 @@ dayjs.extend(duration); dayjs.extend(relativeTime); - import { onMount, tick, getContext, createEventDispatcher, onDestroy } from 'svelte'; + import { onMount, tick, getContext, createEventDispatcher } from 'svelte'; import { createPicker, getAuthToken } from '$lib/utils/google-drive-picker'; import { pickAndDownloadFile } from '$lib/utils/onedrive-file-picker'; @@ -798,7 +798,7 @@ } }; - const onDragOver = (e) => { + const onDragOver = (e: DragEvent) => { e.preventDefault(); // Check if a file is being dragged. @@ -809,14 +809,14 @@ } }; - const onDragLeave = (e) => { - if (e.currentTarget.contains(e.relatedTarget)) { + const onDragLeave = (e: DragEvent) => { + if ((e.currentTarget as HTMLElement)?.contains(e.relatedTarget as Node)) { return; } dragged = false; }; - const onDrop = async (e) => { + const onDrop = async (e: DragEvent) => { e.preventDefault(); console.log(e); @@ -831,7 +831,7 @@ dragged = false; }; - const onKeyDown = (e) => { + const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Shift') { shiftKey = true; } @@ -855,7 +855,7 @@ } }; - const onKeyUp = (e) => { + const onKeyUp = (e: KeyboardEvent) => { if (e.key === 'Shift') { shiftKey = false; } @@ -867,7 +867,7 @@ shiftKey = false; }; - onMount(async () => { + onMount(() => { suggestions = [ { char: '@', @@ -1000,31 +1000,37 @@ window.addEventListener('focus', onFocus); window.addEventListener('blur', onBlur); - await tick(); + let isDestroyed = false; + let dropzoneElement: HTMLElement | null = null; + const initialize = async () => { + await tick(); + if (isDestroyed) return; - const dropzoneElement = document.getElementById('chat-pane'); + dropzoneElement = document.getElementById('chat-pane'); + if (dropzoneElement) { + dropzoneElement.addEventListener('dragover', onDragOver); + dropzoneElement.addEventListener('drop', onDrop); + dropzoneElement.addEventListener('dragleave', onDragLeave); + } - dropzoneElement?.addEventListener('dragover', onDragOver); - dropzoneElement?.addEventListener('drop', onDrop); - dropzoneElement?.addEventListener('dragleave', onDragLeave); + tools.set(await getTools(localStorage.token)); + } + initialize(); - await tools.set(await getTools(localStorage.token)); - }); + return () => { + isDestroyed = true; - onDestroy(() => { - console.log('destroy'); - window.removeEventListener('keydown', onKeyDown); - window.removeEventListener('keyup', onKeyUp); + window.removeEventListener('keydown', onKeyDown); + window.removeEventListener('keyup', onKeyUp); - window.removeEventListener('focus', onFocus); - window.removeEventListener('blur', onBlur); + window.removeEventListener('focus', onFocus); + window.removeEventListener('blur', onBlur); - const dropzoneElement = document.getElementById('chat-pane'); - - if (dropzoneElement) { - dropzoneElement?.removeEventListener('dragover', onDragOver); - dropzoneElement?.removeEventListener('drop', onDrop); - dropzoneElement?.removeEventListener('dragleave', onDragLeave); + if (dropzoneElement) { + dropzoneElement.removeEventListener('dragover', onDragOver); + dropzoneElement.removeEventListener('drop', onDrop); + dropzoneElement.removeEventListener('dragleave', onDragLeave); + } } });