【９日目】チャットアプリの作成 [supabase,localStrageを活用]

今回はsupabaseとlocalStrageを使用してチャットアプリを作成します。

機能としては、ユーザー名を登録しチャットの文を送信するとトーク欄に文が表示される、入力途中のトークはリロードしても入力フォームから消さないようにする、送信すると入力フォームから文字を消すというような機能を搭載させます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="MWrLNBJ" data-user="mizmizsan2" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mizmizsan2/pen/MWrLNBJ">
  chat1</a> by mizmizsan2 (<a href="https://codepen.io/mizmizsan2">@mizmizsan2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

チャット内容や日付、ユーザー名を保存させるためにsupabaseを、入力フォームやユーザーネームを保存するためにlocalStrageを使いました。localStrageでは連想配列を使い、それぞれに入力欄を保存し表示できるようになっています。

保存の仕方は`setInterval("setUser()", 1000);`で1秒経つごとに下のプログラムを呼び出し、それぞれの入力フォームに入っている文字を保存させることができます。
```javascript
function setUser() {
        let chatData = document.getElementById('chatData');
        let name = document.getElementById('userName');

        let chunk = { chatname: name.value, chatdata: chatData.value }
        let chunkData = JSON.stringify(chunk);

        localStorage.setItem('userProf', chunkData);
        console.log(localStorage)
}
```

そしてページをリロードしたときにはその文字たちをlocalStrageから取り出しフォームに保持させるように以下のプログラムを組ませます。
```javascript
        let chatData = document.getElementById('chatData');
        let name = document.getElementById('userName');

        let chunkData = localStorage.getItem('userProf');
        let chunk = JSON.parse(chunkData);

        console.log(chunk);

        chatData.value = chunk.chatdata;
        name.value = chunk.chatname;
```

<br>
functionの前に書かれている「async」やsupabaseのinsertなどの際に書かれている「await」は、簡単に言えばsupabase側とプログラム側の処理の順番を整理するものでお互いの処理を待ちながら並行で処理が行われていきます。


名前を書く欄はmaxlengthを用いて10文字以内に収めるように制限します。
```html
<input type="text" id="userName" value="" placeholder="10字以内" maxlength="10" />
```

<br>
名前の欄に何も書かないままだと少し変なので何も入力されずに文を送信されると名前欄に「名無し」と表示され、トーク内容を空にして送信するとsupabaseには保存されますがcontents欄がEMPTYだと表示をされないようにif文を活用します。

```javascript
if (name.value == null)
            name.value = '名無し';
```
```javascript
if (data[0].contents != "")
            sendChat.innerHTML += `<div>${data[0].user}<br><p class="frame">${data[0].contents}</p><br>${data[0].date}</div><br>`;
```

---
上のプログラムは名前と入力フォームの文字を時間で保存していましたが、名前のほうだけは「入力フォームに文字を入力されたときに保存」というプログラムを組みます。
先ほどまでは連想配列を使用していましたがここから別のものだと考えそれぞれキーを作成させます。(chatData, userName)

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="abEMGeq" data-user="mizmizsan2" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mizmizsan2/pen/abEMGeq">
  chat2</a> by mizmizsan2 (<a href="https://codepen.io/mizmizsan2">@mizmizsan2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`setData`は先ほどと同じ`setInterval`を使って1秒経つごとに実行させるようにさせます。
`setUser`を実行させるためには名前のフォームにonchangeを追加し、カーソルが入力欄から外れたら実行されるようにプログラムしました。
```html
<input type="text" id="userName" value="" placeholder="10字以内" maxlength="10" onchange="setUser()" />
```
```javascript
function setUser() {
        let name = document.getElementById('userName');

        localStorage.setItem('chatname', name.value);
        console.log(localStorage)
    }
```

---
- 画面とストレージ
![chat gamen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584729/7e3e028c-3426-4c82-aa22-6604ac08a51f.png)
![chat strage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584729/10d33094-3024-b663-b187-8547afbd5cd3.png)