Slackクライアントにリアルタイムに顔を表示する
エディタの左上にリアルタイムに顔を表示する - hitode909の日記 を見て僕は主にVimを使っているのでさっとエディター上にリアルタイムに顔を出すのは難しそうだな〜と思ったのだけど、Slackクライアントだったらシュッと出せるんではとやってみたら出せた。
Macユーザーの人は以下のコードを /Applications/Slack.app/Contents/Resources/app.asar.unpacked/src/static/ssb-interop.js
に追加してクライアントを再起動すると出せる。多分クライアントをバージョンアップすると消えるので注意。
navigator.mediaDevices.getUserMedia({audio: false, video: true}).then((stream) => { const video = document.createElement('video');video.draggable=true;document.body.appendChild(video);video.src=window.URL.createObjectURL(stream); video.style='position: absolute; right: 32rem; top: 5rem; max-width: 30vmin; max-height: 30vmin; border: 1vmin solid white; z-index:999;'; video.play(); })
ふとSlackを覗いたときに自分が映っててギョッとして目が覚めたので思いがけず便利だった。
参考
ウニバーに行ってきた
何人かの知人が行ってはおかしくなっていたウニバーについに行ってきた。コースは匠。
料理は過度に良く、「ホッ」「んあっ」「ぅうめえ」のようなプリミティブな反応ばかり出がちだった。
さすが専門店だけありウニの存在はユビキタスで、3種食べ比べの他、白エビや大根の煮物、銀鱈やお吸い物の上にもいた。それぞれ立派なものがドカッと。これが "調味料としてのウニ" という界隈か。
また正直なところ、高質なウニをとりあえず添付することで 料理の質B + ウニの質S = 総合評価A
となっている世界観なのではと疑っていたのだけど全然そんなことはなく、乗ったウニはちゃんと料理に必要な1ピースになっていて、不自然なバランスではなかった。そんな猪口才なことを言わずとも、ただただ美味しかった。美味しければいい。
会計はコース(ちなみに写真はコースの料理全てではない)とお酒を2杯で17,000円ほど。たっかいんだけれども、満足できている。 他のコースも気になるのでまた頭のネジが緩んだらお世話になりたい。
Vue.js やってる
来年、まずは Vue.js を利用しているプロジェクトに参加することになりそうなので https://jp.vuejs.org/v2/guide を見て書いてあることを自分なりにまとめなおしたりコード書いたりして勉強していた。
"基本的な使い方" だけ抑えて、後は必要になったとき探せばいいかなと思っている。ひとまず算出プロパティとウォッチャのパートまで。
以下は学習時のまとめです。
Vue インスタンス、オプションオブジェクト
- Vue アプリケーションは Vue() 関数で Vue インスタンスを作成することによって起動する
- Vue() に渡すオブジェクトをオプションオブジェクトと呼ぶ
- オプションオブジェクト内の data オブジェクトのプロパティは Vue インスタンスが作成される際にリアクティブシステムに追加される
- vm.$watch はインスタンスメソッド
- プロパティ、インスタンス、メソッドについては API リファレンスにまとまってる
ライフサイクル
- Vue インスタンスは生成時に一連の初期化を行う
- それらの各初期化段階ごとにユーザーのコードを追加するための関数(ライフサイクルフック)が実行される
- create, mount, update, destroy それぞれの前後にある(beforeCreate, created ...)
- 全てのライフサイクルフックにおける this は Vue インスタンスを指す
- https://jp.vuejs.org/v2/guide/instance.html の最下部にライフサイクルの全体図がある
テンプレート
- テンプレートは内部で VirtualDOM の描画関数にコンパイルされる
- アプリケーションの状態が変わったら最低限の DOM 操作を行う
- テンプレートを使わず render 関数で直接描画することもできる
- データバインディングは Mustache の記法を使うのが基本
- Mustache で展開した場合、データは HTML ではなくプレーンなテキストとして扱われる
- HTML で展開する場合は v-html ディレクティブを使う
- v-html は XSS の温床なのでユーザからのコンテンツに対して使わない
- Mustache は HTML の属性の内部では使えないので、その場合は v-bind ディレクティブを使う
<div v-bind:disabled="divDisabled">DIV</div>
として divDisabled プロパティに値を入れる
- Mustache の内部では js の式を書ける
- 文は書けない(
1 + 2
は OK、let num = 3
は NG)
- 文は書けない(
ディレクティブ
- v- から始まる Vue における特別な属性
- v-for を除くディレクティブは属性値として単一の js 式を期待する
- 属性値が変化すると各ディレクティブは副作用を DOM に適用する
- v-bind:title における title は v-bind ディレクティブの引数
- v-bind と v-on には省略記法がある
v-bind:title
->:title
v-on:click
->@click
算出プロパティ
- オプションオブジェクトに computed プロパティとして指定
- 例えば upperTitle 算出プロパティを定義すると vm.upperTitle の getter として使われる
- 算出プロパティに渡すオブジェクトに set / get プロパティを書くことで setter も書ける
- 同じ関数を methods プロパティで定義したときと computed プロパティで定義したときの差について
- 結果は同じ
- methods では再描画のたびに関数が評価される
- computed では依存関係が更新されたときにだけ再評価され、それ以外はキャッシュされている評価結果を返す
- 以下のようなコードを用意してブラウザのコンソールから vm.title を更新するときの振る舞いを見ると分かりやすい
<!DOCTYPE html> <html> <body> <div id="app"> <h1> {{ title }} </h1> {{ methods_now() }} {{ computed_now }} </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="./index.js"></script> </body> </html>
const vm = new Vue({ el: '#app', data: { title: "Sample Title" }, methods: { methods_now: function () { return Date.now() } }, computed: { computed_now: function () { return Date.now() } } })
- 監視(watched)プロパティもあるけど computed でできないか考えて使う
- watch はデータ変更のたびに重い処理を非同期で行いたいときとかに便利