Skip to content

Commit a9e9fe7

Browse files
fix: fix memory leaking of ChatControls (open-webui#22112)
1 parent 702906a commit a9e9fe7

1 file changed

Lines changed: 51 additions & 41 deletions

File tree

src/lib/components/chat/ChatControls.svelte

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@
5050
export let files;
5151
export let modelId;
5252
53-
export let pane;
53+
export let pane: Pane | null = null;
5454
55-
let mediaQuery;
5655
let largeScreen = false;
5756
let dragged = false;
5857
let minSize = 0;
@@ -172,56 +171,67 @@
172171
dragged = false;
173172
};
174173
175-
onMount(async () => {
176-
mediaQuery = window.matchMedia('(min-width: 1024px)');
174+
onMount(() => {
175+
const mediaQuery = window.matchMedia('(min-width: 1024px)');
177176
mediaQuery.addEventListener('change', handleMediaQuery);
178177
handleMediaQuery(mediaQuery);
179178
179+
let resizeObserver: ResizeObserver | null = null;
180+
let isDestroyed = false;
181+
180182
// Wait for Svelte to render the Pane after largeScreen changed
181-
await tick();
182-
183-
const container = document.getElementById('chat-container');
184-
minSize = Math.floor((350 / container.clientWidth) * 100);
185-
186-
const resizeObserver = new ResizeObserver((entries) => {
187-
for (let entry of entries) {
188-
const width = entry.contentRect.width;
189-
minSize = Math.floor((350 / width) * 100);
190-
if ($showControls) {
191-
if (pane && pane.isExpanded() && pane.getSize() < minSize) {
192-
pane.resize(minSize);
193-
} else {
194-
let size = Math.floor(
195-
(parseInt(localStorage?.chatControlsSize) / container.clientWidth) * 100
196-
);
197-
if (size < minSize) pane.resize(minSize);
183+
const init = async () => {
184+
await tick();
185+
186+
if (isDestroyed) return;
187+
188+
// If controls were persisted as open, set the pane to the saved size
189+
if ($showControls && pane) {
190+
openPane();
191+
}
192+
193+
setTimeout(() => {
194+
paneReady = true;
195+
}, 0);
196+
197+
const container = document.getElementById('chat-container') as HTMLElement;
198+
if (!container) return;
199+
200+
minSize = Math.floor((350 / container.clientWidth) * 100);
201+
resizeObserver = new ResizeObserver((entries) => {
202+
for (let entry of entries) {
203+
const width = entry.contentRect.width;
204+
minSize = Math.floor((350 / width) * 100);
205+
if ($showControls) {
206+
if (pane && pane.isExpanded() && pane.getSize() < minSize) {
207+
pane.resize(minSize);
208+
} else {
209+
let size = Math.floor(
210+
(parseInt(localStorage?.chatControlsSize) / container.clientWidth) * 100
211+
);
212+
if (size < minSize && pane) pane.resize(minSize);
213+
}
198214
}
199215
}
200-
}
201-
});
202-
resizeObserver.observe(container);
216+
});
217+
resizeObserver.observe(container);
218+
};
219+
init();
203220
204221
document.addEventListener('mousedown', onMouseDown);
205222
document.addEventListener('mouseup', onMouseUp);
206223
207-
setTimeout(() => {
208-
paneReady = true;
209-
}, 0);
210-
211-
// If controls were persisted as open, set the pane to the saved size
212-
if ($showControls && pane) {
213-
openPane();
214-
}
215-
});
216-
217-
onDestroy(() => {
218-
paneReady = false;
219-
if (!largeScreen) {
220-
showControls.set(false);
224+
return () => {
225+
isDestroyed = true;
226+
paneReady = false;
227+
resizeObserver?.disconnect();
228+
if (!largeScreen) {
229+
showControls.set(false);
230+
}
231+
mediaQuery.removeEventListener('change', handleMediaQuery);
232+
document.removeEventListener('mousedown', onMouseDown);
233+
document.removeEventListener('mouseup', onMouseUp);
221234
}
222-
mediaQuery.removeEventListener('change', handleMediaQuery);
223-
document.removeEventListener('mousedown', onMouseDown);
224-
document.removeEventListener('mouseup', onMouseUp);
225235
});
226236
227237
const closeHandler = () => {

0 commit comments

Comments
 (0)