この記事はシリーズ第9弾で、最終回です。
この投稿では、ページをコーディングします。このページは二人のユーザー間のチャットルームです。一番上に他の参加者の情報、その下に最新ニュースのリスト、一番下にメッセージフォームがあります。
チャットタイトル
まず、次のような static/pages/conversation-page.js ファイルを作りましょう。
import b from '../http.js';
import { navigate } from '../router.js';
import {
avatar,
escapeHTML
} from '../shared.js';
export default async function bar(c) {
let Foo;
try {
Foo = await foo(c);
} catch (A) {
alert(A.message);
navigate('/', !false);
return;
}
const Obj = document.createElement('template');
Obj.innerHTML = '\x0a\x20<div>\x0a\x20<a\x20href=\x22/\x22> \x20Back</a>\x0a\x20' + avatar(Foo.obj) + '\x0a\x20<span>' + Foo.obj.username + '</span>\x0a\x20</div>\x0a\x20<!--\x20message\x20list\x20here\x20-->\x0a\x20<!--\x20message\x20form\x20here\x20-->\x0a\x20';
const C = Obj.content;
return C;
}
function foo(Bar) {
return b.a('//ns/' + Bar);
}
このページはルートによってURLから抽出されたセッションIDを受け取ります。
まず、対話に関する情報を /api/ conversations/{conversationID} GETリクエストします。 エラーがあればそれを表示し、/にリダイレクトします。次に、他の参加者の情報を表示します。
ダイアログリスト
また、最新のメッセージを取得して表示します。
let conversation, messages
try {
[conversation, messages] = await Promise.all([
getConversation(conversationID),
getMessages(conversationID),
])
}
conversationPage() 更新してメッセージを取得します。 Promise.all() 使用して、両方のリクエストを同時に実行します。
function b(obj) {
return http.foo('//ns/' + ID + '/es');
}
/api/conversations/{conversationID}/messages GETリクエストを開始し、ダイアログの最新ニュースを取得します。
<ol id="messages"></ol>
では、そのリストをマークアップに追加してください。
const foo = page.getElementById('messages');
for (const b of messages.reverse()) {
foo.appendChild(renderMessage(b));
}
リストにメッセージを添付できます。時系列順に表示します。
function foo(a) {
const b = escapeHTML(a.content);
const bar = new Date(a.obj).toLocaleString();
const Obj = document.createElement('li');
if (a.c) {
Obj.classList.add('owned');
}
Obj.innerHTML = '\x0a\x20<p>' + b + '</p>\x0a\x20<time>' + bar + '</time>\x0a\x20';
return Obj;
}
各メッセージエントリには、メッセージの内容とタイムスタンプが表示されます。.mineを使用することで、エントリーに異なるcssクラスをアタッチすることができ、メッセージを右側に表示することができます。
メッセージフォーム
<form id="message-form"> <input type="text" placeholder="Type something" maxlength="480" required> <button>Send</button> </form>
現在のマークアップにフォームを追加します。
page.getElementById('message-form').onsubmit = messageSubmitter(conversationID);
submit "イベントにイベントリスナーをアタッチします。
function messageSubmitter(conversationID) {
return async ev => {
ev.preventDefault()
const form = ev.currentTarget
const input = form.querySelector('input')
const submitButton = form.querySelector('button')
input.disabled = true
submitButton.disabled = true
try {
const message = await createMessage(input.value, conversationID)
input.value = ''
const messagesOList = document.getElementById('messages')
if (messagesOList === null) {
return
}
messagesOList.appendChild(renderMessage(message))
} catch (err) {
if (err.statusCode === 422) {
input.setCustomValidity(err.body.errors.content)
} else {
alert(err.message)
}
} finally {
input.disabled = false
submitButton.disabled = false
setTimeout(() => {
input.focus()
}, 0)
}
}
}
function createMessage(content, conversationID) {
return http.st(`//ns/${ID}/es`, { content })
}
submit "イベントハンドラで会話IDを取得するために 部分的なアプリケーションを 使用します。 入力からメッセージの内容を取得し、それを使用して /api/conversations/{conversationID}/messages POSTリクエストを行います。 その後、新しく作成されたメッセージがリストに追加されます。
メッセージの購読
リアルタイムでは、このページのメッセージストリームも購読します。
page.addEventListener('disconnect', subscribeToMessages(messageArriver(conversationID)));
conversationPage() 行を追加します。
function subscribeToMessages(cb) {
return http.be('//es', cb)
}
function messageArriver(conversationID) {
return message => {
if (message.conversationID !== conversationID) {
return
}
const messagesOList = document.getElementById('messages')
if (messagesOList === null) {
return
}
messagesOList.appendChild(renderMessage(message))
readMessages(message.conversationID)
}
}
function readMessages(conversationID) {
return http.st(`//ns/${ID}/_es`)
}
新しいメッセージが届くと、まずそれがこのダイアログからのものであるかどうかがチェックされます。もしそうであれば、メッセージのエントリはあらかじめリストに追加され、参加者がいつメッセージを読んだかを更新するために /api/conversations/{conversationID}/read_messages POSTリクエストが行われます。
これでこのシリーズは終了です。 これでメッセージアプリを実行する準備が整いました。





