Notionのサイドバーの表示(開閉)状態をディスプレイ毎に制御するChromeの拡張機能を作った

2024年3月16日JavaScriptchat_bubble0

Notionのサイドバーの表示(開閉)状態をディスプレイ毎に制御するChromeの拡張機能「Notion Sidebar Controller」を作りました。

ディスプレイ毎に以下の制御が可能です。

  • Notionを開いた際の左サイドバーの表示状態
    • 直近の状態、開く、閉じる
  • Notionを開いた際のコメント・更新履歴サイドバーの表示状態
    • 直近の状態、コメントサイドバーを開く、更新履歴サイドバーを開く、アナリティクスサイドバーを開く、閉じる
  • ホバー時に左サイドバーを表示するかどうか

Notionはサイドバーの表示状態をlocalStorageで管理しているため、Notionを開くたびにディスプレイを識別してlocalStorageのデータを変更する必要があれば変更するようにしています。また、必要に応じてサイドバーの開閉イベントを発火させたり開閉のための要素をクリックしたりしてサイドバーを開閉するようにもしています。左サイドバーが閉じられている場合にマウスホバーにより左サイドバーが表示されるという挙動を無効化できるようにもしています。

いずれの機能もマルチモニター環境を意識して実装しました。私が試した限りではNotionのサイドバーを制御する既存の拡張機能やユーザースクリプトでは私の望む挙動にはならず、ディスプレイ毎にサイドバーの表示状態を切り替えられたらなあと考えていたので、欲しかった物を作ったという感じです。

オプションページではディスプレイ毎に先述の制御の設定を行えるようにしています。以下の2つの設定も用意していますが、必要なシーンは限られると思います。

  • Notionを開いた際のサイドバーの状態取得のための待機時間
  • Notionを開いた際に LRU:KeyValueStore2:updateSidebar を削除する

待機時間の設定は通信環境が悪い場合向けです。サイドバーの制御に必要な要素の出現を監視する処理を実装してはいますが、出現しない場合に延々と監視を続けるのは精神衛生上良くないという理由から6秒で監視を停止するようにしているため、通信環境が悪い状態でNotionを開くと適切に制御出来ない可能性があります。ChromeのDevToolsでSlow 3Gを有効にした場合の動作確認は行ったので、通常はデフォの1000ミリ秒から変更する必要は無いと思います。

LRU:KeyValueStore2:updateSidebar(コメント・更新履歴サイドバーの開閉フラグデータ)の削除は、ディスプレイ毎に有効/無効を設定できます。 NotionにおいてlocalStorageにそのデータが存在する場合、ウィンドウサイズの比率によっては LRU:KeyValueStore2:sidebar(左サイドバーの開閉フラグデータ)がtrueになっていても左サイドバーを閉じるという挙動になるようです。その挙動の後、この拡張機能の「左サイドバーの状態」設定で「開く」を選択していた場合には左サイドバーが開きますが、ページを開いてから左サイドバーを開くまでに微妙なラグが生じることになります。そこでlocalStorageから LRU:KeyValueStore2:updateSidebar を削除することでラグが生じないようにします。ラグが生じることがある直接的な原因はページを開いた際のウィンドウサイズの比率に応じたNotion側の処理にあるので、ディスプレイ毎の削除するかしないかの設定を設ける以外の解決策が思いつきませんでした。この設定は必要だと思った場合のみ有効にしてください。ラグ対策でこの設定を有効にする場合は「コメント・更新履歴サイドバーの状態」設定を「直近の状態」か「閉じる」にしておいてください。(「直近の状態」「閉じる」以外の設定ではサイドバーの制御を確実なものにするためにlocalStorageに該当のデータが存在しない場合にデータを登録するという実装にしているため)。

ディスプレイの識別では、ディスプレイ毎のウィンドウと重なる面積を計算し、重なる面積が一番大きいディスプレイをターゲットのディスプレイとして扱うようにしています。面積の計算は、図形の座標から重なっている面積を計算できるOverlap Areaというライブラリを使用しました。座標についてはNotionを開いたタブが含まれるウィンドウの位置・サイズの値と、各ディスプレイの位置・解像度の値(chrome.system.displayで取得)からウィンドウと各ディスプレイの座標データを作成するようにしています。

ウィンドウやディスプレイの位置の値はシステムのメインディスプレイの左端と上端を基準としたleftとtopという値なので、当初は重なる面積を計算するのではなくウィンドウの左上がどのディスプレイにあるかを識別するという感じの実装を試みていたのですが、「ウィンドウの左上がディスプレイの外に出てしまっている場合」を考慮する必要があることに気づき、面倒になって結局そのような実装にはしませんでした。

オプションページはReactとTailwind CSSを使用し、状態管理はZustandを採用しました。
Udemy - complement course data」という拡張機能でRedux Toolkitを採用したときと比較すると楽に実装できたように思います。極小さなオプションページの開発でさえそう実感できるんですから、これがもっと大きなアプリケーションの状態管理になるとより恩恵を実感できるのかもしれません。


トリプルモニター環境でNotionを使用しているので、この拡張機能を作ったことでNotionのサイドバーの開閉挙動で悩まされることが無くなりました。仮にマルチモニター環境でなくともサイドバーの制御には有用だと思うので、使っていただけると嬉しいです。

React,ブラウザ拡張機能

藤乃音りょう