fix: preview generated assistant images inline
This commit is contained in:
parent
8ea79bcfb9
commit
2a19f32f21
2 changed files with 48 additions and 2 deletions
|
|
@ -124,6 +124,13 @@
|
|||
.assistant-side-body { padding:12px; display:grid; gap:10px; font-size:13px; }
|
||||
.assistant-visual-output { display:grid; gap:8px; }
|
||||
.assistant-visual-output img { width:100%; border-radius:10px; border:1px solid var(--g200); background:white; }
|
||||
.assistant-generated-image { display:grid; gap:8px; }
|
||||
.assistant-generated-image img { width:100%; border-radius:10px; border:1px solid var(--g200); background:white; }
|
||||
.assistant-image-actions { display:flex; gap:8px; flex-wrap:wrap; }
|
||||
.assistant-image-modal { position:fixed; inset:0; z-index:9999; background:rgba(15,23,42,.82); display:flex; align-items:center; justify-content:center; padding:24px; }
|
||||
.assistant-image-modal-card { position:relative; max-width:min(96vw,1200px); max-height:92vh; }
|
||||
.assistant-image-modal-card img { max-width:100%; max-height:92vh; border-radius:14px; background:white; box-shadow:0 24px 80px rgba(0,0,0,.35); }
|
||||
.assistant-image-modal-close { position:absolute; top:-12px; right:-12px; width:34px; height:34px; border:0; border-radius:999px; background:white; color:var(--g800); font-size:22px; line-height:1; cursor:pointer; box-shadow:var(--shadow); }
|
||||
.assistant-sources { padding:10px 12px; display:grid; gap:8px; max-height:520px; overflow-y:auto; }
|
||||
.assistant-source { border:1px solid var(--g200); border-radius:10px; padding:9px; background:white; font-size:12px; line-height:1.5; }
|
||||
.assistant-source strong { color:var(--g800); }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
var lastSources = [];
|
||||
var mermaidReady = false;
|
||||
var dynamicExamples = [];
|
||||
var generatedImages = {};
|
||||
var generatedImageSeq = 0;
|
||||
var EMPTY_PROMPT_SETS = [
|
||||
[
|
||||
{ label: 'Status asthma escalation', prompt: 'In a 4-year-old with acute wheeze, when should magnesium sulfate be considered and what dose is recommended?' },
|
||||
|
|
@ -62,6 +64,7 @@
|
|||
if (copyBtn) copyBtn.addEventListener('click', copyLastAnswer);
|
||||
if (exportBtn) exportBtn.addEventListener('click', exportAnswerPdf);
|
||||
if (imageBtn) imageBtn.addEventListener('click', generateImage);
|
||||
document.addEventListener('click', onAssistantDocumentClick);
|
||||
if (input) input.addEventListener('keydown', function (e) {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') onAsk(e);
|
||||
});
|
||||
|
|
@ -365,10 +368,10 @@
|
|||
if (!data.success) throw new Error(data.error || 'Image generation failed');
|
||||
var src = data.imageUrl || data.url || (data.base64 ? ('data:image/png;base64,' + data.base64) : '');
|
||||
if (!src) throw new Error('No image returned');
|
||||
if (out) out.innerHTML = '<img src="' + escapeAttr(src) + '" alt="Generated clinical visual"><a class="btn-sm btn-ghost" href="' + escapeAttr(src) + '" target="_blank" rel="noopener"><i class="fas fa-up-right-from-square"></i> Open</a>';
|
||||
if (out) out.innerHTML = renderGeneratedImage(src, 'Generated clinical visual');
|
||||
if (fromChat) {
|
||||
setBusy(false, 'Ready');
|
||||
var html = '<div class="assistant-generated-image"><img src="' + escapeAttr(src) + '" alt="Generated clinical visual"><a class="btn-sm btn-ghost" href="' + escapeAttr(src) + '" target="_blank" rel="noopener"><i class="fas fa-up-right-from-square"></i> Open image</a></div>';
|
||||
var html = renderGeneratedImage(src, 'Generated clinical visual');
|
||||
replaceLoadingMessage(loading, html, [], [], true);
|
||||
}
|
||||
})
|
||||
|
|
@ -380,6 +383,42 @@
|
|||
});
|
||||
}
|
||||
|
||||
function renderGeneratedImage(src, alt) {
|
||||
var id = 'img-' + (++generatedImageSeq);
|
||||
generatedImages[id] = src;
|
||||
return '<div class="assistant-generated-image"><img src="' + escapeAttr(src) + '" alt="' + escapeAttr(alt || 'Generated image') + '">' +
|
||||
'<div class="assistant-image-actions">' +
|
||||
'<button type="button" class="btn-sm btn-ghost" data-assistant-open-image="' + escapeAttr(id) + '"><i class="fas fa-expand"></i> Preview</button>' +
|
||||
'<a class="btn-sm btn-ghost" href="' + escapeAttr(src) + '" download="clinical-visual.png"><i class="fas fa-download"></i> Download</a>' +
|
||||
'</div></div>';
|
||||
}
|
||||
|
||||
function onAssistantDocumentClick(e) {
|
||||
var openBtn = e.target.closest('[data-assistant-open-image]');
|
||||
if (openBtn) {
|
||||
e.preventDefault();
|
||||
openImagePreview(openBtn.getAttribute('data-assistant-open-image'));
|
||||
return;
|
||||
}
|
||||
if (e.target.closest('.assistant-image-modal-close') || e.target.classList.contains('assistant-image-modal')) {
|
||||
closeImagePreview();
|
||||
}
|
||||
}
|
||||
|
||||
function openImagePreview(id) {
|
||||
var src = generatedImages[id];
|
||||
if (!src) return;
|
||||
closeImagePreview();
|
||||
var modal = document.createElement('div');
|
||||
modal.className = 'assistant-image-modal';
|
||||
modal.innerHTML = '<div class="assistant-image-modal-card"><button type="button" class="assistant-image-modal-close" aria-label="Close">×</button><img src="' + escapeAttr(src) + '" alt="Generated clinical visual"></div>';
|
||||
document.body.appendChild(modal);
|
||||
}
|
||||
|
||||
function closeImagePreview() {
|
||||
document.querySelectorAll('.assistant-image-modal').forEach(function (el) { el.remove(); });
|
||||
}
|
||||
|
||||
function buildContextualImagePrompt(request) {
|
||||
var prompt = String(request || '').trim();
|
||||
if (!lastAnswer) return prompt;
|
||||
|
|
|
|||
Loading…
Reference in a new issue