前回、アプリの概要を説明しましたので、実際にUIを作っていきます。今回はMonaca × Onsen UIを使っています。Onsen UIはMonacaを提供しているアシアル社の開発するモバイルアプリ向けのUIフレームワークです。
必要なもの
予め下記を行っておいてください。
- ニフクラ mobile backendの登録
- Pusherの登録
画面は二つ
今回は画面を二つ作ります。
- チャットID/ユーザ名を決める画面
- チャット画面
ユーザ名を決める画面は認証画面にすることもできますが、今回は手順を簡略化するために自分で好きに決められるようにしています。
チャットIDとユーザ名を決める画面を作る
まずアプリを立ち上げた時に表示される画面を作ります。これは index.html の bodyタグの中に作ります。ボタンを押した際に join という関数を実行します(関数は後述)。 ons-page はOn sen UIで管理されるページになります。ons-inputやons-buttonはそれぞれOnsen UIのテキストフィールド、ボタンになります。
<ons-page id="login"> <div class="join-area" style="text-align: center; margin-top: 30px;"> <h4>チャットルームにログインしてください</h4> <p> <ons-input id="userName" modifier="underbar" placeholder="ユーザ名" float></ons-input><br /> <ons-input id="chatId" modifier="underbar" placeholder="chatId" float></ons-input> </p> <p style="margin-top: 30px;"> <ons-button onclick="join()">Join</ons-button> </p> </div> </ons-page>
joinを実行した際にチャット画面に遷移しますので、HTMLをtemplateタグで囲んでおきます。
<template id="login.html"> <ons-page id="login"> <div class="join-area" style="text-align: center; margin-top: 30px;"> <h4>チャットルームにログインしてください</h4> <p> <ons-input id="userName" modifier="underbar" placeholder="ユーザ名" float></ons-input><br /> <ons-input id="chatId" modifier="underbar" placeholder="chatId" float></ons-input> </p> <p style="margin-top: 30px;"> <ons-button onclick="join()">Join</ons-button> </p> </div> </ons-page> </template>
このままでは何も表示されませんので、ons-navigatorを使って表示します。ons-navigatorは画面遷移をコントロールします。page要素でテンプレート名(login.html)を指定することで、最初にtemplate#login.htmlを表示します。別途login.htmlというファイルを作っておいても同じように扱われます。
<ons-navigator swipeable id="nav" page="login.html"></ons-navigator>
joinメソッドの実装
ではボタンを押した際のjoinメソッドを作ります。ここではユーザ名の入力確認と、チャット画面の遷移を担当します。画面遷移はons-navigatorに対してpushPageメソッドを実行して行います。chat.htmlへ移動しながら、パラメータとしてユーザ名とチャットIDを送ります。
// チャットルームにログインする処理 const join = () => { const userName = $('#userName').val(); if (userName === '') { ons.notification .alert('ユーザ名を決めてください'); return; } localStorage.setItem('userName', userName); const chatId = $('#chatId').val(); $('#nav')[0].pushPage('chat.html', { data: { userName, chatId } }) }
ここでユーザ名を localStorageに保存しています。これで再度アプリを表示した際にユーザ名が自動入力されているようにします。それはアプリを立ち上げて画面を初期化する際に呼ばれるinitイベントに実装します。チャットIDはデフォルトで channel と入力されるようにしています。
// 初期表示処理 $(document).on('init', (event) => { if (event.target.id === 'login') { $('#chatId').val('channel'); const userName = localStorage.getItem('userName'); if (userName) $('#userName').val(userName); } });
チャット画面の作成
では次にチャット画面を作成しますが、これは別ファイルで作成しましょう。 www 以下に chat.html を作ります。このページはテンプレートなのでheaderやbodyタグは不要です。 ons-back-button は前の画面に戻るボタンで、Onsen UIの機能によって簡単にページ遷移が管理できるようになります。
<ons-page id="chat"> <ons-toolbar> <div class="left"><ons-back-button>Back</ons-back-button></div> <div class="center"></div> </ons-toolbar> <input type="hidden" id="channelId" /> <div class="chat-area"> <ons-list id="chats"></ons-list> </div> <div class="send-area"> <ons-input id="message" placeholder="メッセージ"></ons-input> <ons-button onclick="send()" modifier="quiet">送信</ons-button> </div> </ons-page>
この画面では多少CSSを変更していますので css/style.css (最初は空です)に次のように書き込みます。
.send-area { padding: 0 5px; box-sizing: border-box; line-height: 49px; position: fixed; bottom: 0px; width: 100%; border-top: solid 1px #ccc; } .send-area ons-input { display: inline-block; position: relative; width: calc(100% - 60px); } .send-area input { vertical-align: middle; position: relative; width: 98%; }
これでチャット画面が完成です。
チャット画面が表示された際の処理
チャット画面が表示された際には以下の処理を行います。
- Pusherへの接続
- 既存のチャットデータの読み込み(ニフクラ mobile backendから)
そこで、まずはPusherとニフクラ mobile backendを初期化します。これはOnsen UIが使えるようになったタイミング、ons.readyで行うのが良いでしょう。 YOUR_PUSHER_ID はPusherから、YOUR_APPLICATION_KEYとYOUR_CLIENT_KEYはニフクラ mobile backendから取得して書き換えてください。Pusherとニフクラ mobile backend、どちらも他の処理でも使うのでファイル全体のスコープで変数を定義しておきます。
let pusher; let ncmb; const pusherId = 'YOUR_PUSHER_ID'; const applicationKey = 'YOUR_APPLICATION_KEY'; const clientKey = 'YOUR_CLIENT_KEY'; // グローバル変数の処理 ons.ready(function() { pusher = new Pusher(pusherId, { encrypted: true }); ncmb = new NCMB(applicationKey, clientKey); });
ではチャット画面を表示した際の処理を作ります。これはdocumentのshowイベントを使います。チャットIDはhiddenタグの中に隠しておきます(他でも使うので)。
// チャット画面を表示したときの処理 $(document).on('show', (event) => { if (event.target.id === 'chat') { const data = event.target.data; $('#channelId').val(data.chatId); connectPusher(data.userName, data.chatId); loadChat(data.userName, data.chatId); } });
connectPusherはPusherへの接続を行う関数です。接続して、メッセージが来た際には showChat を呼び出します(showChatは後述)。
// Pusherに接続する処理 const connectPusher = (userName, chatId) => { const channel = pusher.subscribe(chatId); channel.bind('message', function(data) { showChat(userName, data); }); };
同様に既存のチャットデータを読み込むのは loadChat になります。こちらはChatクラスのデータを検索し、返ってきたデータをshowChatに送ります。
// 既存のチャットメッセージを読み込む処理 const loadChat = (userName, channel) => { const Chat = ncmb.DataStore('Chat'); Chat .equalTo('channel', channel) .fetchAll() .then(chats => { for (let chat of chats) { showChat(userName, chat); } }); }
showChatはチャットデータをリストに追加する関数です。メッセージを送信したのが自分かどうか(ユーザ名で判断)で多少表示が違います。
// メッセージを一つ表示する処理 const showChat = (userName, data) => { if (data.userName == userName) { $('#chats').append(` <ons-list-item modifier="nodivider"> <div class="right"> <ons-button style="background-color: green">${data.message}</ons-button> </div> </ons-list-item>`); }else{ $('#chats').append(` <ons-list-item modifier="nodivider"> <ons-button>${data.message}</ons-button> <span class="list-item__subtitle">${data.userName}</span> </ons-list-item>`); } }
まだデータはないので何も表示できませんが、ここまででPusherとニフクラ mobile backendの設定が完了し、メッセージが来れば表示できる段階になりました。
次の処理
次はメッセージをニフクラ mobile backendのスクリプトに対して送信する処理を作ります。