Link gallery uploads back to chat

This commit is contained in:
pewdiepie-archdaemon
2026-06-29 02:34:11 +00:00
parent e2c8b8eb37
commit 4a7c03d536
4 changed files with 72 additions and 11 deletions
+1 -1
View File
@@ -686,7 +686,7 @@ import { wireArrowUpRecall, getLastUserMessageFromChatHistory } from './composer
let ids = [];
try {
ids = await fileHandlerModule.uploadPending();
ids = await fileHandlerModule.uploadPending({ sessionId: sessionModule.getCurrentSessionId() });
} catch(e) {
console.error('upload failed', e);
}
+2 -1
View File
@@ -142,7 +142,7 @@ export function removePending(idx) {
/**
* Upload all pending files to server
*/
export async function uploadPending() {
export async function uploadPending(opts = {}) {
if (pendingFiles.length === 0) return [];
_lastUploadCancelled = false;
@@ -169,6 +169,7 @@ export async function uploadPending() {
const fd = new FormData();
pendingFiles.forEach(f => fd.append('files', f, f.name || 'paste.png'));
if (opts.sessionId) fd.append('session_id', opts.sessionId);
_uploadAbortCtrl = new AbortController();
_uploading = true;
const timeoutId = setTimeout(() => {
+48 -3
View File
@@ -8,6 +8,8 @@ import spinnerModule from './spinner.js';
import { makeWindowDraggable } from './windowDrag.js';
import { bindMenuDismiss, dismissOrRemove } from './escMenuStack.js';
import { topPortalZ } from './toolWindowZOrder.js';
import sessionModule from './sessions.js';
import fileHandlerModule from './fileHandler.js';
const API_BASE = window.location.origin;
let _open = false;
@@ -1356,6 +1358,10 @@ function _openDetail(img) {
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 3a2.83 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/></svg>
Edit
</button>
<button class="gallery-detail-back" id="gallery-chat-photo-btn" title="${img.session_id ? 'Open source chat' : 'Start a new chat with this photo'}" aria-label="${img.session_id ? 'Open source chat' : 'Discuss photo'}" style="display:inline-flex;align-items:center;gap:4px;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a4 4 0 0 1-4 4H8l-5 3V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z"/></svg>
${img.session_id ? 'Open chat' : 'Discuss'}
</button>
<button class="gallery-detail-back gallery-detail-fav-header${img.favorite ? ' active' : ''}" id="gallery-detail-fav-header" title="${img.favorite ? 'Unfavorite' : 'Favorite'}" aria-label="Favorite" aria-pressed="${img.favorite ? 'true' : 'false'}" style="display:inline-flex;align-items:center;justify-content:center;padding:4px 8px;">
<svg width="14" height="14" viewBox="0 0 24 24" fill="${img.favorite ? 'currentColor' : 'none'}" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
</button>
@@ -1462,6 +1468,45 @@ function _openDetail(img) {
detail.style.display = 'none';
});
document.getElementById('gallery-chat-photo-btn')?.addEventListener('click', async () => {
if (img.session_id) {
closeGallery();
try {
await sessionModule.selectSession(img.session_id);
} catch (e) {
console.error('Open source chat failed:', e);
uiModule.showError && uiModule.showError('Could not open source chat');
}
return;
}
try {
const dcRes = await fetch('/api/default-chat', { credentials: 'same-origin' });
const dc = await dcRes.json();
if (!dc?.endpoint_url || !dc?.model) {
uiModule.showError && uiModule.showError('Pick a chat model first');
return;
}
sessionModule.createDirectChat(dc.endpoint_url, dc.model, dc.endpoint_id);
closeGallery();
const res = await fetch(img.url, { credentials: 'same-origin' });
if (!res.ok) throw new Error('image fetch ' + res.status);
const blob = await res.blob();
const name = img.filename || 'gallery-photo.jpg';
const file = new File([blob], name, { type: blob.type || 'image/jpeg' });
fileHandlerModule.addFiles([file]);
const input = document.getElementById('message');
if (input) {
input.value = 'Lets discuss this photo.';
input.dispatchEvent(new Event('input'));
input.focus();
}
} catch (e) {
console.error('Discuss photo failed:', e);
uiModule.showError && uiModule.showError('Could not start photo chat');
}
});
// Clickable tag chips — both AI Tags and User Tags. Clicking a chip
// closes the detail, sets the tag filter on the main grid, and
// re-fetches so the user sees other photos with that tag.
@@ -1967,9 +2012,9 @@ export function openGallery() {
<option value="">All sources</option>
</select>
<select class="gallery-sort" id="gallery-sort">
<option value="shuffle"${_sort === 'shuffle' ? ' selected' : ''}>Random</option>
<option value="recent"${_sort === 'recent' ? ' selected' : ''}>Recent</option>
<option value="oldest"${_sort === 'oldest' ? ' selected' : ''}>Oldest</option>
<option value="shuffle"${_sort === 'shuffle' ? ' selected' : ''}>Random order</option>
<option value="recent"${_sort === 'recent' ? ' selected' : ''}>↓ Newest first</option>
<option value="oldest"${_sort === 'oldest' ? ' selected' : ''}>Oldest first</option>
</select>
<button class="gallery-select-btn gallery-toolbar-action" id="gallery-select-btn" title="Select for bulk actions"><span style="position:relative;top:1px;">Select</span></button>
</div>