ショートカットキーが身につくアプリ「Shortype」のプロトタイプをリリースしました
- はじめに
- Shortype のプロトタイプ
- 解決したいことは「ショートカットキーが身につかない」問題
- 実装に関する簡単な説明
- 特に苦労した実装は「押されたキーの判別」
- プロトタイプでリリースした理由
- これまでやってきたこと
- 解決したいことは解決できた?
- これからやること
- 最後に
はじめに
はじめまして、えにしテックの AudioStakes(佐藤大介)と申します。
現在フィヨルドブートキャンプに参加しており、その課題としてタイトルのとおりのアプリ Shortype を自作しています。
普段の作業でついマウスに手を伸ばしがちなので、「キーボードから手を離さず作業できるようになりたい」というモチベーションから Shortype を作ろうと考えました。
この記事では、はじめに Shortype のプロトタイプを紹介し、その後に「技術的な詳細」「これまでやってきたこと」「これからやること」を説明します。
2022/04/01追記: プロトタイプに磨きをかけた version 1.0.0 のリリース記事を公開しました。
Shortype のプロトタイプ
macOS の Google Chrome のショートカットキーを練習できます。
操作はショートカットキーを入力するだけです。
※ 右下の黒いオーバーレイに実際にタイプしたキーが表示されています(keycastr を使用)。
※ 現在開発中のため、アプリの内容は今後変更されます。
動作環境
- ブラウザ: Google Chrome もしくは Microsoft Edge
- 主な理由は、アプリで使用している Keyboard API への対応が必要なため
- OS: macOS
解決したいことは「ショートカットキーが身につかない」問題
これまで、自分が使うツールのショートカットキーを調べて「これは便利なショートカットキー!」と思うことは多々あったものの、それらを身につける前に忘れてしまい、結局マウスで操作するということを繰り返してきました。
このようなことを課題に感じており、ショートカットキーが身につくまで練習できるアプリがあれば解決できるのでは?と考え、Shortype を作り始めました。
実際に試してみて、Chrome のショートカットキーに関しては8割ほど覚えることができたので、プロトタイプとしては期待どおりの成果が得られていると思います。
実装に関する簡単な説明
使っている技術
- Vite v2.8.6
- Vue v3.2.31
- TypeScript v4.6.2
- Tailwind CSS v3.0.23
- Vercel (デプロイ先)
どれも今回初めて使っています。Vue 2 を使って「メモを CRUD できるアプリ」を作成したことがあるので、その経験を基にわからないことは調べながら実装を進めています。
感想としては、開発体験がとても良く、チャレンジしてみて良かったと思っています。
実装した処理の流れ
- ショートカットキーを出題
- 押されたキーを判別し、画面に表示 & 正解かどうか判定
- 正解判定の結果を表示
- 正解のときは ✅ を表示
- 不正解のときは正解を表示
- 正解のキーが押されたら、次のショートカットキーを出題
特に苦労した実装は「押されたキーの判別」
概要
押されたキーの判別は「キーを画面に表示するため」と「正解かどうか判定するため」に必要です。
キーの判別を JavaScript で行うためには KeyboardEvent (キーボードによるユーザーの操作を示すイベント)を使うとよさそう、と考えていました。
しかし、KeyboardEvent
のプロパティの値は「押されている修飾キー(command, shift など)の状態」や「クライアントのキーボードレイアウト」によって異なり、うまく判別できないことがあります。
試行錯誤した結果、KeyboardEvent
に Keyboard API を組み合わせることにしました。現在は期待どおりにキーを判別できるようになっていると思います。
KeyboardEvent のみでは判別できないことがある
はじめは前述のとおり、押されたキーの判別に KeyboardEvent
のプロパティの値のみを使おうと考えました。
検討したプロパティは、key
, code
, keyCode
, which
の4つです。
それぞれ次の理由により、使用に適していないと判断しました。
修飾キーの状態によって、返り値が次のように変化する。
- (修飾なし) a →
a
- shift + a →
A
- option + a →
å
- shift + option + a →
Å
クライアントのキーボードレイアウトによって、返り値が異なる。
たとえば code
の返り値がKeyQ
のとき、次のようになる。
KeyboardEvent.keyCode, KeyboardEvent.which
修飾キーの状態やキーボードのレイアウトの影響を受けないように見えるものの、現在は Deprecated (非推奨)とされている。
※ なお、JavaScript で実装された「ショートカットキーを追加できるライブラリ Mousetrap」では、keyCode
とwhich
を使って押されたキーを判別しているようでした。
Keyboard API を組み合わせると期待どおり判別できた
他の方法を調べているうちに Keyboard API にたどり着き、説明を読んでいると使えそうな気がしてきました。
以下は、MDN の Keyboard API のページで紹介されているサンプルコードです。
if (navigator.keyboard) { var keyboard = navigator.keyboard; keyboard.getLayoutMap() .then(keyboardLayoutMap => { var upKey = keyboardLayoutMap.get('KeyW'); window.alert('Press ' + upKey + ' to move up.'); }); } else { // Do something else. }
このコードでは、クライアントのキーボードレイアウトに対応する KeyboardLayoutMap
を取得し、その get
メソッドに KeyW
(すなわち KeyboardEvent.code
の値)を渡すことで、 KeyW
に対応する KeyboardEvent.key
の値を取得しています。
これを利用し、次のようなコードを実行すると「修飾キーの状態」や「キーボードレイアウト」の影響を受けずに押されたキーの値を取得できるようになります。
document.addEventListener('keydown', (keyboardEvent) => { navigator.keyboard.getLayoutMap() .then(keyboardLayoutMap => { const pressedKey = keyboardLayoutMap.get(keyboardEvent.code) console.log(pressedKey) }) })
この方法を試してみた結果、押されているキーを期待どおりに判別できるようになりました。
Keyboard API は2022/03/07現在 Experimental (実験的)という定義の、比較的新しい技術のようです。サポートしているブラウザは少ないものの、使い心地はとても良いです。
※ 上記のコードを試す際は、Keyboard API をサポートしているブラウザ Google Chrome, Microsoft Edge, Opera のいずれかをご使用ください。
※ KeyboardLayoutMap.get()
がundefined
を返す場合もあります。その対応方法は割愛します。
プロトタイプでリリースした理由
フィヨルドブートキャンプでは、自作サービスの課題として「どんなサービスを作るかを考える」ところから「Web サービスをリリースする」ところまで取り組みます。
その作業期間は決められていないものの、諸々の都合により約8週間と決めて取り組むことにしました。しかし、リリースまでの作業には未経験のものも多く、作業全体の見通しを立てることができていませんでした。
そのため、先にリリースまで行って提出可能な状態を作り、期限の心配から解放された状態でプロダクトを磨いていこうと考えました。
※ この考え方は、WEB+DB PRESS Vol.73 の特集「たのしい開発実況中継~追体験して見つける日々の開発へのヒント~」から得た受け売りです。
もし順番どおりに作業を進めていたら、リリース関連作業でトラブルが生じ、提出に間に合わなくなっていたかもしれません。
たとえば、自作サービスの提出要件に「リリースブログの記事の作成」が含まれているものの、ブログ記事を書いて公開した経験はありませんでした。そのため、その素振りとしてこの記事を書いて公開することに決めました。
実際やってみて、この記事の作成に3日間以上かかっており(プロトタイプの機能の実装期間が6日間だったことを踏まえると、かなり時間がかかっています)、文章を見直す際も数日経ってから見直した方が修正箇所に気づきやすいということがわかったので、最後にリリース記事を書くときは余裕を持って作成し始めようと思いました。
これまでやってきたこと
全体の作業期間8週間のうち、この記事の公開までの約5週間で次のようなものを作成してきました。
インセプションデッキ
インセプションデッキとは、「どのようなプロダクトを、なぜ、どのように作ろうとしているのか」を手軽に伝えられるようにするためのツールです。詳しくは、アジャイルサムライの第II部「アジャイルな方向づけ」をご確認ください。
今回は、次のようなものを作成していきました。
- エレベーターピッチ
- パッケージデザイン
- やらないことリスト
- 夜も眠れない問題
- 期間を見極める
- 何を諦めるのか
これらの作成を経て、自作するプロダクトの解像度を高めることができました。
ペーパープロトタイプ
ペーパープロトタイプは、プロダクトに必要なページを紙に書き出したものです。 Figma を使って作成しました。
最初のペーパープロトタイプは、インセプションデッキのうち「エレベーターピッチ」のみを作った状態で、次のようなものを作成しました。
他の方からのフィードバックや、インセプションデッキを作り進めていく中で、このペーパープロトタイプには余計な画面や機能が多いことに気づきました。
そのため余計なものを取り除き、次のように作り直しました。
プロダクトの価値をユーザーへ届けやすくなったように思います。
作業計画
「プロトタイプでリリースした理由」の項目で紹介しました「WEB+DB PRESS Vol.73 の特集『たのしい開発実況中継~追体験して見つける日々の開発へのヒント~』」を参考にして計画を立てました。
早い段階から提出可能な状態を作ることを念頭に置いた計画にしています。
もし上記の記事を読んでいなかったら、3月末は泣く泣く機能を削りながら提出に間に合わせていたと思います。
「期限のある方」や「期限はないけれど短期間で満足できるものを作りたい方」には一読をオススメします。
カンバン
GitHub のプロジェクトボードを作成し、タスクを Issue として追加しました。
Issue はアジャイルサムライのユーザストーリーを参考に「<達成したいゴール>をしたい。なぜなら<理由>だからだ。」という形式で作成しました。
プロトタイプ
前述のとおりです。
リリースするために必要な未経験の作業
リリースに必要な作業にはロゴの作成や OGP の設定など、未経験な作業が多く含まれていました。それらの作業にどれくらい時間がかかるか予想もつかなかったため、2日間というタイムボックスを切って取り組みました。
プロトタイプのデザインの改善
「未経験の作業」と同様、作業時間の予想がつかなかったため、1日というタイムボックスを切ってできる範囲で改善してみました。
デプロイ
社内で相談してみた結果、Vercel が手軽ということがわかったため Vercel を使ってデプロイしました。実際やってみるとアカウント登録とリポジトリの設定のみでデプロイされ、本当に手軽でした。
プロトタイプのリリースブログの作成
この記事を作成しました。
解決したいことは解決できた?
Shortype で解決したいことは「ショートカットキーが身につかない」という問題でした。
僕自身が(動作確認としてですが)試してみた結果、今では8割ほど正解できるようになりました。
少なくとも Chrome に関しては目論見どおりの成果が得られ、解決できそうです。
ただ、現在の Shortype には課題がまだあるように思います。たとえば次のような課題です。今後これらに取り組んでいきたいと思います。
Google Chrome のショートカットキーしか練習できない
Google Chrome を選んだ理由は、課題となる(出題には工夫が必要となる)ショートカットキーを見つけやすいと考えたためです。
個人的には VSCode や macOS の Terminal など、普段の開発で扱うツールのショートカットキーを練習したいものの、プロトタイプでは練習できません。
出題できないショートカットキーがある
プロトタイプでは 次に該当するショートカットキーは出題できていません。
- 入力するとショートカットキー本来の機能が実行されてしまう(JavaScript で無効化できなかった一部のショートカットキー)
- 操作に対応するショートカットキーが複数ある(すなわち回答が複数ある)
- キー入力以外にも、画面のクリック等の追加操作を必要とする
少なくともショートカットキーを確認できるように、たとえば「回答不要」として出題するなどして、身につけられるようにしたいです。
「すでに身についた」もしくは「興味のない」ショートカットキーが繰り返し出題される
初見のときは「これ知ってる!」や「これ知らなかった〜」と興味をもてるものの、見慣れてくると「すでに身についた」もしくは「興味のない」ショートカットキーへの回答が段々と手間に感じてきます。
できるだけ「身につけたい」かつ「身についてない」ショートカットキーが出題されてほしいです。
これからやること
予定していた作業期間の約8週間のうち、すでに5週間以上が過ぎました。そのためすぐにでも開発を進めて前述の課題を解決していきたいものの、プロトタイプでは品質を気にしていなかったためテストもなく、新機能を追加しにくいコードになっています。
そのため、まず先にテストを追加し、リファクタリングして品質を改善していく予定です。またその際、プロトタイプを触りながら、追加したい機能やその優先順位を考えていきます。
その後に、前述の課題や新たに気づいた課題を解決できるように、開発を進めていく予定です。
最後に
以上、Shortype のプロトタイプ・やってきたこと・これからやることを紹介しました。
プロトタイプの作成過程でご意見をくださった、えにしテック及びフィヨルドブートキャンプのみなさま、本当にありがとうございます。
残り3週間弱、できることは限られていますので、大事と思える課題から順に解決していき、自分なりに納得するものを改めてリリースしたいと思います。