add slash command progress indicator

This commit is contained in:
LenAnderson
2024-04-27 11:12:30 -04:00
parent b8504735fa
commit 5cc3a2cede
5 changed files with 27 additions and 2 deletions

View File

@ -2405,19 +2405,27 @@ async function processCommands(message, abortController) {
deactivateSendButtons(); deactivateSendButtons();
is_send_press = true; is_send_press = true;
/**@type {HTMLTextAreaElement}*/
const ta = document.querySelector('#send_textarea'); const ta = document.querySelector('#send_textarea');
ta.value = ''; ta.value = '';
ta.dispatchEvent(new Event('input', { bubbles:true })); ta.dispatchEvent(new Event('input', { bubbles:true }));
await executeSlashCommandsWithOptions(message, { await executeSlashCommandsWithOptions(message, {
abortController: abortController, abortController: abortController,
onProgress: (done, total)=>ta.style.setProperty('--prog', `${done / total * 100}%`),
}); });
delay(1000).then(()=>clearCommandProgressDebounced());
is_send_press = false; is_send_press = false;
activateSendButtons(); activateSendButtons();
return true; return true;
} }
function clearCommandProgress() {
if (is_send_press) return;
document.querySelector('#send_textarea').style.setProperty('--prog', '0%');
}
const clearCommandProgressDebounced = debounce(clearCommandProgress);
function sendSystemMessage(type, text, extra = {}) { function sendSystemMessage(type, text, extra = {}) {
const systemMessage = system_messages[type]; const systemMessage = system_messages[type];

View File

@ -700,7 +700,7 @@ const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
*/ */
function autoFitSendTextArea() { function autoFitSendTextArea() {
const originalScrollBottom = chatBlock.scrollHeight - (chatBlock.scrollTop + chatBlock.offsetHeight); const originalScrollBottom = chatBlock.scrollHeight - (chatBlock.scrollTop + chatBlock.offsetHeight);
if (sendTextArea.scrollHeight == sendTextArea.offsetHeight) { if (sendTextArea.scrollHeight + 2 == sendTextArea.offsetHeight) {
// Needs to be pulled dynamically because it is affected by font size changes // Needs to be pulled dynamically because it is affected by font size changes
const sendTextAreaMinHeight = window.getComputedStyle(sendTextArea).getPropertyValue('min-height'); const sendTextAreaMinHeight = window.getComputedStyle(sendTextArea).getPropertyValue('min-height');
sendTextArea.style.height = sendTextAreaMinHeight; sendTextArea.style.height = sendTextAreaMinHeight;

View File

@ -2557,6 +2557,7 @@ function modelCallback(_, model) {
* @param {boolean} [options.handleExecutionErrors] * @param {boolean} [options.handleExecutionErrors]
* @param {PARSER_FLAG[]} [options.parserFlags] * @param {PARSER_FLAG[]} [options.parserFlags]
* @param {AbortController} [options.abortController] * @param {AbortController} [options.abortController]
* @param {(done:number, total:number)=>void} [options.onProgress]
* @returns {Promise<SlashCommandClosureResult>} * @returns {Promise<SlashCommandClosureResult>}
*/ */
async function executeSlashCommandsWithOptions(text, options = {}) { async function executeSlashCommandsWithOptions(text, options = {}) {
@ -2567,6 +2568,7 @@ async function executeSlashCommandsWithOptions(text, options = {}) {
options.handleExecutionErrors ?? false, options.handleExecutionErrors ?? false,
options.parserFlags ?? null, options.parserFlags ?? null,
options.abortController ?? null, options.abortController ?? null,
options.onProgress ?? null,
); );
} }
/** /**
@ -2579,7 +2581,7 @@ async function executeSlashCommandsWithOptions(text, options = {}) {
* @param {AbortController} abortController * @param {AbortController} abortController
* @returns {Promise<SlashCommandClosureResult>} * @returns {Promise<SlashCommandClosureResult>}
*/ */
async function executeSlashCommands(text, handleParserErrors = true, scope = null, handleExecutionErrors = false, parserFlags = null, abortController = null) { async function executeSlashCommands(text, handleParserErrors = true, scope = null, handleExecutionErrors = false, parserFlags = null, abortController = null, onProgress = null) {
if (!text) { if (!text) {
return null; return null;
} }
@ -2588,6 +2590,7 @@ async function executeSlashCommands(text, handleParserErrors = true, scope = nul
try { try {
closure = parser.parse(text, true, parserFlags, abortController); closure = parser.parse(text, true, parserFlags, abortController);
closure.scope.parent = scope; closure.scope.parent = scope;
closure.onProgress = onProgress;
} catch (e) { } catch (e) {
if (handleParserErrors && e instanceof SlashCommandParserError) { if (handleParserErrors && e instanceof SlashCommandParserError) {
/**@type {SlashCommandParserError}*/ /**@type {SlashCommandParserError}*/

View File

@ -15,6 +15,7 @@ export class SlashCommandClosure {
/**@type {SlashCommandExecutor[]}*/ executorList = []; /**@type {SlashCommandExecutor[]}*/ executorList = [];
/**@type {string}*/ keptText; /**@type {string}*/ keptText;
/**@type {AbortController}*/ abortController; /**@type {AbortController}*/ abortController;
/**@type {(done:number, total:number)=>void}*/ onProgress;
constructor(parent) { constructor(parent) {
this.scope = new SlashCommandScope(parent); this.scope = new SlashCommandScope(parent);
@ -79,6 +80,7 @@ export class SlashCommandClosure {
closure.executorList = this.executorList; closure.executorList = this.executorList;
closure.keptText = this.keptText; closure.keptText = this.keptText;
closure.abortController = this.abortController; closure.abortController = this.abortController;
closure.onProgress = this.onProgress;
return closure; return closure;
} }
@ -142,7 +144,10 @@ export class SlashCommandClosure {
this.scope.setVariable(key, v); this.scope.setVariable(key, v);
} }
let done = 0;
for (const executor of this.executorList) { for (const executor of this.executorList) {
done += 0.5;
this.onProgress?.(done, this.executorList.length);
if (executor instanceof SlashCommandClosureExecutor) { if (executor instanceof SlashCommandClosureExecutor) {
const closure = this.scope.getVariable(executor.name); const closure = this.scope.getVariable(executor.name);
if (!closure || !(closure instanceof SlashCommandClosure)) throw new Error(`${executor.name} is not a closure.`); if (!closure || !(closure instanceof SlashCommandClosure)) throw new Error(`${executor.name} is not a closure.`);
@ -233,6 +238,8 @@ export class SlashCommandClosure {
return abortResult; return abortResult;
} }
this.scope.pipe = await executor.command.callback(args, value ?? ''); this.scope.pipe = await executor.command.callback(args, value ?? '');
done += 0.5;
this.onProgress?.(done, this.executorList.length);
// eslint-disable-next-line no-cond-assign // eslint-disable-next-line no-cond-assign
if (abortResult = this.testAbortController()) { if (abortResult = this.testAbortController()) {
return abortResult; return abortResult;

View File

@ -1062,6 +1062,13 @@ select {
text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor); text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor);
flex: 1; flex: 1;
order: 3; order: 3;
--progColor: rgba(0, 128, 0, 0.839);
--progWidth: 3px;
--prog: 0%;
border-top: var(--progWidth) solid var(--progColor);
clip-path: polygon(0% 0%, var(--prog) 0%, var(--prog) 5px, 100% 5px, 100% 100%, 0% 100%);
transition: clip-path 200ms;
} }
.slashCommandAutoComplete-wrap { .slashCommandAutoComplete-wrap {