scrapbox-watchlist-sync
使い方
1.
ここをクリックして生成したコードを適当なページのコードブロックに貼り付ける
以下、 /sample-project/scrapbox-watchlist-sync/script.js
に貼り付けたとする
2. 自分のページの script.js
に以下のコードを記入する
jsimport { sync } from "../../sample-project/scrapbox-watchlist-sync/script.js";
sync({
project: "sample-project",
});
常に上書きされるので、手動で書き込まないこと
別のページに書き込みたいときは、 title
を指定する
3. おわり
2024-10-09
11:49:56 また消えちゃった
何が起きている?
12:38:16 わかった
新しい端末でloginすると、参加しているすべてのprojectの accessed
が現在時刻に設定される
結果、参加しているすべてのprojectが直近訪れたprojectとみなされてしまい、それ以外のprojectが下に追いやられてしまう
解決方法
何らかの方法で初回ログイン時の初期設定か、それとも実際にaccessした日時なのかを区別できればいい
問題はその方法だ。どうやって検知する?
12:47:32 解決むずそう
一旦諦める
2024-07-23
23:20:29 いやだめだ。これだと参加してるprojectの更新確認情報が消えてしまう
updated > acessed
なprojectに緑バーを表示している
一旦 .watchlistrc
を削除するか。
23:28:10 直った。今度こそおしまい。
23:14:10 修正完了
22:50:38 復元できない理由がわからない
watchlistの表示の仕組みを調べるしかないか
class ProjectList
で読み込んでいる
23:02:37 わかった
ところが、それにはaccessedが最近の順に上位100件分のproject idしか使われない
この100件が参加しているprojectで埋まってしまっていると、参加しているprojectsの情報は一切載らないことになる
どうすればいいか
保存時に、参加しているprojectのidsを削る
22:19:24 watchlistが消え去る事態に直面している
一旦全ての端末のタブを消そう
21:59:33 バグ発見。古いJSONを .watchlistrc
に保存していた
直した
21:55:59 動いているかあやしい
エラーになったときalertしたい
実装案
✅2(採用)
1
新しいprojectがwatch listに入ったら、それをそのページに書き込む
書き込みはwebsocketを通じてbackgroundで行う
$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/takker/scrapbox-watchlist-sync/script.ts
script.tsimport { patch } from "../scrapbox-userscript-std/websocket.ts";
import { getCodeBlock } from "../scrapbox-userscript-std/rest.ts";
import { isErr, unwrapOk } from "npm:option-t@50/plain_result";
/** 同期設定 */
export interface SyncInit {
/** projectLastAccessedを書き出すページのproject name */
project: string;
/** projectLastAccessedを書き出すページのpage title
*
* @default ".watchlistrc"
*/
title?: string;
}
/** watchListを全てのデバイスで同期する
*
* @param init watchListの保存先ページを決める
*/
export const sync = async (init: SyncInit): Promise<void> => {
const title = init.title ?? ".watchlistrc";
const filename = "projectsLastAccessed.json";
// scrapbox.ioに保存したwatchListを取得する
const res = await getCodeBlock(init.project, title, filename);
const json = isErr(res) ? {} : JSON.parse(unwrapOk(res) || "{}");
/** 端末に保存されたwatchList */
const prev = JSON.parse(
localStorage.getItem("projectsLastAccessed") ?? "{}"
);
// projectおよびそのアクセス日時を更新する
const keys = new Set([...Object.keys(json), ...Object.keys(prev)]);
// 一番新しいアクセス日時を採用する
const newData = Object.fromEntries(
[...keys]
.map((key) => [key, Math.max(json[key] ?? 0, prev[key] ?? 0)] as const)
.sort((a, b) => b[1] - a[1])
);
// 端末とscrapbox.ioに新しいwatchListデータを保存する
const newText = JSON.stringify(newData);
localStorage.setItem("projectsLastAccessed", newText);
await patch(init.project, title, () => [
title,
"This page is automatically generated. DO NOT EDIT ANYTHING, WHITCH WILL BE OVERWRITTEN.",
"",
`code:${filename}`,
` ${newText}`,
"",
]);
};