first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ILlmActionRequest, ILlmInitAction, ModalDisplayStyle } from './common/interfaces';
import { App } from './App';
import { getTargetText, isTargetCkeditor, setTargetText } from './common/textUtil';
import { getPromptStreamResponse } from './common/adminApiUtil';
// Store the React root globally to avoid remounting
let modalRoot: ReactDOM.Root | null = null;
export const initModal = (action: ILlmInitAction) => {
// Find the modal container
const modalContainer: Element | null = document.querySelector('[data-wpj-modal-mount]');
if (!modalContainer) {
console.error('Modal container with [data-wpj-modal-mount] not found.');
return;
}
// Create a root if it doesn't exist
if (!modalRoot) {
modalRoot = ReactDOM.createRoot(modalContainer);
}
const dataAttr = modalContainer.getAttribute('data-wpj-modal-mount');
const displayStyle = (dataAttr ? dataAttr : 'modal') as ModalDisplayStyle;
// Render modal with updated data
modalRoot.render(
// <React.StrictMode>
<App close={closeModal} llmAction={action} displayStyle={displayStyle} />,
// </React.StrictMode>,
);
};
let applyGlobalAbort: ((reason?: string) => void) | null = null;
export const applyAction = (action: ILlmInitAction, buttonId?: string) => {
const body: ILlmActionRequest = {
...action,
text: getTargetText(action.target),
};
const buttonEl = document.getElementById(buttonId ?? '');
buttonEl?.classList.add('is-submitting');
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
applyGlobalAbort && applyGlobalAbort('applyUser');
applyGlobalAbort = null;
let result = '';
// throttle update interval, because ckeditor behaves weirdly when update interval is too fast
let updateInterval: any = null;
updateInterval =
isTargetCkeditor(action.target) &&
setInterval(() => {
setTargetText(action.target, result);
}, 700);
const request = getPromptStreamResponse(body, (partialResponse) => {
result = partialResponse;
!isTargetCkeditor(action.target) && setTargetText(action.target, result);
});
applyGlobalAbort = request.abort;
request.promise
.then(() => {
setTargetText(action.target, result);
buttonEl?.classList.remove('is-submitting');
})
.catch((reason) => {
if (reason !== 'applyUser') {
buttonEl?.classList.remove('is-submitting');
}
})
.finally(() => {
updateInterval && clearInterval(updateInterval);
});
};
export const cancelAction = () => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
applyGlobalAbort && applyGlobalAbort();
applyGlobalAbort = null;
};
export function closeModal() {
if (modalRoot) {
modalRoot.unmount();
modalRoot = null;
window.parent.postMessage({
event: 'llm-modal-closed',
});
}
}