From 17bd35e4527f7c95655c8aa8da863b6a16468334 Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Wed, 5 Mar 2025 06:30:57 +0900 Subject: [PATCH] Revert #773 f7ea95aeea2e0adfb595e8ffd796bb2888430680 due to critical bug --- src/lib/ChatScreens/Chat.svelte | 54 +---- src/lib/ChatScreens/ChatScreen.svelte | 21 -- src/lib/ChatScreens/DefaultChatScreen.svelte | 236 ++++--------------- 3 files changed, 55 insertions(+), 256 deletions(-) diff --git a/src/lib/ChatScreens/Chat.svelte b/src/lib/ChatScreens/Chat.svelte index d976170e..07a8a74c 100644 --- a/src/lib/ChatScreens/Chat.svelte +++ b/src/lib/ChatScreens/Chat.svelte @@ -130,22 +130,9 @@ $effect.pre(() => { blankMessage = (message === '{{none}}' || message === '{{blank}}' || message === '') && idx === -1 }); - // Static map for caching markdown parsing results - const markdownCache = new Map(); - const markParsing = async (data: string, charArg?: string | simpleCharacterArgument, mode?: "normal" | "back", chatID?: number, translateText?:boolean, tries?:number) => { let lastParsedQueue = '' try { - // Create cache key - const cacheKey = `${data}-${JSON.stringify(charArg)}-${mode}-${chatID}-${translateText}`; - - // Use cached result if available and not retranslating - if (markdownCache.has(cacheKey) && !retranslate) { - lastParsedQueue = markdownCache.get(cacheKey); - lastCharArg = charArg; - lastChatId = chatID; - return lastParsedQueue; - } if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){ lastParsedQueue = '' lastCharArg = charArg @@ -197,7 +184,6 @@ const marked = await ParseMarkdown(data, charArg, mode, chatID, getCbsCondition()) lastParsedQueue = marked lastCharArg = charArg - markdownCache.set(cacheKey, marked); return marked } else if(!DBState.db.legacyTranslation){ @@ -207,7 +193,6 @@ translating = false lastParsedQueue = translated lastCharArg = charArg - markdownCache.set(cacheKey, translated); return translated } else{ @@ -217,7 +202,6 @@ translating = false lastParsedQueue = translated lastCharArg = charArg - markdownCache.set(cacheKey, translated); return translated } } @@ -225,12 +209,12 @@ const marked = await ParseMarkdown(data, charArg, mode, chatID, getCbsCondition()) lastParsedQueue = marked lastCharArg = charArg - markdownCache.set(cacheKey, marked); return marked } } catch (error) { //retry if(tries > 2){ + alertError(`Error while parsing chat message: ${translateText}, ${error.message}, ${error.stack}`) return data } @@ -241,17 +225,6 @@ } } - // Limit cache size (runs periodically) - function cleanupMarkdownCache() { - if (markdownCache.size > 100) { - const keys = Array.from(markdownCache.keys()); - // Delete the oldest 50 items - for (let i = 0; i < 50; i++) { - markdownCache.delete(keys[i]); - } - } - } - $effect.pre(() => { displaya(message) }); @@ -262,10 +235,6 @@ unsubscribers.push(ReloadGUIPointer.subscribe((v) => { displaya(message) })) - - // Clean up cache every 3 minutes - const cacheCleanupInterval = setInterval(cleanupMarkdownCache, 180000); - return () => clearInterval(cacheCleanupInterval); }) onDestroy(()=>{ @@ -344,22 +313,11 @@ style:line-height="{(DBState.db.lineHeight ?? 1.25) * (DBState.db.zoomsize / 100)}rem" > {#key $ReloadGUIPointer} - {#if message && message.length > 10000} - - {#await new Promise(resolve => setTimeout(() => resolve(true), 10)) then _} - {#await markParsing(msgDisplay, character, 'normal', idx, translated)} - {@html lastParsed} - {:then md} - {@html md} - {/await} - {/await} - {:else} - {#await markParsing(msgDisplay, character, 'normal', idx, translated)} - {@html lastParsed} - {:then md} - {@html md} - {/await} - {/if} + {#await markParsing(msgDisplay, character, 'normal', idx, translated)} + {@html lastParsed} + {:then md} + {@html md} + {/await} {/key} {/if} diff --git a/src/lib/ChatScreens/ChatScreen.svelte b/src/lib/ChatScreens/ChatScreen.svelte index 55458a2e..2f4acba4 100644 --- a/src/lib/ChatScreens/ChatScreen.svelte +++ b/src/lib/ChatScreens/ChatScreen.svelte @@ -5,7 +5,6 @@ import { CharEmotion, ShowVN, selectedCharID } from "../../ts/stores.svelte"; import ResizeBox from './ResizeBox.svelte' import DefaultChatScreen from "./DefaultChatScreen.svelte"; - import { clearMessageFormCache } from "../../ts/util"; import defaultWallpaper from '../../etc/bg.jpg' import ChatList from "../Others/ChatList.svelte"; import TransitionImage from "./TransitionImage.svelte"; @@ -15,7 +14,6 @@ import ModuleChatMenu from "../Setting/Pages/Module/ModuleChatMenu.svelte"; let openChatList = $state(false) let openModuleList = $state(false) - let lastCharacterId = $state(-1); const wallPaper = `background: url(${defaultWallpaper})` const externalStyles = @@ -33,25 +31,6 @@ } })() }); - - $effect.pre(() => { - if ($selectedCharID !== lastCharacterId) { - if (lastCharacterId >= 0) { - clearMessageFormCache(lastCharacterId); - - setTimeout(() => { - if (window.gc) { - try { - window.gc(); - } catch (e) { - console.log("GC not available"); - } - } - }, 100); - } - lastCharacterId = $selectedCharID; - } - }); {#if $ShowVN} diff --git a/src/lib/ChatScreens/DefaultChatScreen.svelte b/src/lib/ChatScreens/DefaultChatScreen.svelte index ed07c1d5..991d9410 100644 --- a/src/lib/ChatScreens/DefaultChatScreen.svelte +++ b/src/lib/ChatScreens/DefaultChatScreen.svelte @@ -28,10 +28,6 @@ import { getInlayAsset } from 'src/ts/process/files/inlays'; import PlaygroundMenu from '../Playground/PlaygroundMenu.svelte'; import { ConnectionOpenStore } from 'src/ts/sync/multiuser'; - import { onMount, onDestroy } from "svelte"; - import AutoresizeArea from "../UI/GUI/TextAreaResizable.svelte"; - import { alertConfirm, alertClear } from "../../ts/alert"; - import { clearMessageFormCache } from "../../ts/util"; let messageInput:string = $state('') let messageInputTranslate:string = $state('') @@ -45,107 +41,6 @@ let currentCharacter:character|groupChat = $state(DBState.db.characters[$selectedCharID]) let toggleStickers:boolean = $state(false) let fileInput:string[] = $state([]) - - // Virtual scroll related states - let visibleStartIndex = $state(0); - let visibleEndIndex = $state(30); - let chatContainerRef: HTMLElement = $state(null); - let scrollPosition = $state(0); - let isScrolling = $state(false); - let scrollingTimeoutId: number; - - // Data loading state - let isInitialLoading = $state(true); - - // Function for optimization - function updateVisibleMessages(e?: Event) { - if (!chatContainerRef) return; - - const el = chatContainerRef; - const scrollTop = el.scrollTop; - const containerHeight = el.clientHeight; - - // Save scroll position - scrollPosition = scrollTop; - - // Update scrolling state - isScrolling = true; - clearTimeout(scrollingTimeoutId); - scrollingTimeoutId = window.setTimeout(() => { - isScrolling = false; - }, 200); - - // Optimized infinite scroll logic - const scrolled = el.scrollHeight - containerHeight + scrollTop; - if (scrolled < 100 && DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message.length > loadPages) { - loadPages += 15; - } - - // Limit maximum number of messages to display if there are many - if (DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message.length > 200) { - // Load only the most recent 200 messages in memory - const messageCount = DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message.length; - visibleStartIndex = Math.max(0, messageCount - loadPages); - visibleEndIndex = messageCount; - } else { - visibleStartIndex = 0; - visibleEndIndex = loadPages; - } - } - - // Asynchronous chat data loading function - async function loadChatDataAsync() { - isInitialLoading = true; - - // Small delay to allow UI rendering - await new Promise(resolve => setTimeout(resolve, 0)); - - // Check character change and clear cache - if(lastCharId !== $selectedCharID) { - clearMessageFormCache(lastCharId); - lastCharId = $selectedCharID; - rerolls = []; - rerollid = -1; - } - - // Process bulk data loading in background - await new Promise(resolve => setTimeout(resolve, 0)); - - // Process chat data asynchronously by chunks - const messages = DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message; - - if (messages.length > 100) { - // Process large message sets in chunks asynchronously - const chunkSize = 30; - let processedChunks = 0; - - for (let i = 0; i < messages.length; i += chunkSize) { - const chunk = messages.slice(i, i + chunkSize); - // Process each chunk - await new Promise(resolve => { - setTimeout(() => { - // Only prepare work here - // Actual rendering will be done later in messageForm - processedChunks++; - resolve(null); - }, 0); - }); - - // Determine initial load message count based on progress - loadPages = Math.min(messages.length, Math.max(30, processedChunks * chunkSize)); - - // Show all of the last 30 messages - if (i >= Math.max(0, messages.length - 30)) { - loadPages = messages.length; - } - } - } else { - loadPages = messages.length; - } - - isInitialLoading = false; - updateVisibleMessages(); - } async function send(){ return sendMain(false) @@ -523,16 +418,6 @@ $effect.pre(() => { currentCharacter = DBState.db.characters[$selectedCharID] }); - - // Load chat data when character or chat page changes - $effect.pre(() => { - const charId = $selectedCharID; - const chatPage = DBState.db.characters[$selectedCharID]?.chatPage; - - if (charId >= 0) { - loadChatDataAsync(); - } - }); @@ -546,20 +431,13 @@ {/if} {:else} -
- - - {#if isInitialLoading} -
-
-
-

{language.loading}

-
-
- {/if} - +
{ + //@ts-ignore + const scrolled = (e.target.scrollHeight - e.target.clientHeight + e.target.scrollTop) + if(scrolled < 100 && DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message.length > loadPages){ + loadPages += 15 + } + }}>
{#if DBState.db.useChatSticker && currentCharacter.type !== 'group'}
{toggleStickers = !toggleStickers}} @@ -761,66 +639,50 @@ )} {send}/> {/if} - {#key loadPages} - {#each messageForm(DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message, loadPages) as chat, i} - {#if !isScrolling || i < 20} - {#if chat.role === 'char'} - {#if DBState.db.characters[$selectedCharID].type !== 'group'} - - {:else} - - {/if} - {:else} - - {/if} + {#each messageForm(DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message, loadPages) as chat, i} + {#if chat.role === 'char'} + {#if DBState.db.characters[$selectedCharID].type !== 'group'} + {:else} - -
-
-
- -
-
-
-
-
+ {/if} - {/each} - {/key} - + {:else} + + {/if} + {/each} {#if DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].message.length <= loadPages} {#if DBState.db.characters[$selectedCharID].type !== 'group' }