recorder-prototype
実装したもの
テーブル表示
カレンダー表示
demo
なぜかVercelへのdeployに失敗する
足りないもの
/icons/done.icon計測中の記録を全てのdeviceで同期させる
現状だとページを変えただけで記録データが消えるのでとても不便
同期する情報
開始時刻
仮の記録名
/users/{userId}の直下に格納すると良さそう
/icons/done.icon入力して少し時間が経ったらdatabaseに反映するようにしたい
現状、focusが外れると更新するようになっている
これを自動的に更新するようにしたい
方法
現在記録中の記録名に関しては、入力後1秒後に自動更新するようにした
やった
/icons/done.icon入力欄が下の方にあって押しづらいのを直す
候補
上に置く
/icons/done.icon10:44:36 下に置いて常に固定する
記録を追加するたびにscrollする
とにかく、最新の記録と入力欄がすぐ見える場所にあってほしい
カレンダーから予定を動かせるようにしたい
今回もめんどくさそうなのでパス
カレンダーを見やすくする
event blockに時刻を表示しない
やり方がわからん
/icons/done.icon時間間隔を長めにする
timeslotsとstepをいじると似たようなことができる
/icons/done.iconnav barを固定した
useEffect()を使ってあとからhas-navbar-fixed-topを<body>に追加しないとページ上部が隠れてしまう おそらくrenderとCSS読み込みの順番が関係しているのだと思う
JSXでis-activeを操作するようにした
選択操作が正常に動いていない
useEffectの依存からはずした影響
13:02:38 コードを戻してみた
何らかのeventをきっかけに値を親componentに通知することはできる
JSONにobjectを変換してから同じかどうか比較して、同じであった場合にsetStateの呼び出しをskipしてみたがだめだった
なぜか5回位呼び出されてしまう
13:51:53 これ無理だな
eventを経由して呼び出す以外に方法がない
さらにevent経由で呼び出したとして、何故か正しく反映されない
あとuseTableの返り値をuseTableの引数で使わなければならなかったりしてややこしい
component設計をやり直そう
現状
RecordListにtableのhooksとcomponentを入れている
削除ボタンと削除機能はDashboardページに入れた
変更後
RecordListはcomponentのみ入れる
削除機能などを一つにしたcustom hookを作る
自動更新機能も一緒にする?
一緒にしたほうがいいだろう
DashBoardページからcustom hookを呼び出し、返り値をRecordListに渡す
理想
code:tsx
export const Dashboard = (...) => {
// hooks
const {...} = useRecordList(...);
// components
return <>
<RecordList {...} />
<Delete {...} />
<Copy {...} />
</>
}
15:42:01 設計を一旦断念
時間がない
苦肉の策として、delete buttonをtableの中に入れた
もしかしたら、Buttonなどの操作部品も含めて全て同一のComponentに閉じ込めたほうが良いのかもしれない
実際、React Tableのkitchen sink exampleはbutton含めて全てTableに閉じ込められていた 一旦記録用tableを整理するか
編集用cellを一つに統一する
headerとも一つにまとめたいな
同じ処理を同じところに書きたい
列headerごとにobjectを作るのもありか?
code:ts
{
Header: 'time',
id: 'start-time',
accessor: row => lightFormat(row.start,'HH:mm:ss'),
Cell: ({row})=> {
const {value, onBlur, onChange} = useEditableCell({...});
return <FlexTextArea ... />;
},
}
このデータだけで、その列の表示及び操作方法が決定される
最初からheaderに入れ込んでおけばいい
22:24:12 とりあえずRecordList.tsxを分割した
recordList/header.tsx
列のheaderの表示方法を定義
recordList/Table.tsx
tableのhtml構造
recordList/RecordList.tsx
本体
だいぶ見やすくなった
22:41:12 てかこのtable genericにできるな
ScheduleListにも使い回せる
いやTableは使い回せない
中で使っているUrlEditorががっつりRecordListに依存している
ColumnMenuだけばらそう
列の表示非表示を切り替えるやつ
22:57:32 できた。少しだけスッキリした
/icons/done.icon選択欄をcheck boxに直す
代わりに使っている<div>のCSSがURLの入力欄のデザインと衝突してしまうので、check boxに戻すことにした
直した
/icons/done.icon記録中のタイトルを変更した直後に完了ボタンを押すと、タイトルが消えてしまう現象を直した
firestoreへのデータ登録を非同期に行っていたのが原因だった
awaitを使って待つようにした
/icons/done.icon入力値をreal timeに反映する部分をhookに分離する
仕様
入力後一定時間経過すると登録された関数に入力値を送信する
setTimeoutを使う
外部からの入力値変更は、focusがあたっていないときのみ行う
useEffectを使う
外部の入力値の検証もやるか?
だが最初から不正な値を渡されると、正常な値として使えるものがなくなる
focusが外れたら直ちに入力値を送信する
検証機能付き
入力値が不正の場合は送信しない
入力値が不正な状態でfocusを外すと、初期値に戻す
18:27:53 Bulmaの.is-dangerが動くように、.textareaを入れた
min-heightに値が入って変なことになってしまうので、inline要素で無効に設定した
いろんなpropertyを無効にしなければ動きそうにないので止めた
代わりに.has-text-dangerで赤文字にするようにした
常にstart<endとなるよう入力値を検証する
endの代わりにdurationをdatabaseに格納しようかとも思ったが、data型の表現が面倒だな。やめよう。
現在時刻を入力するショートカットがほしい
PCなら、keyboard shortcutを導入すれば良さそう
全deviceを視野に入れるなら、<input type='time'>とかを使ったほうが良いかも
/icons/doing.iconinputの代わりにdivを使う
11:45:50 断念。何故か固まってしまう
inputではなくtextareaを使うと良さそう
19:16:04 できた
改善案
<textarea>の外枠をなくす
clickしたときのみ<textarea>を表示するようにする
/icons/doing.icon年月日の表示非表示を切り替えたい
headerに切り替えボタンをつけるか
2020-12-04 14:07:43 入れた
drop down menuの中にcheckboxを入れた
切り替えの状態は保存していない
これもdatabaseから読み込めるようにしておくといいかも
キーボードショートカット
曖昧検索欄
入力すると記録名を曖昧検索して一覧表示する
実装
titleだけ取得して絞り込み検索を行うhookを作る
候補はどうやって表示すればいいかな?
これほしいな
井戸端編集で絞り込んで、どれだけ時間を費やしているのかとか知りたい
記録名置換
同じ名前の記録を一斉に別の名前へ変換する
実装
同じtitleの記録を全て検索して、一括置換する
置換する前に、置換するかどうかuserに聞く
簡易実行ボタン
各記録にボタンをつける
押すとその記録名で新たに記録を開始する
/icons/doing.iconofflineで実行できるようにする
2020-12-03 09:09:31 おかしい。multi-tabでも使えるoptionを有効にしたのにerrorがでる
FirebaseError
Failed to obtain exclusive access to the persistence layer. To allow shared access, multi-tab synchronization has to be enabled in all tabs. If you are using experimentalForceOwningTab:true, make sure that only one tab has persistence enabled at any given time.
09:13:55 option名が変わっていた。
変更後のoption名にしたら直った
きちんと動作している
networkを切断してもdataの読み書きができる
networkに復帰すると、dataが同期される
表示数を制限する
直近の20件のみ表示するようにしてみる
/icons/done.icon10:57:38 やった
絞り込みの都合上、一番上が最新の記録になるように変更した
逆に出来ないこともないが、こっちのほうが見やすそうなのでそのままにする
必要なデータだけを自動で取得・同期するようにしたい
テーブルには最大20件だけ表示して、ページめくりをするとその次の20件を読み込むようにするとか
カレンダーでも同じかな
どう実装するか
配列ではなくiteratorを返せば無限リストとして使える? データ更新中であることを表示したい
データ更新用Hooksでもloadingとerrorを渡すようにする
もしくはPromiseを返す
これだとその場で読み込み中表示を作らないといけない
あんまり柔軟性ないかな?
Nav barにloginしたときだけ表示されるメニューを入れたい
入れたいもの
data exportボタン
2020-12-07 00:41:44 設計が難しいので一旦パス
authDataがundefinedのときの処理をuseExportに入れる必要が出てくるaa
予定やタイムラインへのリンク
どう実装するか
user !== undefinedのときだけ表示するボタンにする
{authData && <>表示したい部品</>}を使う
Login 中はLogin画面からdashboardにredirectするようにする
/icons/doing.iconScrapbox連携
行リンクを紐付ける
どこに記録を書いたか辿ることができる
リンクを登録するのがめんどくさそうtakker.icon
とりあえず登録欄だけでも作っておくか
field name: link
どう表示する?
そのまま表示すると場所を取る
普段は折りたたんで見えなくしておくとか
ふつうはdetailというリンクだけ出しておく
折りたたみを開くとURLの入力欄があわわれる
16:15:30 入力の反映は出来たが、何故かurlをtextareaに表示できない
property間違えている?
そっちにしたら直った
簡単に反映できるようにしたい
案
行リンクを選択した状態で特定のPageMenuを押すと記録が開始される
Scrapboxから起動できるように、APIを用意しておく
その他
ページを開いた状態でPageMenuかなにかを押すと、そのページのタイトルでコマがカレンダーに作成される
つまり1 clickで予定を作れるようにしたい
実装
どうやって実装すればいいのかはよく知らない
記録中でもURLを設定できるようにしたい
現状だと、記録後でないとURLを指定できない
自動読み込み
スクロールで自動読み込み?
一週間前の記録とかを見るのが大変
日付や週単位でpagenation?
こっちで見たいな
絞り込み検索の方が良いのでは?
裏で絞り込みのqueryを発行して、取得範囲を変えるようにしよう
frontendは、ボタンを使うなり検索formを使うなり好きにしてくれ
絞り込みをどちらでやる?
日付で絞り込み
databaseに任せたほうが良さそう
clientでやるしかないな
全dataを取得して、絞り込みをかける
重くならないか?
GitHubにexportする
流石にsandbox上で編集するのが限界に思えてきた
hot reloadしているから遅いし
PWA対応