ある中卒がWeb系エンジニアになるまでと、それからのこと

うつ病で高校を中退したり、たこ焼き屋のオヤジにホームページとたこ焼きを作らされたり、そのホームページが訴えられそうになったり、弁護士を目指したりした後にエンジニアになった人が書くブログ

発言中は口を挟ませないけど、喋り終わったら相手にも喋らせてあげるアプリを作る

2020/07/09の日報

Hanasot開発の日報、第13日目です。
やったことは

  • 発言権を譲渡する機能を作成する

です。
時間は、

  • Hanasot開発 1h58min
  • 日報ブログ 56min

です。
運動は

です。

発言権を譲渡する機能を作成する

はい。今日ちょっとGitLabのエラーが出て、直すのに時間かかったので短めにいきます。ただ基本機能は結構できあがってきたので、UIを整えたら明日か明後日にでもテスト風景の動画を撮影しようかなと思います。

SweetAlert2を導入していい感じに発言権を受け渡しする

まずはUI面で必要なSweetAlert2を導入しました。これ前の案件で使ったんですけど、いいかんじのアラートを出してくれる便利なやつです。

f:id:chusotsuengineer:20200709223111p:plain
これはconfirmです。
f:id:chusotsuengineer:20200709223156p:plain
チェックマークがgifになってて動きます

で、これをnpmでインストールします。
npm install sweetalert2してください。

そしたらimport Swal from 'sweetalert2';で使えるようになります。

で、こんな感じで使います。

f:id:chusotsuengineer:20200709223700p:plain
開始ボタンを押したとき、発言権を持っている人の画面に出す
f:id:chusotsuengineer:20200709223729p:plain
発言権を持っている人が、相手の映像をクリックして発言権を渡そうとした時に出す
f:id:chusotsuengineer:20200709223806p:plain
渡すをクリックしたとき。既にマイクはミュートされています。
f:id:chusotsuengineer:20200709223833p:plain
発言権を受け取った人の画面に出す。

ソースコードはこんな感じです。

<template>
~~~略~~~
    <button v-if="!isStarted" @click="startDialogue">哲学対話を開始する</button>
    <video
      v-for="participant in participants"
      :key="participant"
      :id="participant"
      width="400px"
      autoplay
      playsinline
      @click="transferRight(participant)"></video>
~~~略~~~
</template>
    watch: {
~~~略~~~
     isStarted(newValue) {
        if (!newValue) {
          return;
        }
        if(this.right !== this.peer.id) {
          this.isMuted = true;
          this.isRight = false;
        } else {
          this.isMuted = true;
          Swal.fire(
            'トーキングオブジェクトをお渡しします!',
            '最初の発言者は緊張しますね。\n深呼吸したらマイクをオンにして語ってみましょう。\nHanasotはあなたのありのままの心を映す場所です。',
            'success'
          )
        }
      },
     right(newValue) {
        if (!this.isStarted) {
          return;
        }
        if (newValue !== this.peer.id) {
          this.isMuted = true;
          this.isRight = false;
        } else {
          this.isRight = true;
          Swal.fire(
            'トーキングオブジェクトを受け取りました!',
            'どんなことでも構いません。\nあなたの心のままに語ってみましょう。',
            'success'
          );
        }
      }
    },
    methods: {
      transferRight(participant) {
        if (!this.isRight) {
          return;
        }
        Swal.fire({
          title: 'トーキングオブジェクトを渡しますか?',
          text: "次にトーキングオブジェクトを受け取るまでマイクはミュートされます。",
          icon: 'question',
          showCancelButton: true,
          confirmButtonColor: '#3085d6',
          cancelButtonColor: '#d33',
          confirmButtonText: '渡す',
          cancelButtonText: 'もう少し話す',
        }).then(async result => {
          if (result.value) {
            await firebase.firestore().collection('rooms').doc(this.roomID).update({right: participant});
            Swal.fire(
              'トーキングオブジェクトを渡しました!',
              'みんなの発言を聞くこともまた対話です。\nゆっくりじっくり聞いてみましょう。',
              'success'
            )
          }
        });
      },
~~~略~~~
      async setEventListener(mediaConnection) {
~~~略~~~
        await firebase.firestore().collection('rooms').doc(this.roomID).onSnapshot(snapshot => {
          const room = snapshot.data();
          this.isStarted = room.isStarted;
          this.right = room.right;
        });
      }

動作フローは

  1. 対話開始ボタンが押されて、watchプロパティ内のisStartedメソッドが実行される
  2. 発言権を持っているユーザーが、任意の参加者の映像をクリックすることでtransferRightメソッドが実行される
  3. 発言権の切り替えが行われると、watchプロパティ内のrightが実行される
  4. 切り替え終了

という感じです。

ちなみに発言権のことを哲学対話ではトーキングオブジェクト(以下TO)という物で表します。ぬいぐるみやマイクなど何でもいいのですが、TOを持っている人にのみ発言が許されるというルールです。つまり発言権を可視化したわけですね。

所感

ずっと思っていたのですが、ソースコードの解説だけだと動作イメージがないから進捗が分かりづらいですね(スクショはたまに載せてますが...)。動画が1番わかりやすいですがビデオ通話という性質上、画面録画もしづらいですし...
うーん。とりあえずテストで撮ってみてまた考えます。せっかく記事にするなら読んで楽しいものにしたいので。

Hanasotが段々と完成していく様子を眺められる感じにできたら理想です。