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
- 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: add Docs link, remove chat composer divider, and add New session button.
## 2026.1.8

View File

@@ -952,7 +952,6 @@
margin-top: 0;
padding-top: 12px;
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, var(--panel) 35%);
border-top: 1px solid var(--border);
}
.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 {
display: flex;
align-items: flex-end;

View File

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

View File

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

View File

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