new interface
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,116 @@
|
||||
/* DONA_INLINE_INDEX_V2 — rendu natif dans l'index, sans carte opaque. */
|
||||
#donaInlineScene[hidden] { display:none !important; }
|
||||
#donaInlineScene {
|
||||
position:fixed;
|
||||
z-index:55;
|
||||
top:clamp(92px,12vh,150px);
|
||||
right:clamp(18px,4vw,72px);
|
||||
bottom:clamp(108px,13vh,150px);
|
||||
left:clamp(43%,46vw,54%);
|
||||
display:grid;
|
||||
grid-template-columns:0 minmax(0,1fr);
|
||||
color:var(--dona-text, #eff3ff);
|
||||
pointer-events:none;
|
||||
font-family:inherit;
|
||||
}
|
||||
#donaInlineScene .dona-inline-right {
|
||||
pointer-events:auto;
|
||||
min-width:0;
|
||||
max-width:min(44vw, 760px);
|
||||
overflow:hidden;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
#donaInlineScene .dona-inline-left { visibility:hidden; }
|
||||
#donaInlineScene .dona-inline-top {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:space-between;
|
||||
gap:16px;
|
||||
padding-bottom:2px;
|
||||
}
|
||||
#donaInlineScene .dona-inline-eyebrow {
|
||||
color:#95a9cf;
|
||||
font-weight:700;
|
||||
font-size:11px;
|
||||
letter-spacing:.13em;
|
||||
opacity:.92;
|
||||
}
|
||||
#donaInlineScene .dona-inline-close {
|
||||
background:rgba(255,255,255,.07);
|
||||
color:#e7efff;
|
||||
border:1px solid rgba(175,202,241,.3);
|
||||
font:inherit;
|
||||
font-size:24px;
|
||||
line-height:1;
|
||||
border-radius:50%;
|
||||
width:36px;
|
||||
height:36px;
|
||||
cursor:pointer;
|
||||
flex-shrink:0;
|
||||
}
|
||||
#donaInlineScene .dona-inline-close:hover,
|
||||
#donaInlineScene .dona-inline-close:focus-visible {
|
||||
background:rgba(255,255,255,.14);
|
||||
outline-color:#9fcafa;
|
||||
}
|
||||
#donaInlineScene .dona-inline-heading {
|
||||
font-size:clamp(24px,2.8vw,38px);
|
||||
font-weight:700;
|
||||
line-height:1.22;
|
||||
margin:6px 0 14px;
|
||||
}
|
||||
#donaInlineScene .dona-inline-heading[hidden] { display:none !important; }
|
||||
#donaInlineScene .dona-inline-content {
|
||||
overflow-y:auto;
|
||||
overscroll-behavior:contain;
|
||||
scrollbar-width:thin;
|
||||
padding:0 12px 18px 0;
|
||||
min-height:0;
|
||||
font-size:clamp(14px,1.04vw,17px);
|
||||
line-height:1.65;
|
||||
white-space:normal;
|
||||
}
|
||||
#donaInlineScene .dona-inline-paragraph {
|
||||
margin:0 0 13px;
|
||||
white-space:pre-wrap;
|
||||
overflow-wrap:anywhere;
|
||||
color:var(--dona-text-muted, #d0daeb);
|
||||
}
|
||||
#donaInlineScene .dona-inline-meta { color:#9fc9ed; margin:0 0 14px; }
|
||||
#donaInlineScene .dona-inline-section { padding:0 0 12px; margin:0; }
|
||||
#donaInlineScene .dona-inline-subheading {
|
||||
font-size:clamp(15px,1.22vw,19px);
|
||||
color:#eef5ff;
|
||||
margin:14px 0 8px;
|
||||
font-weight:650;
|
||||
}
|
||||
#donaInlineScene .dona-inline-list { margin:0 0 12px; padding-left:1.4em; color:#d0daeb; overflow-wrap:anywhere; }
|
||||
#donaInlineScene .dona-inline-list li { margin:0 0 4px; }
|
||||
#donaInlineScene .dona-inline-more { margin:10px 0; color:#b7d5ff; }
|
||||
#donaInlineScene .dona-inline-more summary { cursor:pointer; }
|
||||
#donaInlineScene code { font-size:.93em; background:rgba(255,255,255,.08); border-radius:4px; padding:1px 4px; }
|
||||
.dona-inline-identity-shift {
|
||||
translate:var(--dona-inline-shift-x,0px) var(--dona-inline-shift-y,0px);
|
||||
scale:var(--dona-inline-scale,1);
|
||||
transition:translate .55s ease, scale .55s ease;
|
||||
transform-origin:center center;
|
||||
will-change:translate, scale;
|
||||
}
|
||||
.dona-inline-suppressed-modal { display:none !important; }
|
||||
body.dona-inline-active #dona-hermes-live-v1 { display:none !important; }
|
||||
@media(max-width:840px) {
|
||||
#donaInlineScene {
|
||||
top:clamp(210px,31vh,370px);
|
||||
left:18px;
|
||||
right:18px;
|
||||
bottom:clamp(95px,11vh,160px);
|
||||
display:block;
|
||||
}
|
||||
#donaInlineScene .dona-inline-right { max-width:none; }
|
||||
#donaInlineScene .dona-inline-heading { font-size:clamp(21px,4.2vw,30px); }
|
||||
#donaInlineScene .dona-inline-content { font-size:15px; padding-right:6px; }
|
||||
}
|
||||
@media (prefers-reduced-motion:reduce) {
|
||||
.dona-inline-identity-shift { transition:none; }
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
/* DONA_INLINE_INDEX_V2 - Réponses dans l'index, sans modal ni carte opaque.
|
||||
* V2 : orbe/vagues plus petits et à gauche, statut unifié dans la zone existante.
|
||||
*/
|
||||
(() => {
|
||||
'use strict';
|
||||
if (window.__donaInlineIndexV2) return;
|
||||
window.__donaInlineIndexV2 = true;
|
||||
|
||||
const MAX = 24000;
|
||||
const $ = id => document.getElementById(id);
|
||||
const node = (tag, cls, value) => {
|
||||
const n = document.createElement(tag);
|
||||
if (cls) n.className = cls;
|
||||
if (value !== undefined && value !== null) n.textContent = String(value);
|
||||
return n;
|
||||
};
|
||||
const cap = (text, len = MAX) => String(text ?? '').slice(0, len);
|
||||
const state = { kind: '', id: null, text: '', rich: false, recentRich: 0,
|
||||
shifted: null, socket: null, active: false,
|
||||
displayObserver: null, scanTimer: 0,
|
||||
statusNode: null, statusOriginal: '', statusCaptured: false };
|
||||
|
||||
function setup() {
|
||||
if ($('donaInlineScene')) return;
|
||||
const scene = node('section', 'dona-inline-scene');
|
||||
scene.id = 'donaInlineScene';
|
||||
scene.hidden = true;
|
||||
scene.setAttribute('aria-label', 'Réponse de Dona dans l’accueil');
|
||||
const side = node('div', 'dona-inline-left');
|
||||
side.append(node('div', 'dona-inline-left-label', 'Dona'));
|
||||
const right = node('article', 'dona-inline-right');
|
||||
const top = node('div', 'dona-inline-top');
|
||||
const eyebrow = node('span', 'dona-inline-eyebrow', 'RÉPONSE · DONA');
|
||||
const close = node('button', 'dona-inline-close', '×');
|
||||
close.type = 'button';
|
||||
close.title = 'Masquer la réponse';
|
||||
close.setAttribute('aria-label', 'Masquer la réponse et revenir à l’accueil');
|
||||
close.addEventListener('click', hide);
|
||||
top.append(eyebrow, close);
|
||||
const heading = node('h2', 'dona-inline-heading');
|
||||
heading.id = 'donaInlineHeading';
|
||||
const content = node('div', 'dona-inline-content');
|
||||
content.id = 'donaInlineContent';
|
||||
content.setAttribute('role', 'region');
|
||||
content.setAttribute('aria-label', 'Contenu de la réponse');
|
||||
right.append(top, heading, content);
|
||||
scene.append(side, right);
|
||||
document.body.append(scene);
|
||||
window.addEventListener('resize', () => { if (state.active) positionIdentity(); }, {passive:true});
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape' && state.active && !document.querySelector('[role="dialog"]:not([hidden])')) hide();
|
||||
});
|
||||
attachEvents();
|
||||
observeStandaloneResponse();
|
||||
}
|
||||
|
||||
function setHeading(title) {
|
||||
const h = $('donaInlineHeading');
|
||||
if (!h) return;
|
||||
const clean = cap(title || '', 140).trim();
|
||||
h.textContent = clean;
|
||||
h.hidden = !clean;
|
||||
}
|
||||
function statusCandidates() {
|
||||
const selectors = [
|
||||
'#donaStatusText', '#hermesStatus', '#voiceStatus', '#assistantStatus', '#statusText',
|
||||
'.dona-status-text', '.assistant-status', '.status-text', '.voice-status', '.hermes-status',
|
||||
'[data-dona-status]', '[data-hermes-status]', '[data-status-role="assistant"]'
|
||||
];
|
||||
for (const sel of selectors) {
|
||||
const el = document.querySelector(sel);
|
||||
if (el && !el.closest('#donaInlineScene, .dv9-overlay, .d8-overlay') && getComputedStyle(el).display !== 'none') return el;
|
||||
}
|
||||
const all = [...document.querySelectorAll('div,span,p,small,strong')];
|
||||
return all.find(el => {
|
||||
if (el.closest('#donaInlineScene, .dv9-overlay, .d8-overlay')) return false;
|
||||
if (getComputedStyle(el).display === 'none') return false;
|
||||
const t = (el.textContent || '').trim();
|
||||
return /Hermes prépare sa réponse|Dona répond|Dona parle|Réponse reçue|Prête?/i.test(t);
|
||||
}) || null;
|
||||
}
|
||||
function setStatus(text) {
|
||||
const el = statusCandidates();
|
||||
if (!el) return;
|
||||
if (!state.statusCaptured || state.statusNode !== el) {
|
||||
state.statusNode = el;
|
||||
state.statusOriginal = el.textContent || '';
|
||||
state.statusCaptured = true;
|
||||
}
|
||||
el.textContent = String(text || '').trim();
|
||||
}
|
||||
function restoreStatus() {
|
||||
if (state.statusNode && state.statusCaptured) {
|
||||
state.statusNode.textContent = state.statusOriginal;
|
||||
}
|
||||
}
|
||||
|
||||
function show(kind, title) {
|
||||
const scene = $('donaInlineScene');
|
||||
if (!scene) return;
|
||||
scene.hidden = false;
|
||||
state.active = true;
|
||||
state.kind = kind;
|
||||
document.body.classList.add('dona-inline-active');
|
||||
setHeading(title);
|
||||
requestAnimationFrame(positionIdentity);
|
||||
}
|
||||
function clearContent() { $('donaInlineContent').replaceChildren(); }
|
||||
function hide() {
|
||||
state.active = false;
|
||||
$('donaInlineScene').hidden = true;
|
||||
document.body.classList.remove('dona-inline-active');
|
||||
if (state.shifted) {
|
||||
state.shifted.classList.remove('dona-inline-identity-shift');
|
||||
state.shifted.style.removeProperty('--dona-inline-shift-x');
|
||||
state.shifted.style.removeProperty('--dona-inline-shift-y');
|
||||
state.shifted.style.removeProperty('--dona-inline-scale');
|
||||
state.shifted = null;
|
||||
}
|
||||
restoreStatus();
|
||||
for (const el of document.querySelectorAll('.dona-inline-suppressed-modal')) el.classList.remove('dona-inline-suppressed-modal');
|
||||
}
|
||||
|
||||
function identityCandidate() {
|
||||
const root = $('alfredMainV1') || document.body;
|
||||
const preferred = [
|
||||
'#donaWave', '#donaWaves', '#donaOrb', '#alfredOrb', '#alfredWave',
|
||||
'.av-orb-wrap', '.av-orb', '.av-wave-wrap', '.av-waves',
|
||||
'.dona-wave-stage', '.dona-waves', '.dona-orb', '.orb-container',
|
||||
'[data-dona-visualizer]', '[data-dona-orb]', '[data-dona-waves]'
|
||||
];
|
||||
const candidates = preferred.flatMap(sel => [...root.querySelectorAll(sel)]);
|
||||
if (!candidates.length) {
|
||||
const all = [...root.querySelectorAll('[class], [id]')].slice(0, 800);
|
||||
candidates.push(...all.filter(el => {
|
||||
const label = String(el.className?.baseVal || el.className || '') + ' ' + (el.id || '');
|
||||
return /(?:^|[\s_-])(?:dona|alfred|av)?[\s_-]?(?:orb|orbe|waves?|waveform)(?:[\s_-]|$)/i.test(label);
|
||||
}));
|
||||
}
|
||||
for (const el of candidates) {
|
||||
if (el.closest('#donaInlineScene, .dv9-overlay, .d8-overlay, #dona-hermes-live-v1')) continue;
|
||||
if (el.matches('button, input, textarea, dialog')) continue;
|
||||
const rect = el.getBoundingClientRect();
|
||||
if (rect.width < 50 || rect.height < 20 || rect.width > innerWidth * .98) continue;
|
||||
if (getComputedStyle(el).display === 'none') continue;
|
||||
return el;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function positionIdentity() {
|
||||
if (!state.active) return;
|
||||
const candidate = identityCandidate();
|
||||
if (!candidate) return;
|
||||
if (state.shifted && state.shifted !== candidate) {
|
||||
state.shifted.classList.remove('dona-inline-identity-shift');
|
||||
state.shifted.style.removeProperty('--dona-inline-shift-x');
|
||||
state.shifted.style.removeProperty('--dona-inline-shift-y');
|
||||
state.shifted.style.removeProperty('--dona-inline-scale');
|
||||
}
|
||||
const label = String(candidate.className?.baseVal || candidate.className || '') + ' ' + (candidate.id || '');
|
||||
const waveLike = /wave|vague/i.test(label);
|
||||
const oldX = parseFloat(candidate.style.getPropertyValue('--dona-inline-shift-x')) || 0;
|
||||
const oldY = parseFloat(candidate.style.getPropertyValue('--dona-inline-shift-y')) || 0;
|
||||
const rect = candidate.getBoundingClientRect();
|
||||
const centreX = rect.left + rect.width / 2 - oldX;
|
||||
const centreY = rect.top + rect.height / 2 - oldY;
|
||||
const portrait = matchMedia('(max-width: 840px)').matches;
|
||||
const desiredX = portrait ? innerWidth * .50 : innerWidth * .18;
|
||||
const desiredY = portrait ? innerHeight * .27 : innerHeight * .50;
|
||||
const x = Math.max(-innerWidth, Math.min(innerWidth, desiredX - centreX));
|
||||
const y = Math.max(-innerHeight, Math.min(innerHeight, desiredY - centreY));
|
||||
const scale = portrait ? (waveLike ? .46 : .34) : (waveLike ? .54 : .32);
|
||||
candidate.style.setProperty('--dona-inline-shift-x', x.toFixed(1) + 'px');
|
||||
candidate.style.setProperty('--dona-inline-shift-y', y.toFixed(1) + 'px');
|
||||
candidate.style.setProperty('--dona-inline-scale', String(scale));
|
||||
candidate.classList.add('dona-inline-identity-shift');
|
||||
state.shifted = candidate;
|
||||
}
|
||||
|
||||
function paragraph(text, cls) {
|
||||
const p = node('p', cls || 'dona-inline-paragraph');
|
||||
const chunks = cap(text, 12000).split(/(\*\*[^*]+\*\*|`[^`]+`)/g);
|
||||
for (const chunk of chunks) {
|
||||
if (/^\*\*[^*]+\*\*$/.test(chunk)) p.append(node('strong', '', chunk.slice(2, -2)));
|
||||
else if (/^`[^`]+`$/.test(chunk)) p.append(node('code', '', chunk.slice(1, -1)));
|
||||
else p.append(document.createTextNode(chunk));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
function appendProse(text) {
|
||||
const container = $('donaInlineContent');
|
||||
const lines = cap(text).replace(/\r/g, '').split(/\n{2,}/);
|
||||
for (const item of lines.slice(0, 90)) {
|
||||
const p = item.trim();
|
||||
if (!p) continue;
|
||||
if (/^#{1,3}\s+/.test(p)) container.append(node('h3', 'dona-inline-subheading', p.replace(/^#{1,3}\s+/, '')));
|
||||
else container.append(paragraph(p));
|
||||
}
|
||||
}
|
||||
function renderText(text, heading = '') {
|
||||
state.rich = false;
|
||||
state.text = cap(text);
|
||||
show('text', heading);
|
||||
clearContent();
|
||||
appendProse(state.text);
|
||||
setStatus('Dona répond…');
|
||||
}
|
||||
function renderStream(event) {
|
||||
if (!event || !event.type || featureOverlayOpen()) return;
|
||||
if (event.type === 'start') {
|
||||
state.id = event.id;
|
||||
state.rich = false;
|
||||
state.text = '';
|
||||
show('stream', '');
|
||||
clearContent();
|
||||
setStatus('Hermes prépare sa réponse…');
|
||||
} else if (state.id && event.id !== state.id) return;
|
||||
else if (event.type === 'delta') {
|
||||
if (state.rich) return;
|
||||
state.text = cap(state.text + String(event.text || ''));
|
||||
show('stream', '');
|
||||
setStatus('Dona répond…');
|
||||
clearContent();
|
||||
appendProse(state.text);
|
||||
} else if (event.type === 'tool') {
|
||||
if (state.rich) return;
|
||||
show('stream', '');
|
||||
setStatus('Hermes prépare sa réponse…');
|
||||
if (!state.text) {
|
||||
clearContent();
|
||||
$('donaInlineContent').append(paragraph('Consultation : ' + cap(event.name, 90)));
|
||||
}
|
||||
} else if (event.type === 'error') {
|
||||
if (!state.rich) {
|
||||
show('stream', '');
|
||||
setStatus('Une erreur est survenue');
|
||||
}
|
||||
}
|
||||
}
|
||||
function list(title, items, ordered = false) {
|
||||
if (!Array.isArray(items) || !items.length) return;
|
||||
const wrap = node('section', 'dona-inline-section');
|
||||
wrap.append(node('h3', 'dona-inline-subheading', title));
|
||||
const ul = node(ordered ? 'ol' : 'ul', 'dona-inline-list');
|
||||
items.slice(0, 50).forEach(item => ul.append(node('li', '', typeof item === 'string' ? cap(item, 500) : cap(item?.title || item?.name || item?.label || JSON.stringify(item), 500))));
|
||||
wrap.append(ul);
|
||||
$('donaInlineContent').append(wrap);
|
||||
}
|
||||
function featureOverlayOpen() {
|
||||
const ids = ['donaSuiteV9', 'donaDynamicV8'];
|
||||
return ids.some(id => {
|
||||
const el = $(id);
|
||||
return el && !el.hidden && getComputedStyle(el).display !== 'none';
|
||||
});
|
||||
}
|
||||
function renderRecipe(recipe) {
|
||||
const name = cap(recipe.title || recipe.name || 'Recette', 160);
|
||||
show('suite', name);
|
||||
setStatus('Dona répond…');
|
||||
clearContent();
|
||||
const d = recipe.duration || recipe.time || recipe.minutes || recipe.duration_min || recipe.duration_minutes;
|
||||
if (d) $('donaInlineContent').append(paragraph('Durée : ' + cap(d, 50) + (typeof d === 'number' ? ' min' : ''), 'dona-inline-meta'));
|
||||
list('Ingrédients', recipe.ingredients);
|
||||
let steps = recipe.steps || recipe.preparation || recipe.instructions || recipe.method;
|
||||
if (typeof steps === 'string') steps = steps.split(/\n+/).filter(Boolean);
|
||||
list('Préparation', steps, true);
|
||||
}
|
||||
function renderSuite(result) {
|
||||
if (!result || typeof result !== 'object' || featureOverlayOpen()) return;
|
||||
state.recentRich = Date.now();
|
||||
state.rich = true;
|
||||
const kind = String(result.kind || '');
|
||||
if (kind === 'recipe') {
|
||||
const recipes = Array.isArray(result.recipes) ? result.recipes : [];
|
||||
if (recipes.length) {
|
||||
renderRecipe(recipes[0]);
|
||||
if (recipes.length > 1) {
|
||||
const summary = node('details', 'dona-inline-more');
|
||||
summary.append(node('summary', '', `Voir ${recipes.length - 1} autre(s) recette(s)`));
|
||||
const ul = node('ul', 'dona-inline-list');
|
||||
recipes.slice(1, 12).forEach(rec => ul.append(node('li', '', cap(rec.title || rec.name || 'Recette', 140))));
|
||||
summary.append(ul); $('donaInlineContent').append(summary);
|
||||
}
|
||||
} else renderText(result.speech || 'Aucune recette trouvée.', result.title || 'Recettes');
|
||||
return;
|
||||
}
|
||||
show('suite', result.title || 'Réponse de Dona');
|
||||
setStatus('Dona répond…');
|
||||
clearContent();
|
||||
if (result.speech) appendProse(result.speech);
|
||||
if (kind === 'menu' && result.menu) {
|
||||
const m = result.menu;
|
||||
if (Array.isArray(m)) list('Menus', m);
|
||||
else {
|
||||
list('Menus', m.days || m.meals || m.menu || []);
|
||||
list('Liste de courses', m.shopping_list || m.groceries || []);
|
||||
}
|
||||
} else if (kind === 'briefing' || kind === 'daily') {
|
||||
list('Événements', result.briefing?.events);
|
||||
if (result.briefing?.weather) appendProse(JSON.stringify(result.briefing.weather));
|
||||
} else if (kind === 'documents') list('Documents', result.documents?.found);
|
||||
else if (kind === 'memories') list('Souvenirs', result.memories);
|
||||
else if (kind === 'monitor') list('Supervision', result.monitor?.items || result.monitor?.warnings || []);
|
||||
else if (kind === 'child') list('Questions', result.quiz?.questions || result.quiz || []);
|
||||
else if (kind === 'routine') list('Actions prévues', result.routine?.actions || result.routine || []);
|
||||
}
|
||||
function renderVisual(card) {
|
||||
if (!card || card.schema !== 'dona.visual.v1' || featureOverlayOpen()) return;
|
||||
if (Date.now() - state.recentRich < 1200 && card.type === 'recipe') return;
|
||||
if (card.type === 'recipe') { state.rich = true; renderRecipe(card); }
|
||||
else {
|
||||
state.rich = true;
|
||||
show('visual', card.title || 'Dona');
|
||||
setStatus('Dona répond…');
|
||||
clearContent();
|
||||
if (card.subtitle) appendProse(card.subtitle);
|
||||
list('Informations', card.details);
|
||||
}
|
||||
}
|
||||
function renderFinal(data) {
|
||||
if (!data || typeof data !== 'object' || featureOverlayOpen()) return;
|
||||
if (data.type === 'dona_dynamic') return;
|
||||
if (data.type === 'dona_visual_card') return renderVisual(data);
|
||||
if (Date.now() - state.recentRich < 2800) return;
|
||||
const body = data.content && typeof data.content === 'object' ? data.content : data;
|
||||
const text = body.text || body.speech || (typeof body.content === 'string' ? body.content : '');
|
||||
if (typeof text !== 'string' || !text.trim()) return;
|
||||
if (state.active && state.text && text.trim() === state.text.trim()) return;
|
||||
renderText(text, '');
|
||||
}
|
||||
|
||||
function observeStandaloneResponse() {
|
||||
if (state.displayObserver) return;
|
||||
function inspect() {
|
||||
for (const el of document.querySelectorAll('[role="dialog"], .dona-response-overlay, .dona-display-overlay, [class*="response-overlay"], [class*="dona-display"], [id*="donaDisplay"], [id*="donaResponse"]')) {
|
||||
if (el.closest('#donaInlineScene') || el.classList.contains('dona-inline-suppressed-modal')) continue;
|
||||
if (el.hidden || getComputedStyle(el).display === 'none') continue;
|
||||
const text = (el.textContent || '').slice(0, 3000);
|
||||
if (!/R[ÉE]PONSE\s*[·•-]\s*DONA/i.test(text) || !/Hermes|réponse complète/i.test(text)) continue;
|
||||
if (!state.active) {
|
||||
const parts = [...el.querySelectorAll('h1,h2,h3,p')].map(e => e.textContent.trim()).filter(Boolean);
|
||||
renderText(parts.join('\n\n').slice(0, MAX), '');
|
||||
}
|
||||
el.classList.add('dona-inline-suppressed-modal');
|
||||
}
|
||||
}
|
||||
state.displayObserver = new MutationObserver(() => {
|
||||
if (state.scanTimer) return;
|
||||
state.scanTimer = setTimeout(() => { state.scanTimer = 0; inspect(); }, 300);
|
||||
});
|
||||
state.displayObserver.observe(document.body, {childList:true, subtree:true});
|
||||
inspect();
|
||||
}
|
||||
function attachEvents() {
|
||||
const start = Date.now();
|
||||
function connect() {
|
||||
const socket = window.alfredSocket || (typeof window.io === 'function' ? window.io({reconnection:true}) : null);
|
||||
if (!socket) {
|
||||
if (Date.now() - start < 15000) setTimeout(connect, 150);
|
||||
return;
|
||||
}
|
||||
state.socket = socket;
|
||||
socket.on('dona_suite_v9', renderSuite);
|
||||
socket.on('dona_visual_card', renderVisual);
|
||||
socket.on('alfred_render', renderFinal);
|
||||
socket.on('dona_hermes_stream', renderStream);
|
||||
}
|
||||
connect();
|
||||
}
|
||||
window.DonaInlineIndexV2 = {hide, showText: renderText};
|
||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', setup, {once:true});
|
||||
else setup();
|
||||
})();
|
||||
@@ -146,7 +146,7 @@ function init(){
|
||||
else if(++attempts>80)clearInterval(interval);
|
||||
},150);
|
||||
const socket=window.alfredSocket;
|
||||
socket?.on('dona_suite_v9',result=>render(result,lastPrompt));
|
||||
socket?.on('dona_suite_v9',result=>{if(opened)render(result,lastPrompt);});
|
||||
}
|
||||
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init,{once:true});else init();
|
||||
window.DonaSuiteV9={open,close,render,ask};
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/dona-hermes-stream-v1.css') }}">
|
||||
<!-- DONA VISUAL CSS V1 -->
|
||||
<link rel="stylesheet" href="/static/css/dona-visuals-v1.css">
|
||||
<!-- DONA_INLINE_INDEX_V1 CSS -->
|
||||
<link rel="stylesheet" href="/static/css/dona-inline-index-v1.css?v=2">
|
||||
</head>
|
||||
<body>
|
||||
<main class="alfred-shell">
|
||||
@@ -270,5 +272,7 @@
|
||||
<script defer src="{{ url_for('static', filename='js/dona-hermes-stream-v1.js') }}"></script>
|
||||
<!-- DONA VISUAL JS V1 -->
|
||||
<script defer src="/static/js/dona-visuals-v1.js"></script>
|
||||
<!-- DONA_INLINE_INDEX_V1 JS -->
|
||||
<script defer src="/static/js/dona-inline-index-v1.js?v=2"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user