JSFiddle - React, Tailwind, and code Playground

by Atsushi Nakatsugawa

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<script src="https://fire-dust-acorn.glitch.me/hexabase.js"></script>
<div class="container" style="padding-top: 1em;">
  <div class="row justify-content-md-center">
    <div class="col-10">
      <form>
        <div class="row g-3">
          <div class="col">
            <select id="user" class="form-control">
              <option>Log in as...</option>
              <option value="demo5">Demo 5</option>
              <option value="demo6">Demo 6</option>
            </select>
          </div>
        </div>
        <div class="login">
        
        </div>
        <br />
        <div class="row g-3" style="padding-top: 1em;">
          <div class="col chat">
            
          </div>
        </div>
        <div class="row g-3">
          <div class="col">
            <input type="text" class="form-control" name="comment" aria-describedby="emailHelp" placeholder="チャットメッセージ">
          </div>
          <div class="col">
            <button type="submit" name="Button" id="button" class="btn btn-primary" disabled>メッセージ</button>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>

JavaScript

const { HexabaseClient } = hexabase;
const client = new HexabaseClient();

// 認証用のメールアドレスとパスワード
const logins = {
	demo5: {
  	email: '[email protected]',
		password: 'K4c%j%vzR7sQKS$u&Uo%',
  },
  demo6: {
  	email: '[email protected]',
		password: '5j6Q6RYhm6hnDP&6h*rj8ByLa',
  }
};

// Hexabaseのワークスペース、プロジェクト、ワークスペースのID
const workspaceId = '65b23ad3c1d10befed7a8ad3';
const projectId = '65b315e1af0bb018ee33678a';
const datastoreId = '65d30e653f7e0afce520e6e5';
const itemId = '65d30e6a3f7e0afce520e6fd';

// 複数の処理で使う変数用
const params = {
	item: null, // データストアアイテム
  histories: [], // 既存コメント
};

// DOM
const form = document.querySelector('form');
const comment = document.querySelector('[name="comment"]');
const button = document.querySelector('#button');
const select = document.querySelector('#user');
const login = document.querySelector('.login');

select.onchange = async (e) => {
	// ログインする
	const { email, password } = logins[e.target.value];
  await client.login({email, password});
  // ワークスペース・プロジェクト・データストアの取得
  await client.setWorkspace(workspaceId);
  const project = await client.currentWorkspace.project(projectId);
  const datastore = await project.datastore(datastoreId);
  // チャット対象のデータストアアイテム
  params.item = await datastore.item(itemId);
  // リアルタイム通知の購読を開始
  params.item.subscribe('update', recieveComment);
  // コメントを取得。取得した際には最新が最初にあるので、リバースする
  params.histories = (await params.item.histories()).reverse();
  // チャットを描画
  renderChat();
  // ログイン情報を表示
  login.innerHTML = `Logged in as ${client.currentUser.userName}`;
  // ボタンを押せるようにする
  button.disabled = false;
  // コメントに入力フォーカスを置く
  comment.focus();
};

// コメントが追加された際に呼ばれる処理
const recieveComment = (data) => {
	params.histories.push(data);
	renderChat();
}

// チャットを一覧表示する処理
const renderChat = () => {
  // ログインユーザー情報
	const user = client.currentUser;
  // 履歴を一覧表示
	document.querySelector('.chat').innerHTML = params.histories
  	.slice(-5)
    .map(history => `
  <div class="row" style="padding-top:...