Offer Troubleshoot as a profile, and say plainly when it has no log
This commit is contained in:
@@ -238,6 +238,9 @@ function vv_ai_chat_assets(): void {
|
||||
white-space:nowrap; flex:1; min-width:0; }
|
||||
.vv-ai-crow.active .vv-ai-crow-t { color:#9bd; }
|
||||
.vv-ai-crow-m { font-size:9px; color:#3a3a3a; font-family:monospace; flex-shrink:0; }
|
||||
.vv-ai-chat { transition:height .14s ease; }
|
||||
.vv-ai-grow { font-size:13px !important; line-height:1; padding:4px 9px !important; }
|
||||
.vv-ai-grow-on { color:#9bd !important; border-color:#2d4a6a !important; }
|
||||
.vv-ai-crow-s { font-size:9px; color:#5c7cfa; font-family:monospace; }
|
||||
.vv-ai-c .vv-ai-crow-s { color:#7a9ae0; }
|
||||
.vv-ai-crow-x { font-size:11px; color:#333; flex-shrink:0; padding:0 2px; visibility:hidden; }
|
||||
@@ -652,6 +655,36 @@ vv_ai_profiles_script();
|
||||
});
|
||||
const newBtn = $('new'); if (newBtn) newBtn.addEventListener('click', newChat);
|
||||
|
||||
// ── Expand / collapse ────────────────────────────────────────────────
|
||||
// Both heights come from the markup, so the page decides them and this only switches
|
||||
// between them. Remembered per instance: the dashboard chat and the tab's are different
|
||||
// sizes for different reasons, and a shared key would make one of them wrong.
|
||||
//
|
||||
// Scroll position is pinned to the bottom afterwards. Growing the box leaves the transcript
|
||||
// scrolled where it was, which puts the newest answer off-screen at the exact moment you
|
||||
// asked for more room to read it.
|
||||
const growBtn = $('grow');
|
||||
if (growBtn) {
|
||||
const el = chatEl();
|
||||
const base = el.dataset.h || '';
|
||||
const tall = el.dataset.hTall || '';
|
||||
const KEY = 'vv-ai-tall-' + P;
|
||||
const apply = big => {
|
||||
if (!base || !tall) return;
|
||||
el.style.height = big ? tall : base;
|
||||
growBtn.textContent = big ? '⤡' : '⤢';
|
||||
growBtn.title = big ? 'Back to the smaller view' : 'Give the conversation more room';
|
||||
growBtn.classList.toggle('vv-ai-grow-on', big);
|
||||
scroll();
|
||||
};
|
||||
growBtn.addEventListener('click', () => {
|
||||
const big = el.style.height !== tall;
|
||||
localStorage.setItem(KEY, big ? '1' : '0');
|
||||
apply(big);
|
||||
});
|
||||
if (localStorage.getItem(KEY) === '1') apply(true);
|
||||
}
|
||||
|
||||
// Surface any script error into the transcript. Without it a throw anywhere on the page is
|
||||
// invisible unless the console happens to be open, which is how a silent hang survives a
|
||||
// diagnosis session.
|
||||
@@ -759,7 +792,12 @@ vv_ai_profiles_script();
|
||||
// profile which profile button starts active
|
||||
// compact card-sized chrome, for a chat living inside a Monitor card
|
||||
// height transcript height; a fixed value in compact mode, since a card in a grid row
|
||||
// cannot grow with its content without dragging the row's other cards with it
|
||||
// cannot grow with its content without dragging the row's other cards with it.
|
||||
// Setting it also adds the expand control — a fixed height is exactly the situation
|
||||
// where you sometimes want more room, and there is nothing to expand without one.
|
||||
// tall the expanded height. Defaults to 2.5x height, which is the point where a long
|
||||
// answer stops needing a scroll for most questions without the card swallowing the
|
||||
// page it sits on
|
||||
// empty empty-state text
|
||||
// controls extra markup dropped into the composer's control strip
|
||||
function vv_ai_chat_markup(string $prefix, array $o = []): void {
|
||||
@@ -767,8 +805,21 @@ function vv_ai_chat_markup(string $prefix, array $o = []): void {
|
||||
$compact = !empty($o['compact']);
|
||||
$height = $o['height'] ?? '';
|
||||
$empty = $o['empty'] ?? 'Ask Varaverk about itself.';
|
||||
// 2.5x by default, computed here so the page can override with a value that suits its layout
|
||||
// rather than the include guessing at one it cannot see.
|
||||
$tall = $o['tall'] ?? '';
|
||||
if ($height !== '' && $tall === '' && preg_match('/^(\d+(?:\.\d+)?)(px|vh|em|rem)$/', $height, $hm)) {
|
||||
$n = (float)$hm[1] * 2.5;
|
||||
// vh is a share of the viewport, so 2.5x runs off the bottom of the screen — an expand
|
||||
// that puts the composer out of reach is worse than no expand. Clamped to something that
|
||||
// still leaves the page scrollable to its own controls.
|
||||
if ($hm[2] === 'vh') $n = min($n, 85);
|
||||
$tall = rtrim(rtrim(number_format($n, 2, '.', ''), '0'), '.') . $hm[2];
|
||||
}
|
||||
$style = $height !== '' ? ' style="height:' . htmlspecialchars($height, ENT_QUOTES)
|
||||
. ';max-height:none;"' : '';
|
||||
. ';max-height:none;"'
|
||||
. ' data-h="' . htmlspecialchars($height, ENT_QUOTES) . '"'
|
||||
. ' data-h-tall="' . htmlspecialchars($tall, ENT_QUOTES) . '"' : '';
|
||||
?>
|
||||
<div class="vv-ai-chatwrap<?= $compact ? ' vv-ai-c' : '' ?>" style="display:flex;flex-direction:column;gap:<?= $compact ? '4px' : '12px' ?>;min-width:0;">
|
||||
|
||||
@@ -789,6 +840,10 @@ function vv_ai_chat_markup(string $prefix, array $o = []): void {
|
||||
placeholder="<?= htmlspecialchars($o['placeholder'] ?? 'Ask anything — questions about this install route to the assistant on their own.', ENT_QUOTES) ?>"></textarea>
|
||||
<div class="vv-ai-ctrls">
|
||||
<?= $o['controls'] ?? '' ?>
|
||||
<?php if ($height !== ''): ?>
|
||||
<button class="vv-ai-btn ghost vv-ai-grow" id="<?= $p ?>-grow" type="button"
|
||||
title="Give the conversation more room">⤢</button>
|
||||
<?php endif; ?>
|
||||
<button class="vv-ai-btn ghost" id="<?= $p ?>-new" type="button">New</button>
|
||||
<span class="vv-ai-hint">Ctrl+Enter to send</span>
|
||||
<button class="vv-ai-btn" id="<?= $p ?>-send" type="button">Ask</button>
|
||||
|
||||
Reference in New Issue
Block a user