fix(ui): allow Control UI chat without node
This commit is contained in:
@@ -183,16 +183,7 @@ export function renderApp(state: AppViewState) {
|
|||||||
const presenceCount = state.presenceEntries.length;
|
const presenceCount = state.presenceEntries.length;
|
||||||
const sessionsCount = state.sessionsResult?.count ?? null;
|
const sessionsCount = state.sessionsResult?.count ?? null;
|
||||||
const cronNext = state.cronStatus?.nextWakeAtMs ?? null;
|
const cronNext = state.cronStatus?.nextWakeAtMs ?? null;
|
||||||
const hasConnectedMobileNode = state.nodes.some((n) => {
|
const chatDisabledReason = state.connected ? null : "Disconnected from gateway.";
|
||||||
if (!Boolean(n.connected)) return false;
|
|
||||||
const p = typeof n.platform === "string" ? n.platform.trim().toLowerCase() : "";
|
|
||||||
return p.startsWith("ios") || p.startsWith("ipados") || p.startsWith("android");
|
|
||||||
});
|
|
||||||
const chatDisabledReason = !state.connected
|
|
||||||
? "Disconnected from gateway."
|
|
||||||
: hasConnectedMobileNode
|
|
||||||
? null
|
|
||||||
: "No connected iOS/Android node — Web Chat + Talk are disabled.";
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="shell">
|
<div class="shell">
|
||||||
@@ -398,7 +389,7 @@ export function renderApp(state: AppViewState) {
|
|||||||
stream: state.chatStream,
|
stream: state.chatStream,
|
||||||
draft: state.chatMessage,
|
draft: state.chatMessage,
|
||||||
connected: state.connected,
|
connected: state.connected,
|
||||||
canSend: state.connected && hasConnectedMobileNode,
|
canSend: state.connected,
|
||||||
disabledReason: chatDisabledReason,
|
disabledReason: chatDisabledReason,
|
||||||
sessions: state.sessionsResult,
|
sessions: state.sessionsResult,
|
||||||
onRefresh: () => {
|
onRefresh: () => {
|
||||||
|
|||||||
@@ -451,17 +451,6 @@ export class ClawdbotApp extends LitElement {
|
|||||||
this.nodesPollInterval = null;
|
this.nodesPollInterval = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private hasConnectedMobileNode() {
|
|
||||||
return this.nodes.some((n) => {
|
|
||||||
if (!Boolean(n.connected)) return false;
|
|
||||||
const p =
|
|
||||||
typeof n.platform === "string" ? n.platform.trim().toLowerCase() : "";
|
|
||||||
return (
|
|
||||||
p.startsWith("ios") || p.startsWith("ipados") || p.startsWith("android")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
resetToolStream() {
|
resetToolStream() {
|
||||||
this.toolStreamById.clear();
|
this.toolStreamById.clear();
|
||||||
this.toolStreamOrder = [];
|
this.toolStreamOrder = [];
|
||||||
@@ -765,9 +754,8 @@ 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() {
|
||||||
if (!this.connected || !this.hasConnectedMobileNode()) return;
|
if (!this.connected) return;
|
||||||
await sendChat(this);
|
await sendChat(this);
|
||||||
void loadChatHistory(this);
|
void loadChatHistory(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,11 @@ export type ChatProps = {
|
|||||||
|
|
||||||
export function renderChat(props: ChatProps) {
|
export function renderChat(props: ChatProps) {
|
||||||
const canInteract = props.connected;
|
const canInteract = props.connected;
|
||||||
const canCompose = props.canSend && !props.sending;
|
const canCompose = props.connected && !props.sending;
|
||||||
const sessionOptions = resolveSessionOptions(props.sessionKey, props.sessions);
|
const sessionOptions = resolveSessionOptions(props.sessionKey, props.sessions);
|
||||||
const composePlaceholder = (() => {
|
const composePlaceholder = props.connected
|
||||||
if (!props.connected) return "Connect to the gateway to start chatting…";
|
? "Message (⌘↩ to send)"
|
||||||
if (!props.canSend) return "Connect an iOS/Android node to enable Web Chat + Talk…";
|
: "Connect to the gateway to start chatting…";
|
||||||
return "Message (⌘↩ to send)";
|
|
||||||
})();
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<section class="card chat">
|
<section class="card chat">
|
||||||
@@ -90,7 +88,7 @@ export function renderChat(props: ChatProps) {
|
|||||||
<span>Message</span>
|
<span>Message</span>
|
||||||
<textarea
|
<textarea
|
||||||
.value=${props.draft}
|
.value=${props.draft}
|
||||||
?disabled=${!props.canSend}
|
?disabled=${!props.connected}
|
||||||
@keydown=${(e: KeyboardEvent) => {
|
@keydown=${(e: KeyboardEvent) => {
|
||||||
if (e.key !== "Enter") return;
|
if (e.key !== "Enter") return;
|
||||||
if (!e.metaKey && !e.ctrlKey) return;
|
if (!e.metaKey && !e.ctrlKey) return;
|
||||||
@@ -105,7 +103,7 @@ export function renderChat(props: ChatProps) {
|
|||||||
<div class="row chat-compose__actions">
|
<div class="row chat-compose__actions">
|
||||||
<button
|
<button
|
||||||
class="btn primary"
|
class="btn primary"
|
||||||
?disabled=${!props.canSend || props.sending}
|
?disabled=${!props.connected || props.sending}
|
||||||
@click=${props.onSend}
|
@click=${props.onSend}
|
||||||
>
|
>
|
||||||
${props.sending ? "Sending…" : "Send"}
|
${props.sending ? "Sending…" : "Send"}
|
||||||
|
|||||||
Reference in New Issue
Block a user