# 機能設計書 120-Aboutダイアログ

## 概要

アプリケーションのバージョン情報ダイアログを表示する機能（OpenAbout アクション / AboutDialog）の設計書である。

### 本機能の処理概要

本機能は、Windows Terminal のバージョン情報、更新確認、関連リンク（ソースコード、ドキュメント、リリースノート、プライバシーポリシー、サードパーティライセンス）を含むダイアログを表示する。また、パッケージの更新確認機能を備え、新しいバージョンが利用可能かどうかを非同期にチェックする。

**業務上の目的・背景**：ユーザーが現在使用している Windows Terminal のバージョンを確認し、更新の有無を把握するために必要な機能である。また、オープンソースプロジェクトとして、ソースコードやドキュメントへのリンクを提供することで、コミュニティへの参加やフィードバックの送信を容易にする。

**機能の利用シーン**：ユーザーがアプリケーションのバージョンを確認したい場合、更新が利用可能かチェックしたい場合、フィードバックを送信したい場合、サードパーティライセンスを確認したい場合に使用される。

**主要な処理内容**：
1. OpenAbout アクションにより AboutDialog を表示する
2. アプリケーション名とバージョン番号を取得・表示する
3. パッケージ更新の確認を非同期で実行する
4. 各種リンク（ソースコード、ドキュメント等）を表示する
5. フィードバック送信ボタンとサードパーティライセンスリンクを提供する

**関連システム・外部連携**：
- Windows Package Manager API（PackageUpdateAvailability）による更新確認
- Windows Store Context API（GetAppAndOptionalStorePackageUpdatesAsync）による Store 経由の更新確認
- ShellExecute による外部URLのブラウザ表示
- NOTICE.html ファイルのブラウザ表示

**権限による制御**：特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 13 | AboutDialog（バージョン情報） | 主画面 | バージョン番号・更新確認・ドキュメントリンクの表示 |
| 1 | TerminalPage（メイン画面） | 遷移元画面 | _HandleOpenAbout / _ShowAboutDialog で AboutDialog を表示 |

## 機能種別

UI表示・情報表示処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| （パラメータなし） | - | - | 本アクションはパラメータを取らない | - |

### 入力データソース

- CascadiaSettings::ApplicationDisplayName()（アプリケーション名）
- CascadiaSettings::ApplicationVersion()（バージョン番号）
- Windows Package Manager API（更新情報）
- Windows Store Context API（更新情報、フォールバック）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ApplicationDisplayName | hstring | アプリケーション表示名 |
| ApplicationVersion | hstring | バージョン番号 |
| UpdatesAvailable | bool | 更新が利用可能か |
| CheckingForUpdates | bool | 更新確認中か |

### 出力先

AboutDialog（ContentDialog）として TerminalPage 上にモーダル表示。

## 処理フロー

### 処理シーケンス

```
1. _HandleOpenAbout が呼び出される
   └─ _ShowAboutDialog を呼び出す
2. AboutDialog のコンストラクタが実行される
   └─ InitializeComponent() で XAML を初期化
3. _queueUpdateCheck が非同期で実行される
   └─ 最終チェックから1日以上経過している場合のみ実行
4. 更新確認処理
   a. CheckingForUpdates = true に設定（プログレスリング表示）
   b. DEV ブランド: 3秒待機後に UpdatesAvailable = true
   c. リリースブランド: PackageManager で更新確認
   d. PackageManager が応答しない場合: StoreContext でフォールバック
5. CheckingForUpdates = false に設定
6. ダイアログが表示される
   └─ バージョン情報、更新状態、リンク一覧が表示される
```

### フローチャート

```mermaid
flowchart TD
    A[_HandleOpenAbout] --> B[_ShowAboutDialog]
    B --> C[AboutDialog コンストラクタ]
    C --> D[InitializeComponent]
    D --> E[_queueUpdateCheck 開始]
    E --> F{最終チェックから1日以上経過?}
    F -->|No| Z1[co_return]
    F -->|Yes| G{IsPackaged?}
    G -->|No| Z1
    G -->|Yes| H[CheckingForUpdates = true]
    H --> I{WT_BRANDING_DEV?}
    I -->|Yes| J[3秒待機後 UpdatesAvailable = true]
    I -->|No| K[PackageManager で更新確認]
    K --> L{応答あり?}
    L -->|Yes| M[UpdatesAvailable を設定]
    L -->|No| N[StoreContext でフォールバック]
    N --> O{更新あり?}
    O -->|Yes| P[UpdatesAvailable = true]
    O -->|No| Q[変更なし]
    J --> R[CheckingForUpdates = false]
    M --> R
    P --> R
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-120-01 | 更新確認間隔 | 最終チェックから1日以上経過した場合のみ更新確認を実行する | _queueUpdateCheck 呼び出し時 |
| BR-120-02 | パッケージ確認 | IsPackaged() が true の場合のみ更新確認を実行する（非パッケージビルドでは実行しない） | 更新確認時 |
| BR-120-03 | DEV ブランド特別動作 | WT_BRANDING_DEV の場合は3秒待機後に常に UpdatesAvailable = true とする（テスト用） | DEVビルド時 |
| BR-120-04 | 二段階確認 | まず PackageManager で確認し、応答がない場合は StoreContext でフォールバックする | リリースビルド時 |
| BR-120-05 | フィードバックURL | RELEASE ブランドと DEV/その他ブランドでフィードバック送信URLが異なる | フィードバック送信時 |
| BR-120-06 | サードパーティライセンス | NOTICE.html をアプリケーションの実行ファイルと同じディレクトリから読み込む | ライセンス表示時 |

### 計算ロジック

- 更新確認間隔: `now - _lastUpdateCheck < std::chrono::days{1}` で判定
- 更新可用性: PackageUpdateAvailability::Available または Required の場合に UpdatesAvailable = true

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パッケージ取得失敗 | Package::Current() や FindPackageForUser が失敗した場合 | catch(...) で吸収し、StoreContext にフォールバック |
| - | Store確認失敗 | StoreContext の API が失敗した場合 | catch(...) で吸収 |
| - | 非パッケージ環境 | IsPackaged() が false の場合 | 更新確認をスキップ |

### リトライ仕様

リトライは行わない。次回ダイアログ表示時に再度チェックされる（1日間隔）。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

- 更新確認は非同期コルーチンで実行されるため、UIのブロッキングは発生しない
- 更新確認中はプログレスリングが表示される

## セキュリティ考慮事項

- 外部URLへのアクセスは ShellExecute を使用し、ブラウザに委譲する
- フィードバックURLは Microsoft の公式リンク（go.microsoft.com）
- パッケージ更新確認は Windows の標準API を使用する

## 備考

- ContentDialog として実装され、DefaultButton は Close に設定されている
- PrimaryButton がフィードバック送信に使用される
- バージョン情報のテキストは選択可能（IsTextSelectionEnabled="True"）
- 各リンクは HyperlinkButton として実装され、NavigateUri で直接URLに遷移する
- サードパーティライセンスのみ Click イベントハンドラで NOTICE.html を開く

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AboutDialog.h | `src/cascadia/TerminalApp/AboutDialog.h` | **10-31行目**: AboutDialog クラス定義。ApplicationDisplayName、ApplicationVersion メソッドと UpdatesAvailable、CheckingForUpdates プロパティ。_lastUpdateCheck で最終チェック時刻を管理 |

**読解のコツ**: WINRT_OBSERVABLE_PROPERTY マクロは、値の変更時に PropertyChanged イベントを発火する WinRT プロパティを定義する。XAML のデータバインディングで使用される。

#### Step 2: XAML UIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AboutDialog.xaml | `src/cascadia/TerminalApp/AboutDialog.xaml` | **1-68行目**: ContentDialog ベースのXAML定義。アプリ名とバージョンの表示、更新確認プログレスリング、更新通知、各種HyperlinkButton |

**主要UIコンポーネント**:
- **20-28行目**: アプリケーション名とバージョン番号の TextBlock
- **31-41行目**: 更新確認中のプログレスリング（CheckingForUpdates にバインド）
- **42-51行目**: 更新利用可能メッセージ（UpdatesAvailable にバインド）
- **56-65行目**: 各種リンク（ソースコード、ドキュメント、リリースノート、プライバシーポリシー、サードパーティライセンス）

#### Step 3: 処理ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AboutDialog.cpp | `src/cascadia/TerminalApp/AboutDialog.cpp` | **28-32行目**: コンストラクタ。InitializeComponent と _queueUpdateCheck の呼び出し |
| 3-2 | AboutDialog.cpp | `src/cascadia/TerminalApp/AboutDialog.cpp` | **34-42行目**: ApplicationDisplayName と ApplicationVersion。CascadiaSettings の static メソッドを呼び出す |
| 3-3 | AboutDialog.cpp | `src/cascadia/TerminalApp/AboutDialog.cpp` | **60-148行目**: _queueUpdateCheck。非同期更新確認の実装。1日間隔チェック、DEV/RELEASE ブランド分岐、PackageManager/StoreContext 二段階確認 |

**主要処理フロー（_queueUpdateCheck）**:
1. **63-67行目**: 1日以内にチェック済みの場合は co_return
2. **70-73行目**: 非パッケージ環境の場合は co_return
3. **76-77行目**: CheckingForUpdates = true、UpdatesAvailable = false
4. **81-86行目**: DEVブランドの場合は3秒待機後に UpdatesAvailable = true
5. **92-117行目**: PackageManager で CheckUpdateAvailabilityAsync を実行
6. **123-138行目**: PackageManager が応答しない場合は StoreContext でフォールバック
7. **146-147行目**: CheckingForUpdates = false

#### Step 4: イベントハンドラを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AboutDialog.cpp | `src/cascadia/TerminalApp/AboutDialog.cpp` | **44-51行目**: _SendFeedbackOnClick。ブランドに応じたフィードバックURLを ShellExecute で開く |
| 4-2 | AboutDialog.cpp | `src/cascadia/TerminalApp/AboutDialog.cpp` | **53-58行目**: _ThirdPartyNoticesOnClick。NOTICE.html を実行ファイルのディレクトリから読み込んでブラウザで開く |

### プログラム呼び出し階層図

```
TerminalPage::_HandleOpenAbout (AppActionHandlers.cpp:1620)
    |
    +-- TerminalPage::_ShowAboutDialog
            |
            +-- AboutDialog コンストラクタ (AboutDialog.cpp:28)
                    |
                    +-- InitializeComponent (XAML 初期化)
                    |
                    +-- _queueUpdateCheck (AboutDialog.cpp:60)
                            |
                            +-- [DEV] 3秒待機 → UpdatesAvailable = true
                            |
                            +-- [RELEASE] PackageManager::CheckUpdateAvailabilityAsync
                            |       |
                            |       +-- Available/Required → UpdatesAvailable = true
                            |       +-- NoUpdates → UpdatesAvailable = false
                            |       +-- Error/Unknown → StoreContext にフォールバック
                            |
                            +-- StoreContext::GetAppAndOptionalStorePackageUpdatesAsync
                                    |
                                    +-- 更新あり → UpdatesAvailable = true
```

### データフロー図

```
[入力]                          [処理]                              [出力]

CascadiaSettings ──>  ApplicationDisplayName ──>  ダイアログ表示
                      ApplicationVersion         （名前、バージョン）

PackageManager   ──>  CheckUpdateAvailability ──>  UpdatesAvailable
StoreContext     ──>  GetStorePackageUpdates       プロパティ更新
                                                   （プログレスリング/
                                                    更新通知表示）

ユーザークリック ──>  ShellExecute ──────────────>  ブラウザで URL を開く
                      (フィードバック/NOTICE.html)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AboutDialog.h | `src/cascadia/TerminalApp/AboutDialog.h` | ソース | AboutDialog クラスの宣言 |
| AboutDialog.cpp | `src/cascadia/TerminalApp/AboutDialog.cpp` | ソース | AboutDialog の処理実装 |
| AboutDialog.xaml | `src/cascadia/TerminalApp/AboutDialog.xaml` | XAML | AboutDialog のUI定義 |
| AboutDialog.idl | `src/cascadia/TerminalApp/AboutDialog.idl` | IDL | WinRT インターフェース定義 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleOpenAbout ハンドラ |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _ShowAboutDialog の呼び出し |
