From 4ee6e271fb877ee610eb0c60e4a1ab4924f6309e Mon Sep 17 00:00:00 2001 From: hanishkvc Date: Mon, 10 Nov 2025 18:37:53 +0530 Subject: [PATCH] SimpleChatTCRV:Vision:Show user image selection in btn Add a new helper to create a file type input which includes a btn with image. Use same wrt the user image selection button. Update button creation helper to show innerText only if the newly added innerHTML arg is undefined. When ever user makes a image selection, the image will be shown in the input-filetype-image-button. In turn when the same is submitted to ai engine server, the image will be cleared. --- tools/server/public_simplechat/simplechat.css | 4 +++ tools/server/public_simplechat/simplechat.js | 12 ++++--- tools/server/public_simplechat/ui.mjs | 32 ++++++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/tools/server/public_simplechat/simplechat.css b/tools/server/public_simplechat/simplechat.css index 38e4866236..ca20b75ad1 100644 --- a/tools/server/public_simplechat/simplechat.css +++ b/tools/server/public_simplechat/simplechat.css @@ -79,6 +79,10 @@ max-width: fit-content; max-height: 20vh; } +.user-in-img { + max-width: 20vmin; + max-height: 20vmin; +} .gridx2 { diff --git a/tools/server/public_simplechat/simplechat.js b/tools/server/public_simplechat/simplechat.js index 895ddd1ad0..11bb9faf7f 100644 --- a/tools/server/public_simplechat/simplechat.js +++ b/tools/server/public_simplechat/simplechat.js @@ -964,7 +964,7 @@ class MultiChatUI { // Save any placeholder set by default like through html, to restore where needed this.elInUser.dataset.placeholder = this.elInUser.placeholder // Setup Image loading button and flow - this.elInFileX = ui.el_creatediv_inputfile('image', 'image', '', ()=>{ + this.elInFileX = ui.el_creatediv_inputfileimgbtn('image', 'image', '', ()=>{ let f0 = this.elInFileX.el.files?.item(0); if (!f0) { return @@ -972,11 +972,14 @@ class MultiChatUI { console.log(`DBUG:InFileX:${f0?.name}`) let fR = new FileReader() fR.onload = () => { - this.me.dataURLs.push(fR.result) - console.log(`INFO:InFileX:Loaded file ${f0.name}`) + if ((fR.result) && (typeof(fR.result) == 'string')) { + this.me.dataURLs.push(fR.result) + this.elInFileX.elImg.src = fR.result + console.log(`INFO:InFileX:Loaded file ${f0.name}`) + } } fR.readAsDataURL(f0) - }, "") + }, 'user-in') this.elBtnUser.parentElement?.appendChild(this.elInFileX.elB) this.validate_element(this.elInSystem, "system-in"); @@ -1362,6 +1365,7 @@ class MultiChatUI { this.me.dataURLs.pop() } chat.add(new ChatMessageEx(new NSChatMessage(Roles.User, content, undefined, undefined, undefined, undefined, image))) + this.elInFileX.elImg.src = "" } if (this.elInUser.dataset.placeholder) { this.elInUser.placeholder = this.elInUser.dataset.placeholder; diff --git a/tools/server/public_simplechat/ui.mjs b/tools/server/public_simplechat/ui.mjs index cbd8c578e6..159234b60a 100644 --- a/tools/server/public_simplechat/ui.mjs +++ b/tools/server/public_simplechat/ui.mjs @@ -48,8 +48,9 @@ export function el_children_config_class(elBase, idSelected, classSelected, clas * @param {(this: HTMLButtonElement, ev: MouseEvent) => any} callback * @param {string | undefined} name * @param {string | undefined} innerText + * @param {string | undefined} innerHTML */ -export function el_create_button(id, callback, name=undefined, innerText=undefined) { +export function el_create_button(id, callback, name=undefined, innerText=undefined, innerHTML=undefined) { if (!name) { name = id; } @@ -59,7 +60,11 @@ export function el_create_button(id, callback, name=undefined, innerText=undefin let btn = document.createElement("button"); btn.id = id; btn.name = name; - btn.innerText = innerText; + if (innerHTML) { + btn.innerHTML = innerHTML; + } else { + btn.innerText = innerText; + } btn.addEventListener("click", callback); return btn; } @@ -231,7 +236,6 @@ export function el_creatediv_input(id, label, type, defaultValue, cb, className= return { div: div, el: el }; } - /** * Create a div wrapped input of type file, * which hides input and shows a button which chains to underlying file type input. @@ -241,17 +245,35 @@ export function el_creatediv_input(id, label, type, defaultValue, cb, className= * @param {(arg0: any) => void} cb * @param {string} className */ -export function el_creatediv_inputfile(id, label, defaultValue, cb, className) { +export function el_creatediv_inputfilebtn(id, label, defaultValue, cb, className) { let elX = el_creatediv_input(id, label, "file", defaultValue, cb, className) elX.el.hidden = true let idB = `${id}-button` let elB = el_create_button(idB, (mev) => { elX.el.click() - }, idB, label) + }, idB, label, `

${label}

`) return { div: elX.div, el: elX.el, elB: elB }; } +/** + * Create a div wrapped input of type file, + * which hides input and shows a image button which chains to underlying file type input. + * @param {string} id + * @param {string} label + * @param {any} defaultValue + * @param {(arg0: any) => void} cb + * @param {string} className + */ +export function el_creatediv_inputfileimgbtn(id, label, defaultValue, cb, className) { + let elX = el_creatediv_inputfilebtn(id, label, defaultValue, cb, className); + let elImg = document.createElement('img') + elImg.classList.add(`${className}-img`) + elX.elB.appendChild(elImg) + return { div: elX.div, el: elX.el, elB: elX.elB, elImg: elImg }; +} + + /** * Auto create ui input elements for specified fields/properties in given object * Currently supports text, number, boolean field types.