59 lines
2.3 KiB
Plaintext
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>
|
|
}
|
|
}
|