chore: refine control ui links and composer

This commit is contained in:
Peter Steinberger
2026-01-08 12:04:11 +01:00
parent d42444928b
commit 03605bfa6a
6 changed files with 59 additions and 3 deletions

View File

@@ -5,6 +5,7 @@
- WhatsApp: group `/model list` output by provider for scannability. (#456) - thanks @mcinteerj - WhatsApp: group `/model list` output by provider for scannability. (#456) - thanks @mcinteerj
- Hooks: allow per-hook model overrides for webhook/Gmail runs (e.g. GPT 5 Mini). - Hooks: allow per-hook model overrides for webhook/Gmail runs (e.g. GPT 5 Mini).
- Control UI: logs tab opens at the newest entries (bottom). - Control UI: logs tab opens at the newest entries (bottom).
- Control UI: add Docs link, remove chat composer divider, and add New session button.
## 2026.1.8 ## 2026.1.8

View File

@@ -952,7 +952,6 @@
margin-top: 0; margin-top: 0;
padding-top: 12px; padding-top: 12px;
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, var(--panel) 35%); background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, var(--panel) 35%);
border-top: 1px solid var(--border);
} }
.shell--chat-focus .chat-compose { .shell--chat-focus .chat-compose {

View File

@@ -199,6 +199,31 @@
); );
} }
.docs-link {
position: fixed;
right: calc(var(--shell-pad) + 4px);
bottom: calc(var(--shell-pad) + 4px);
z-index: 30;
padding: 8px 12px;
border-radius: 999px;
border: 1px solid var(--border);
background: rgba(0, 0, 0, 0.35);
color: var(--text);
font-size: 12px;
letter-spacing: 0.4px;
text-transform: uppercase;
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.3);
transition: transform 140ms ease, border-color 140ms ease,
background 140ms ease, color 140ms ease;
}
.docs-link:hover {
transform: translateY(-2px);
border-color: rgba(245, 159, 74, 0.5);
background: rgba(245, 159, 74, 0.18);
color: var(--text);
}
.content-header { .content-header {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;

View File

@@ -195,7 +195,7 @@ export type AppViewState = {
handleWhatsAppWait: () => Promise<void>; handleWhatsAppWait: () => Promise<void>;
handleWhatsAppLogout: () => Promise<void>; handleWhatsAppLogout: () => Promise<void>;
handleTelegramSave: () => Promise<void>; handleTelegramSave: () => Promise<void>;
handleSendChat: () => Promise<void>; handleSendChat: (messageOverride?: string, opts?: { restoreDraft?: boolean }) => Promise<void>;
resetToolStream: () => void; resetToolStream: () => void;
handleLogsScroll: (event: Event) => void; handleLogsScroll: (event: Event) => void;
exportLogs: (lines: string[], label: string) => void; exportLogs: (lines: string[], label: string) => void;
@@ -449,6 +449,8 @@ export function renderApp(state: AppViewState) {
}, },
onDraftChange: (next) => (state.chatMessage = next), onDraftChange: (next) => (state.chatMessage = next),
onSend: () => state.handleSendChat(), onSend: () => state.handleSendChat(),
onNewSession: () =>
state.handleSendChat("/new", { restoreDraft: true }),
}) })
: nothing} : nothing}
@@ -517,6 +519,14 @@ export function renderApp(state: AppViewState) {
}) })
: nothing} : nothing}
</main> </main>
<a
class="docs-link"
href="https://docs.clawd.bot"
target="_blank"
rel="noreferrer"
>
Docs
</a>
</div> </div>
`; `;
} }

View File

@@ -1001,10 +1001,20 @@ export class ClawdbotApp extends LitElement {
async loadCron() { async loadCron() {
await Promise.all([loadCronStatus(this), loadCronJobs(this)]); await Promise.all([loadCronStatus(this), loadCronJobs(this)]);
} }
async handleSendChat() { async handleSendChat(
messageOverride?: string,
opts?: { restoreDraft?: boolean },
) {
if (!this.connected) return; if (!this.connected) return;
const previousDraft = this.chatMessage;
if (messageOverride != null) {
this.chatMessage = messageOverride;
}
this.resetToolStream(); this.resetToolStream();
const ok = await sendChat(this); const ok = await sendChat(this);
if (!ok && messageOverride != null) {
this.chatMessage = previousDraft;
}
if (ok) { if (ok) {
this.setLastActiveSessionKey(this.sessionKey); this.setLastActiveSessionKey(this.sessionKey);
} }
@@ -1016,6 +1026,9 @@ export class ClawdbotApp extends LitElement {
this.resetToolStream(); this.resetToolStream();
void loadChatHistory(this); void loadChatHistory(this);
} }
if (ok && messageOverride != null && opts?.restoreDraft && previousDraft.trim()) {
this.chatMessage = previousDraft;
}
this.scheduleChatScroll(); this.scheduleChatScroll();
} }

View File

@@ -27,6 +27,7 @@ export type ChatProps = {
onRefresh: () => void; onRefresh: () => void;
onDraftChange: (next: string) => void; onDraftChange: (next: string) => void;
onSend: () => void; onSend: () => void;
onNewSession: () => void;
}; };
export function renderChat(props: ChatProps) { export function renderChat(props: ChatProps) {
@@ -116,6 +117,13 @@ export function renderChat(props: ChatProps) {
></textarea> ></textarea>
</label> </label>
<div class="row chat-compose__actions"> <div class="row chat-compose__actions">
<button
class="btn"
?disabled=${!props.connected || props.sending}
@click=${props.onNewSession}
>
New session
</button>
<button <button
class="btn primary" class="btn primary"
?disabled=${!props.connected || props.sending} ?disabled=${!props.connected || props.sending}