Skip to content

🖥 002 PCローカル・UI設計

画面構成・モジュール構造・データ構造・データフロー

設計書 v1.0 / 2026-04-19


1 画面構成

PCアプリはメインウィンドウ1枚+付箋ウィンドウN枚のマルチウィンドウ構成です。

PC アプリのウィンドウ構成(メインウィンドウ 1 枚 + 付箋ウィンドウ N 枚)
⚙️ 設定
一般設定
通常はトレイに常駐
1.1 🏠 メインウィンドウ
app/page.tsx
役割
アプリの司令塔。ユーザーには見えないことが多い(トレイ常駐)
機能
起動時に付箋ウィンドウを生成・配置
設定画面・検索オーバーレイを表示
トレイアイコンのイベントを受け取る
iPhone からの受信(ポーリング)を担当
ファイル
app/page.tsx
買い物リスト
📌
☑ パンを買う
☐ 牛乳
☐ 卵×6
BH1
1.2 📝 付箋ウィンドウ(N 枚)
StickyNote.tsx
役割
付箋 1 枚ごとに独立した WebviewWindow
機能
テキスト編集(RichTextEditor)
ピン留め・たたむ・色変更
右クリックメニュー(iPhone 送信・アーカイブ等)
画像キャプチャ・リンク挿入
ファイル
app/components/StickyNote.tsx

1.3 ウィンドウ生成の仕組み

付箋1枚ごとに独立したTauriウィンドウが生成される仕組みを図示します。

図 2-1 ウィンドウ生成の仕組み


2 モジュール構造

フロントエンド(TypeScript/React)とバックエンド(Rust)の2層構成です。

2.1 フロントエンド(TypeScript / React)

付箋ウィンドウを構成する主要コンポーネント・フック・ユーティリティの依存関係を示します。

図 2-2 フロントエンドモジュール構成

2.2 バックエンド(Rust)

TauriコマンドとAppStateを中心とするRust側モジュールの役割を一覧します。

表 2.2-1 バックエンドモジュール一覧

Noファイル役割主な責務
1main.rsエントリーポイントTauri アプリ起動・プラグイン登録・シングルインスタンス制御
2lib.rsinvoke ハンドラ定義フロントエンドから呼ばれる全コマンドを宣言。処理は各モジュールに委譲
3state.rsAppState(唯一の状態)ノート一覧・設定・VAPID鍵・デバイス情報をメモリ上で保持。Mutex で排他制御
4settings.rs設定管理base_path・言語・フォントサイズ等を settings.json に読み書き
5logic.rs付箋ビジネスロジックノート作成・保存・リネーム・アーカイブ・削除・タグ管理
6storage.rsファイル I/OMarkdown ファイルの読み書き・frontmatter パース
7tray.rsトレイアイコントレイメニュー生成・全表示/全隠し・クリックイベント処理
Noファイル役割主な責務
8webpush.rsプッシュ通知送信VAPID 鍵生成・APNs/FCM への Web Push 送信
9gdrive.rsGoogle Drive 連携Drive ファイルの読み書き・ポーリング(iPhone からの受信検出)
10capture.rs画像キャプチャSnipping Tool 起動・クリップボード画像を assets/ に保存
11clipboard.rsクリップボードテキスト・画像のクリップボード読み書き
12sound.rs効果音保存音・通知音などの再生
13import.rsファイルインポート外部 Markdown ファイルを Vault に取り込む
14logger.rsログデバッグログの出力管理

3 データ構造

付箋ファイル・設定ファイル・モジュール依存の3種類のデータ構造を定義します。

3.1 付箋データ(Markdown ファイル = frontmatter + 本文)

付箋1枚 = Markdown ファイル1枚。PC ローカルのファイルシステムが正。Drive は中継所に過ぎない。

表 3.1-1 付箋データフィールド一覧

Noフィールド意味
1bodystring本文テキスト(Markdown)
2pathstringファイルパス(実質的な主キー)
3contextstringコンテキスト名(本文1行目から自動生成)
4updatedstring最終更新日時
5x, ynumber?画面上の位置座標
6width, heightnumber?ウィンドウサイズ
Noフィールド意味
7background_colorstring?付箋の背景色
8always_on_topbool?最前面固定(ピン留め)
9foldedbool?折りたたみ状態(最小化)
10seqi32重なり順(Z-index 相当)
11tagsstring[]タグ一覧

3.2 設定データ(settings.json

settings.json で管理するアプリ全体の設定項目5点を定義します。

表 3.2-1 設定データフィールド一覧

Noフィールド意味
1base_pathstring?Vault フォルダのパス(未設定なら初回セットアップ画面)
2languagestring表示言語
3auto_startbooleanOS 起動時に自動起動するか
Noフィールド意味
4font_sizenumber基本フォントサイズ
5sound_enabledboolean効果音 ON/OFF

3.3 クラス図(依存関係)

主要モジュール間の依存関係をMermaidクラス図で示します。

図 2-3 クラス図(主要モジュール依存関係)


4 データフロー

アプリ起動から保存・画像・検索・iPhone連携まで6つのシーケンス図を示します。

4.1 アプリ起動

起動時にファイルシステムから付箋一覧を読み込むフローです。

図 2-4 アプリ起動シーケンス

4.2 付箋の保存・自動リネーム

本文の1行目をファイル名(context)として自動採用する。800ms のデバウンスで連続入力に追従。

図 2-5 付箋の保存・自動リネームシーケンス

4.3 画像キャプチャ

OS 内蔵の Snipping Tool を呼び出し、撮影された画像を Vault の assets/ に自動保存する。

図 2-6 画像キャプチャシーケンス

4.4 全文検索

キーワードをリアルタイムで全付箋から検索するフローです。

図 2-7 全文検索シーケンス


5 UI インタラクション

付箋ウィンドウの操作領域・モード・マウス挙動を定義します。

5.1 モード定義

表示・編集の2モードとその遷移条件を定義します。

表 5.1-1 モード定義

Noモード状態
1表示モード(閲覧中)Markdown としてレンダリング済みの付箋を読んでいる状態
2編集モード(執筆中)カーソルが点滅し文字を書き込める状態。背景が半透明の白になる

図 2-8 モード遷移図

5.2 操作領域の定義

付箋ウィンドウをエディタ本文・余白(A)・フッタ(B)の3エリアに分けて操作を割り当てます。

ヘッダー領域(ドラッグでウィンドウ移動)(A)エディタ余白(ドラッグ→ウィンドウ移動)(DBクリック→編集開始)エディタ本文(テキスト・リンク)(B) フッタ領域文字が存在しない下部の空間(エディタ外)クリック→編集終了 / DBクリック→文末から編集開始エディタ本文(A) 余白(B) フッタ

図 2-9 付箋ウィンドウの操作領域

表 5.2-1 操作領域の定義

No領域場所ユーザーの意図
1エディタ本文文字・リンクが実際に存在する場所「ここを直接操作・書き換えたい」
2(A) エディタ余白文字の右側・左側に広がる枠線内の空白「この行の続きや近くから書き込みたい」
3(B) フッタ領域最後の行より下にある何もない空間(エディタ外)「一番下から追記したい」または「編集を終わらせたい」

5.3 インタラクション・マトリックス

エリア × 操作の組み合わせで起きる動作を一覧にまとめます。

5.3.1 🖱 ワンクリック

表 5.3-1 ワンクリック操作一覧

Noクリックした場所表示モード編集モード
1エディタ本文何もしない(ドラッグ準備)カーソル移動(その文字へ)
2(A) エディタ余白何もしない(ドラッグ準備)カーソル移動(最近傍の文字へ)
3(B) フッタ領域何もしない(ドラッグ準備)編集終了
4リンクリンクを開くカーソル移動
5ウィンドウ外フォーカス解除編集終了(保存して表示モードへ)

5.3.2 🖱🖱 ダブルクリック

表 5.3-2 ダブルクリック操作一覧

Noクリックした場所表示モード編集モード
1エディタ本文編集開始(クリックした文字から)単語選択
2(A) エディタ余白編集開始(最近傍の文字から)
3(B) フッタ領域編集開始(文末から)

5.3.3 ✋ ドラッグ(押しっぱなしで移動)

表 5.3-3 ドラッグ操作一覧

Noドラッグした場所表示モード編集モード
1エディタ本文🪟 ウィンドウ移動📝 テキスト範囲選択
2(A) エディタ余白🪟 ウィンドウ移動🪟 ウィンドウ移動
3(B) フッタ領域🪟 ウィンドウ移動🪟 ウィンドウ移動

6 機能一覧

システムトレイメニュー・付箋のツールバー・右クリックメニュー・設定画面の機能と、各機能の設計意図を記します。

6.1 システムトレイメニュー

タスクバーのトレイアイコンを左クリック(または右クリック)すると表示されるメニューです。show_menu_on_left_click(true) の設定により、左クリックでもメニューが開きます。

表 6.1-1 システムトレイメニュー項目

項目機能設計意図・工夫
新規メモ新しい付箋を作成するプールウィンドウ方式(後述)で表示遅延ゼロを実現。トレイが発火すると fusen:create_note_from_tray をメインウィンドウに emit し、JS 側が昇格処理を担う
検索全文検索オーバーレイを開くVault 内の全 .md を Rust 側で行単位に grep。ヒットした 1 件目は自動的に対象ウィンドウにジャンプし、Enter/Shift+Enter/F3 で前後の結果をナビゲートできる
全部隠す(Ctrl+Shift+H)全付箋を非表示にするWebView2 の COM 層がネスト呼び出しでスタックオーバーフローを起こす問題を、JS 側が 1 窓ずつ 50ms 間隔でシリアルに処理することで回避
全部戻す非表示の全付箋を再表示する同上。Rust 側の LAST_VISIBILITY_MS(AtomicU64)で前回操作から 3 秒以内の連打をブロック。JS の連打と Rust のガードで二重に守る
タグで絞り込むタグ選択で表示付箋を絞り込むメニューを開くたびに Vault を再スキャンして最新タグを取得。☑/☐ で選択状態を可視化。タグトグルは std::thread::spawn で非同期処理し、Win32 同期メッセージによるスタック消費を防ぐ
設定設定画面を開くメインウィンドウは通常 hidden。show()unminimize()set_focus() の順で先に表示を確保してから fusen:open_settings を emit する。順序が逆だとウィンドウが invisible のままイベントを受け取れない
終了アプリを終了するapp.exit(0) で全 WebView ウィンドウを即時破棄。on_window_event を経由せず直接 OS プロセスを終了させる

6.2 付箋のツールバー

付箋にカーソルを乗せると右上にホバー表示されるツールバーです。閲覧モードと編集モードで表示が切り替わります。

表 6.2-1 閲覧モードのツールバー項目

ボタン機能設計意図・工夫
新規付箋を作成するプールウィンドウ方式で即時表示。ウェルカムノートでは animate-bounce + オレンジ色になり「ここから始めよう」と誘導する
△/▽付箋を折りたたむ/広げるタイトルバーの高さだけに縮小する。高さは logicalHeight × scaleFactor で物理ピクセル精度に変換し、高 DPI モニタでもズレない。折りたたみ中にユーザーが手動でウィンドウを広げた場合(10 物理 px 以上)は自動展開し、そのサイズを新たな「展開サイズ」として記憶する
ピン(📌)付箋を最前面に固定するピン状態によって SVG の形が変わる:ONは「縦に刺さったピン+影」、OFFは「斜め45°に倒れたピン」。固定 ON 時は「ギュッ」音(120 Hz 三角波 → 60 Hz、80ms)、固定 OFF 時は「ポン」音(400 Hz → 800 Hz サイン波、100ms)を AudioContext で生成。音声ファイルをバンドルせず、コードだけで音を作る

表 6.2-2 編集モードのツールバー項目

ボタン機能設計意図・工夫
選択テキストをMarkdownテーブルに変換CSV 風に入力したテキストをテーブル記法に一発変換
🔷Mermaidダイアグラムのテンプレートを挿入フローチャート・シーケンス図のひな形を即挿入
カメラ画面キャプチャを付箋に貼り付けるOS 内蔵の Snipping Tool を起動し、撮影した画像を assets/ に保存して ![]() 記法で本文に挿入
フローティングフォーマットバーテキスト選択時に選択範囲の真上に浮き上がる B / H1 / ≡ / ☑ の 4 ボタンツールバーを探さなくていい。選んだ瞬間にフォーマット操作ができる。座標は CodeMirror の coordsAtPos() で計算し、ウィンドウ上端を超える場合は下に反転(flip)してウィンドウ内に収める

6.3 付箋右クリックメニュー(閲覧モード)

付箋を閲覧モードで右クリックしたときのメニューです。

表 6.3-1 付箋右クリックメニュー(閲覧モード)項目

項目機能設計意図・工夫
📄 ファイル名現在の付箋ファイル名を表示(選択不可)付箋は似たような見た目が並ぶ。「いまどの付箋を操作しているか」をメニューの冒頭で示すことで誤操作を防ぐ
📂 フォルダを開く付箋ファイルが保存されているフォルダをエクスプローラーで開く「脱出口」。データは平文 .md。エクスプローラー・Obsidian・VS Code からいつでも直接触れる設計。データはユーザーが完全に所有する
✨ 新規メモ(Ctrl+N)新しい付箋を作成するwin.outerPosition()(物理ピクセル)と scaleFactor を取得してメインプロセスに渡し、30 論理 px ずらした位置で出現。DPI 混在マルチモニタ環境でも正確にずれる
📋 複製現在の付箋を複製する同上のオフセット機構を使用。内容・フォーマット・タグを含めてそのままコピーし、隣に並べる
🎨 色変更付箋の背景色を変更する(青 / ピンク / 黄)3 色のみ。選択肢を絞ることで決断疲れを排除した設計。色は frontmatter の background_color に保存されアプリ再起動後も維持される
🏷️ タグタグの追加・トグル・削除モードのサブメニューメニューを開く瞬間に fusen_get_all_tags で最新タグ一覧を Rust から取得(React state の古い値を使わない)。削除モードへの切り替えは shouldReopenMenu.current = true でメニューを閉じた直後に同じ座標で再表示する
⏰ アラームを設定付箋にアラームを設定する「5分後」〜「1週間後」のクイックボタン+日時直接指定の 2 モード。時刻は JST (+09:00) でフロントマター alarm_at に保存。時刻になると付箋が点滅し、効果音が鳴る
📱 iPhoneに送る付箋の内容を iPhone に送信する送信前に fusen_check_pro_setup で Google Drive への実際の接続とプッシュ設定ファイルの存在を確認(ローカル状態ではなく Drive を実際に叩く)。未設定なら { tab: 'iphone' } を添えて設定画面の iPhone 連携タブへ直行
📦 アーカイブ付箋をタグフォルダ or Archive フォルダに移動する移動前にアプリ固有 frontmatter(background_color・geometry 等)を strip_sticky_fields で除去してから書き込む。関連画像を先にコピーし、コピー成功後に元ファイルを削除するフォールセーフな順序。複数タグ付きならサブメニューで移動先を選択
🗑️ 削除(Ctrl+D)付箋をゴミ箱に移動するfusen_move_to_trash で OS のゴミ箱へ。削除音を鳴らしてからウィンドウを hide()destroy() する順序で、ユーザーに白紙フレームを見せない

6.4 付箋右クリックメニュー(編集モード)

編集モード中に右クリックすると切り替わるメニューです。テキスト操作に特化しています。

表 6.4-1 付箋右クリックメニュー(編集モード)項目

項目機能設計意図・工夫
Undo / Redo直前の操作を取り消す / やり直すPredefinedMenuItem で OS ネイティブ操作にバインド。CodeMirror の編集履歴をそのまま使う
切り取り / コピー / 貼り付け / 全選択標準テキスト操作同上。Web クリップボード API ではなく OS ネイティブのクリップボード連携
📅 今日の日付(曜日付き)カーソル位置に 2026-04-27(日) 形式で挿入メニュー項目名自体に挿入後の実際の文字列を表示する。「Insert date」ではなく「📅 2026-04-27(日)」と書くことで、押す前に何が入るか分かる。Intl.DateTimeFormat で言語設定に従い曜日を自動変換(ja: 日・月・火、en: Sun・Mon・Tue)
🕒 現在時刻カーソル位置に HH:MM 形式で挿入同上。議事録・タスクログに時刻を一瞬で打ち込める
📅🕒 日付+時刻カーソル位置に日付と時刻を両方挿入上の 2 項目を 1 アクションに合わせたショートカット

6.5 設定画面

システムトレイ → 設定 から開く設定画面のタブと設定項目です。

表 6.5-1 設定画面タブ一覧

タブ設定項目設計意図・工夫
一般設定言語(日本語 / English)・自動起動 ON/OFF・効果音 ON/OFF言語切り替えは全付箋ウィンドウの UI に即時反映。自動起動は tauri-plugin-autostart で Windows の HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run に登録。トグル操作が完了した瞬間に有効になる
外観フォントサイズ(10〜32px、スライダーで変更)スライダーをドラッグしながらリアルタイムにプレビューが更新される。決定した値は CSS 変数として全ウィンドウに伝播する
データVault フォルダのパス変更・他フォルダからの Markdown インポートインポートは .md ファイルと関連画像(fusen_img_*)を一括取り込む。Obsidian・Notion エクスポート・手書き md からの移行を想定。Vault フォルダ変更後は全付箋を再スキャンして再生成する
iPhone 連携Google Drive 連携の設定・認証PKCE フロー(サーバーレス OAuth)でトークンをローカルにのみ保存。Drive 接続が切れると本タブのアイコンに赤バッジが表示される。フィードバック Discord Webhook URL はバイナリに含めず Vercel 環境変数に持つ
このアプリについてアプリバージョンの表示getVersion() が Cargo.toml からランタイムに読む。バージョン文字列はフロントエンドにハードコードされていない
フィードバック開発者へのフィードバック送信送信内容は Discord Webhook 経由で開発者に届く。Webhook URL は Vercel 環境変数に持ち、バイナリには含めない

7 エラーハンドリング・リカバリ方針

7.1 ローカルファイルとリカバリ

7.1.1 保存時のパス喪失保護(増殖バグ回避)

ユーザーが手動でファイルを移動・削除した場合や、リネーム処理が直前に行われた場合、古いパスに対する自動保存(ジオメトリ変更など)が発火すると古い名前でファイルが復活してしまう(増殖バグ)。 これを防ぐため、logic.rs の保存処理では**「上書き対象のファイルパスが物理的に存在するか(!current_path_obj.exists())」をチェック**し、存在しない場合は保存処理をブロック(Err 返却)してトレースログを出力する保護機構を備えている(実施済み)。

7.1.2 アトミック書き込みによるファイル破損防止

付箋内容の保存は、一時ファイルへの書き込み完了後に元のファイルへ rename するアトミック書き込みで行う。これにより、保存処理中の予期せぬ電源断やクラッシュによるデータ欠損・破損を完全に防ぐ(実施済み)。 ファイルシステムエラー(書き込み権限なし等)が発生した場合は、保存を中止し Tauri コマンドのエラーとして返却する。

7.1.3 PC アプリ再起動時の状態復元

起動時に Vault フォルダを全スキャン(フロントマター解析)して付箋ウィンドウを再生成するため、アプリが異常終了した場合でも次回起動時にファイルの状態から自動復元される(実施済み)。 ただし、終了直前の「メモリ上にしか存在しない未保存の内容」は失われる(保存タイミングは blur 時またはデバウンス 800ms 経過後)。


8 環境変数・シークレット

PC版(Tauri アプリ)のビルド・リリースに必要な変数・シークレットの一覧です。

8.1 ローカルビルド用(.env.local

src-tauri/build.rs がコンパイル時に読み取り、バイナリに直接埋め込む。.env.local.gitignore 対象のため Git には含まない。

表 8.1-1 ローカルビルド用環境変数(.env.local)

変数名取得元用途
GDRIVE_CLIENT_IDGoogle Cloud Console → 認証情報 → OAuth 2.0 クライアント(Tauri用) → クライアント IDPC版 Drive 認証の OAuth Client ID。gdrive.rs 内で env!() マクロで参照。
GDRIVE_CLIENT_SECRETGoogle Cloud Console → 認証情報 → OAuth 2.0 クライアント(Tauri用) → クライアント シークレットPC版 Drive 認証の OAuth Client Secret。gdrive.rs 内で env!() マクロで参照。

8.2 CI/CD用(GitHub Secrets)

GitHub Actions のリリースワークフロー(release.yml / do-release.yml)が参照するシークレット。

表 8.2-1 CI/CD用 GitHub Secrets

シークレット名用途設定するワークフロー
GDRIVE_CLIENT_IDTauri ビルド時の Drive Client ID(ローカルと同値)release.yml
GDRIVE_CLIENT_SECRETTauri ビルド時の Drive Client Secret(ローカルと同値)release.yml
TAURI_SIGNING_PRIVATE_KEYTauri アップデーター署名用秘密鍵release.yml
TAURI_SIGNING_PRIVATE_KEY_PASSWORD上記秘密鍵のパスフレーズrelease.yml
WINGET_TOKENwinget-pkgs への PR 作成用 PAT(public_repo スコープ必要)release.yml
WINGET_APP_IDdo-release.yml が main ブランチへ push するための GitHub App IDdo-release.yml
WINGET_APP_PRIVATE_KEY上記 GitHub App の秘密鍵do-release.yml

9 改版履歴

表 9-1 改版履歴

Noバージョン日付変更内容
11.026-04-19新規作成。旧 001_ARCHITECTURE_DESIGN.html のPC側内容(構造図・クラス図・シーケンス図・ER図)を統合・整理
21.126-04-24ウィンドウ構成図を graph LR(横向き)に変更。スクロールなしで全体が見えるよう改善。
31.226-04-26セクション7「環境変数・シークレット」を新規追加。ローカルビルド用とCI/CD用を分けて記載。
41.326-04-27セクション6「機能一覧」を新規追加(システムトレイ・ツールバー・右クリックメニュー・設定画面)。各機能に設計意図・工夫を追記。旧6→7、旧7→8、旧8→9に繰り下げ。