- after-request → after-settle: scrollChat() was firing before HTMX swapped the new message into the DOM, so the chat log didn't scroll to the new message. after-settle fires post-swap, post-settle. - hx-sync="this:drop": prevents duplicate submissions if the user taps SEND a second time while a slow Ollama response is in flight. - hx-disabled-elt="find button": disables SEND button visually during a pending request; paired with hx-sync for belt-and-suspenders. - autocorrect="off" autocapitalize="none" spellcheck="false": iOS autocorrect mangles model names (llama3.2 etc.) and autocapitalize uppercases every message's first word. Both are wrong for a terminal- style chat interface. - enterkeyhint="send": tells the iOS/Android soft keyboard to label the Return key "Send" instead of the generic return arrow. https://claude.ai/code/session_01M4L3R98N5fgXFZRvV8X9b6
88 lines
2.5 KiB
HTML
88 lines
2.5 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block content %}
|
|
|
|
<div class="sidebar">
|
|
|
|
<!-- Agents -->
|
|
<div class="panel">
|
|
<div class="panel-header">// AGENTS</div>
|
|
<div class="panel-body">
|
|
<div class="agent-card">
|
|
<div class="agent-card-header">
|
|
<span class="status-dot amber"></span>
|
|
<span class="agent-name">TIMMY</span>
|
|
</div>
|
|
<div class="agent-meta">
|
|
<span class="meta-key">TYPE</span> <span class="meta-val">sovereign</span><br>
|
|
<span class="meta-key">MODEL</span> <span class="meta-val">llama3.2</span><br>
|
|
<span class="meta-key">BACKEND</span> <span class="meta-val">ollama</span><br>
|
|
<span class="meta-key">VERSION</span> <span class="meta-val">1.0.0</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- System Health (HTMX polled) -->
|
|
<div class="panel"
|
|
hx-get="/health/status"
|
|
hx-trigger="load, every 30s"
|
|
hx-target="this"
|
|
hx-swap="innerHTML">
|
|
<div class="panel-header">// SYSTEM HEALTH</div>
|
|
<div class="panel-body">
|
|
<div class="health-row">
|
|
<span class="health-label">LOADING...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Chat Panel -->
|
|
<div class="panel chat-panel">
|
|
<div class="panel-header">// TIMMY INTERFACE</div>
|
|
|
|
<div class="chat-log" id="chat-log">
|
|
<div class="chat-message agent">
|
|
<div class="msg-meta">TIMMY // SYSTEM</div>
|
|
<div class="msg-body">Mission Control initialized. Timmy ready — awaiting input.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chat-input-bar">
|
|
<form hx-post="/agents/timmy/chat"
|
|
hx-target="#chat-log"
|
|
hx-swap="beforeend"
|
|
hx-indicator="#send-indicator"
|
|
hx-sync="this:drop"
|
|
hx-disabled-elt="find button"
|
|
hx-on::after-settle="this.reset(); scrollChat()"
|
|
style="display:flex; flex:1; gap:8px;">
|
|
<input type="text"
|
|
name="message"
|
|
placeholder="send a message to timmy..."
|
|
autocomplete="off"
|
|
autocorrect="off"
|
|
autocapitalize="none"
|
|
spellcheck="false"
|
|
enterkeyhint="send"
|
|
required />
|
|
<button type="submit">
|
|
SEND
|
|
<span id="send-indicator" class="htmx-indicator">▋</span>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function scrollChat() {
|
|
const log = document.getElementById('chat-log');
|
|
log.scrollTop = log.scrollHeight;
|
|
}
|
|
scrollChat();
|
|
</script>
|
|
|
|
{% endblock %}
|