|
|
|
|
|
|
|
|
import { defaultValueCtx, Editor, editorViewCtx, editorViewOptionsCtx, parserCtx, rootCtx, serializerCtx } from '@milkdown/core'; |
|
|
|
|
|
import { chatLogEditor } from './boot-app'; |
|
|
|
|
|
|
|
|
const earlyOutputs = []; |
|
|
const earlyElements = []; |
|
|
|
|
|
export function outputMessage(msg) { |
|
|
if (!chatLogEditor) { |
|
|
|
|
|
earlyOutputs.push(msg); |
|
|
|
|
|
const elem = document.createElement('pre'); |
|
|
elem.textContent = msg; |
|
|
elem.style.whiteSpace = 'pre-wrap'; |
|
|
elem.dataset.earlyOutput = '1'; |
|
|
|
|
|
const container = document.querySelector('.chat-log') || document.body; |
|
|
container.appendChild(elem); |
|
|
earlyElements.push(elem); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
if (earlyOutputs.length > 0) { |
|
|
flushBufferedOutputs(); |
|
|
} |
|
|
|
|
|
|
|
|
chatLogEditor.action((ctx) => { |
|
|
const view = ctx.get(editorViewCtx); |
|
|
const parser = ctx.get(parserCtx); |
|
|
const serializer = ctx.get(serializerCtx); |
|
|
const state = view.state; |
|
|
|
|
|
const currentMarkdown = serializer(state.doc); |
|
|
const newMarkdown = currentMarkdown ? (currentMarkdown + '\n' + msg) : msg; |
|
|
const doc = parser(newMarkdown); |
|
|
|
|
|
const tr = state.tr.replaceWith(0, state.doc.content.size, doc.content); |
|
|
view.dispatch(tr); |
|
|
}); |
|
|
|
|
|
const chatLogElem = document.querySelector('.chat-log .milkdown .ProseMirror'); |
|
|
if (chatLogElem) { |
|
|
if (typeof chatLogElem.scrollTo === 'function') { |
|
|
chatLogElem.scrollTo({ top: chatLogElem.scrollHeight, behavior: 'smooth' }); |
|
|
} else { |
|
|
chatLogElem.scrollTop = chatLogElem.scrollHeight; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function flushBufferedOutputs() { |
|
|
if (!chatLogEditor) return; |
|
|
if (earlyOutputs.length === 0) return; |
|
|
|
|
|
|
|
|
const combined = earlyOutputs.join('\n'); |
|
|
|
|
|
chatLogEditor.action((ctx) => { |
|
|
const view = ctx.get(editorViewCtx); |
|
|
const parser = ctx.get(parserCtx); |
|
|
const serializer = ctx.get(serializerCtx); |
|
|
const state = view.state; |
|
|
|
|
|
const currentMarkdown = serializer(state.doc); |
|
|
const newMarkdown = currentMarkdown ? (currentMarkdown + '\n' + combined) : combined; |
|
|
const doc = parser(newMarkdown); |
|
|
const tr = state.tr.replaceWith(0, state.doc.content.size, doc.content); |
|
|
view.dispatch(tr); |
|
|
}); |
|
|
|
|
|
|
|
|
for (const el of earlyElements) { |
|
|
if (el && el.parentNode) el.parentNode.removeChild(el); |
|
|
} |
|
|
earlyElements.length = 0; |
|
|
earlyOutputs.length = 0; |
|
|
|
|
|
|
|
|
const chatLogElem = document.querySelector('.chat-log .milkdown .ProseMirror'); |
|
|
if (chatLogElem) { |
|
|
if (typeof chatLogElem.scrollTo === 'function') { |
|
|
chatLogElem.scrollTo({ top: chatLogElem.scrollHeight, behavior: 'smooth' }); |
|
|
} else { |
|
|
chatLogElem.scrollTop = chatLogElem.scrollHeight; |
|
|
} |
|
|
} |
|
|
} |
|
|
|