細かすぎて伝わらない UI の工夫

Adventarを支える技術 Advent Calendar 2019 の22日目です。

さすがにネタ切れ気味なので、UI 系の細かいネタを投下します。

ユーザーアイコンが404のときにフォールバック

Adventar では Twitter などのソーシャルログインを使っていて、ユーザーのアイコンは各プロバイダから取得できる画像の URL をそのまま使っています。その URL がずっと使えるならいいのですが、ユーザーがプロバイダのほうでアイコンを更新した場合などに古いアイコンの URL がリンク切れになってしまいます。

そうなると、ひどいと以下のようなってしまいます。

f:id:hokaccha:20191219223950p:plain

これはひどい。せめてデフォルトアイコンを設定するようにしたいところです。しかし、アイコンの URL はアクセスしてみないと取得できるのかどうかわかりません。そこで img 要素の onerror イベントをトリガーしてデフォルト画像にフォールバックしています。

<img src={{user.icon}} onerror="this.src = '/default.png'">

実際は Vue.js でやっていてもう少し複雑ですが、こんな感じのイメージです。実際のコードは以下です。

https://github.com/adventar/adventar/blob/c175ac9bd7fd9c12a74bd86202129394ba13e41f/frontend/components/UserIcon.vue

これでさっきの画面は以下のようになります。

f:id:hokaccha:20191219224003p:plain

だいぶマシですね。

部分的にローディング

API の呼び出し待ちなどにローディングを表示するのはユーザーに状況を伝えるのに重要なアクションですが、ローディングを表示するのはできるだけ小さい範囲に留めるようにしています。

例えばトップ検索画面のカレンダー一覧ですが、カレンダーの一覧取得には API の結果を待たないといけないので、返ってくるまでしばらくラグが発生します。そのとき全画面ローディングにしてもいいのですが、以下のように、必要な部分だけをローディングにすることで、可能な限りユーザーに速く画面を見せます。

f:id:hokaccha:20191219224035p:plain:w300

また、8日目の記事に書いたのですが、最初のログイン処理にやや時間がかかってしまうため、その間ローディングを出したいのですが、これもログイン情報が必要なところは多くないので、必要なところだけローディングにして体験を損ねないようにしています。

f:id:hokaccha:20191205123054p:plain:w300

これでだいぶ初期表示が速くなり、体験がよくなります。

吹き出しの位置のこだわり

これは本当に細かいのですが、カレンダーで登録情報を編集するポップアップがあるのですが、この吹き出しの位置に微妙なこだわりがあって、端の登録を押したとき、スマホなどの画面幅が狭い場合は以下のようになります。

f:id:hokaccha:20191219224120g:plain

可能な限り選択した吹き出しに近い位置に出して、吹き出しの三角は選択したセルを指します。

また、PC などの画面幅が広いデバイスで見た場合は左右に余白ができるので、端のセルでも中央にポップアップを表示したいところです。

f:id:hokaccha:20191219224138g:plain

書いてみると当たり前の動きな動きすぎてなんでこれを紹介しているのか自分でもよくわからなくなってきましたが、この動作をあらゆる画面幅で動作するように実装するのが思いの他大変だったので紹介したくなっただけです。

実装を見返してみると色々ハードコーディングしてあったりして泥臭くてだいぶひどい感じですが、がんばった後が見られますね...。

https://github.com/adventar/adventar/blob/c175ac9bd7fd9c12a74bd86202129394ba13e41f/frontend/components/CalendarTable.vue#L188-L212

まとめ

今日はネタ切れ気味で細かい UI の話を書きました。本当に細かすぎてすいません。明日は Adventar をオープンソースで公開した話を書こうと思います。