Closed5

X でデフォルトタイムラインを「おすすめ」から「フォロワー」に変えるブックマークレット

KeiKei


javascript:(async()=>{let e=document.cookie.split(" ").find(e=>e.startsWith("twid")),t=/\d+(?=;$)/.exec(e??"")[0];if(void 0===e){alert("先にログインしてね");return}let s=window.indexedDB.open("localforage"),i=await new Promise(e=>s.onsuccess=()=>e(s.result)),n=i.transaction("keyvaluepairs","readwrite"),l=n.objectStore("keyvaluepairs"),a=await new Promise(e=>{let t=l.getAllKeys();t.onsuccess=()=>e(t.result)}),r=a.find(e=>"string"==typeof e&&e.endsWith("pinnedTimelines"));if(void 0!==r){let o=l.get(r),c=await new Promise(e=>o.onsuccess=()=>e(o.result));if("home_latest"===c.selectedTimeline.type){alert("既に設定されています");return}}let d=l.put({selectedTimeline:{type:"home_latest"},sort:"Relevance",_lastPersisted:17144892e5},user:${t}:rweb.pinnedTimelines);d.onsuccess=()=>{alert("処理が成功しました。ページを再読み込みしてください。")}})()

KeiKei

このままコピペして貼り付けようとするとブラウザによっては最初の「javascript:」が勝手に切り取られてしまうので、うまくいかない場合は「javascript:」だけ自分で書いてからコピペしてください

KeiKei

自分用メモとしてのコメントも含む minify する前のソースはこちら

(async () =>{
  // IndexedDB で使う ID
  const twidCookie = document.cookie.split(" ").find(cookie => cookie.startsWith("twid"))
  const twid = /\d+(?=;$)/.exec(twidCookie ?? "")[0]

  if (twidCookie === undefined) {
    alert("先にログインしてね")

    return
  }

  const db = window.indexedDB.open("localforage")
  /** @type IDBDatabase */
  const targetDb = await new Promise(r => db.onsuccess = () => r(db.result))
  const dbTransaction = targetDb.transaction("keyvaluepairs", "readwrite")
  const objectStore = dbTransaction.objectStore("keyvaluepairs")
  /** @type IDBValidKey[] */
  const objectStoreKeys = await new Promise(r => {
    const request = objectStore.getAllKeys()

    request.onsuccess = () => r(request.result)
  })

  const timelineKey = objectStoreKeys.find(key => (typeof key === "string") && key.endsWith("pinnedTimelines"))

  // 既にあった場合、そのことを通知して何もせず終了する
  // これはいつか起きるかもしれない「この設定が無視されるようになったこと」の判別にもなる
  if (timelineKey !== undefined) {
    const req = objectStore.get(timelineKey)
    /** @type {{ selectedTimeline: { type: "home_latest" | string } }} */
    const result = await new Promise(r => req.onsuccess = () => r(req.result))

    if (result.selectedTimeline.type === "home_latest") {
      alert("既に設定されています")

      return
    }
  }

  // とりあえずコピペしたものの型通りに設定
  const setTimelineSettings = objectStore.put({
    selectedTimeline: { type: "home_latest" },
    // 並び替える設定なんてあったっけ?
    sort: "Relevance",
    // タイムスタンプを設定する
    // とりあえず日本時間の 2024/05/01 00:00 で設定
    "_lastPersisted": 1714489200000
  }, `user:${twid}:rweb.pinnedTimelines`)

  setTimelineSettings.onsuccess = () => {
    alert("処理が成功しました。ページを再読み込みしてください。")
  }
})()
KeiKei

ざっくりとした解説:

デフォルトのタイムラインをどちらにするかは IndexedDB のデータから判別されているので、その IndexedDB のデータをいじります。
以上。

KeiKei

ブックマークレット用なのでライブラリ無しの vanillaJS で書いたけど、IndexedDB の Promise 版がほしいなと強く思った。

このスクラップは2024/05/17にクローズされました