generated at
scrapbox-watchlist-sync
自動でwatch listの同期を行うUserScript

使い方
1. ここをクリックして生成したコードを適当なページのコードブロックに貼り付ける
以下、 /sample-project/scrapbox-watchlist-sync/script.js に貼り付けたとする
2. 自分のページの script.js に以下のコードを記入する
js
import { sync } from "../../sample-project/scrapbox-watchlist-sync/script.js"; sync({ project: "sample-project", });
この設定では、 /sample-project/.wathlistrc projectsLastAccessedが書き込まれる
常に上書きされるので、手動で書き込まないこと
別のページに書き込みたいときは、 title を指定する
3. おわり

2024-10-09
11:49:56 また消えちゃった
何が起きている?
12:38:16 わかった
新しい端末でloginすると、参加しているすべてのprojectの accessed が現在時刻に設定される
結果、参加しているすべてのprojectが直近訪れたprojectとみなされてしまい、それ以外のprojectが下に追いやられてしまう
解決方法
何らかの方法で初回ログイン時の初期設定か、それとも実際にaccessした日時なのかを区別できればいい
問題はその方法だ。どうやって検知する?
12:47:32 解決むずそう
一旦諦める
とりあえず、login時に手動で端末側のprojectsLastAccessedを消し、コードブロックに保存したwatch listを復元することで対応しよう
2024-07-23
23:20:29 いやだめだ。これだと参加してるprojectの更新確認情報が消えてしまう
updated > acessed なprojectに緑バーを表示している
一旦 .watchlistrc を削除するか。
23:28:10 直った。今度こそおしまい。
23:14:10 修正完了
22:50:38 復元できない理由がわからない
今日更新する以前のprojectsLastAccessedなら、watchlistが消えない
新しく作ったprojectsLastAccessedをsetItemすると、watchlistが全て消えてしまう
watchlistの表示の仕組みを調べるしかないか
class ProjectList で読み込んでいる
23:02:37 わかった
ProjectList.apiPath() api/projectsを組み立てている
ところが、それにはaccessedが最近の順に上位100件分のproject idしか使われない
この100件が参加しているprojectで埋まってしまっていると、参加しているprojectsの情報は一切載らないことになる
どうすればいいか
保存時に、参加しているprojectのidsを削る
22:19:24 watchlistが消え去る事態に直面している
一旦全ての端末のタブを消そう
21:59:33 バグ発見。古いJSONを .watchlistrc に保存していた
直した
21:55:59 動いているかあやしい
エラーになったときalertしたい

実装案
✅2(採用)
projectsLastAccessedの中身をそのままコードブロックに書き込む
remote watch listのコードとscrapbox2anki crawl.ts を組み合わせて実装する
1
ある特定のページをcloud watch listとして用いる
書式はrmaruonさんのテーブル記法を用いる
新しいprojectがwatch listに入ったら、それをそのページに書き込む
書き込みはwebsocketを通じてbackgroundで行う

$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/takker/scrapbox-watchlist-sync/script.ts
script.ts
import { 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}`, "", ]); };

#2024-10-09 11:50:09
#2024-07-23 21:56:20
#2023-04-29 09:03:22
#2022-08-05 12:32:25