Files
2026-07-12 15:55:18 +05:30

59 lines
2.3 KiB
Plaintext

// Realtime chat. Route: /chat. There is NO client JS file — the page just
// declares `data-room="chat"` and the framework's realtime runtime handles the
// WebSocket, rendering incoming messages into the `<template>`s below and
// sending the form on submit. Server side: app/realtime/chat.ts.
page Chat {
layout = "public"
seo {
title = "Realtime chat"
description = "A broadcast chat room — declared with data-room, zero client JS."
}
style {
.chat-log {
height: 320px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 0.35rem;
font-size: 0.95rem;
}
.chat-row--system { color: var(--wire-color-muted); font-size: 0.85rem; }
.chat-form { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.chat-form .chat-name { max-width: 150px; }
.chat-form .chat-msg { flex: 1 1 12rem; }
[data-room-status].is-connected { background: var(--wire-color-success); color: #05210f; }
[data-room-status].is-disconnected,
[data-room-status].is-error { background: var(--wire-color-danger); color: #fff; }
}
view {
<h1>Realtime chat</h1>
<p>
Open this page in two tabs. The page ships <strong>no client JS</strong> —
it just declares <code>data-room="chat"</code>; the framework connects,
renders messages, and sends the form. Server side is a <code>defineRoom</code>
handler in <code>app/realtime/chat.ts</code>.
</p>
<div data-room="chat">
<div data-component="stack" gap="4">
<span data-room-status data-room-status-class="wire-badge" class="wire-badge wire-badge--default">connecting…</span>
<div data-room-log class="chat-log wire-card"></div>
<template data-room-item="message"><div><strong>%user%</strong>: %text%</div></template>
<template data-room-item="system"><div class="chat-row--system"><em>%text%</em></div></template>
<form data-room-send class="chat-form">
<input name="user" class="wire-input chat-name" placeholder="Your name" autocomplete="off">
<input name="text" class="wire-input chat-msg" placeholder="Type a message…" data-room-reset autocomplete="off">
<button type="submit" class="wire-btn wire-btn--primary">Send</button>
</form>
</div>
</div>
<p><a href="/">← Home</a></p>
}
}