# 画面設計書 33-DiffList画面

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるDiffList画面の設計仕様を定義するものです。

### 本画面の処理概要

DiffList画面は、Wikipedia記事の2つのリビジョン間の差分を行単位で表示する子コンポーネントです。DiffContainerViewControllerの子ViewControllerとして動作し、追加・削除・変更された行をハイライト表示します。

**業務上の目的・背景**：
編集者が記事の変更内容を詳細に確認するために、追加された文字列を緑色、削除された文字列を赤色でハイライトし、変更箇所を視覚的に把握しやすくすることが目的です。コンテキスト行（変更されていない周辺行）も合わせて表示することで、変更の前後関係を理解しやすくしています。

**画面へのアクセス方法**：
DiffContainer画面の一部として自動的に表示されます。独立した画面遷移は持ちません。

**主要な操作・処理内容**：
1. 差分データのUICollectionViewによるリスト表示
2. 追加行（緑）・削除行（赤）・変更行（青）のハイライト表示
3. コンテキスト行（グレー）の表示
4. 展開/折りたたみによるコンテキスト表示の切り替え
5. セル内の文字レベルでの差分ハイライト

**画面遷移**：
- 遷移元：DiffContainer画面（親コンポーネント）
- 遷移先：なし（子コンポーネントとして埋め込み表示）

**権限による表示制御**：
特に権限による表示制御はありません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | 差分比較 | 補助機能 | 差分リスト表示の本体 |

## 画面種別

一覧（差分行リスト）

## URL/ルーティング

本画面は独立した画面ではなく、DiffContainerViewControllerの子コンポーネントとして組み込まれるため、独自のURLやルーティングは持ちません。

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| theme | 入力 | Theme | テーマ設定 |
| listViewModel | 入力 | DiffListViewModel | 差分リストデータ |
| delegate | 入力 | DiffListDelegate | デリゲート |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| collectionView | UICollectionView | 差分行のリスト |
| DiffListChangeCell | UICollectionViewCell | 変更行セル（追加/削除/移動） |
| DiffListContextCell | UICollectionViewCell | コンテキスト行セル |
| DiffListUneditedCell | UICollectionViewCell | 未編集行セル |
| DiffListGroupedScrollFooterView | UICollectionReusableView | 編集間のフッター |

## イベント仕様

### 1-セクション展開/折りたたみ

コンテキストセルをタップすると、そのセクションの詳細行を展開または折りたたみます。展開状態はコレクションビューのスナップショットとして管理されます。

### 2-スクロール

UICollectionViewCompositionalLayoutを使用した垂直スクロールで、全ての差分行を閲覧できます。各セクションは独立したグループとしてレイアウトされます。

### 3-アクセシビリティ読み上げ

各セルはアクセシビリティラベルを持ち、VoiceOverで変更内容を読み上げます。

## データベース更新仕様

本画面はデータベースを更新しません（読み取り専用）。

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | - | - | 本画面はAPI経由で取得したデータの表示のみ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| diff-paragraph-moved-distance-line | 情報 | "Paragraph moved %1$d line" | 段落移動時（単数） |
| diff-paragraph-moved-distance-lines | 情報 | "Paragraph moved %1$d lines" | 段落移動時（複数） |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 差分データが空の場合 | コレクションビューが空の状態で表示 |
| セル設定失敗 | fatalErrorでクラッシュ（デバッグ用） |

## 備考

- UICollectionViewDiffableDataSourceを使用したモダンなデータソース管理
- UICollectionViewCompositionalLayoutによる複雑なレイアウト
- 各セル種別ごとに異なるレイアウト定義
- テーマ対応（ライト/ダーク）
- Dynamic Type対応

---

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

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

### 推奨読解順序

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

差分表示に使用される主要なデータ構造を把握します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DiffListViewModel | `Wikipedia/Code/` | 差分リストのViewModel |
| 1-2 | DiffListChangeItemViewModel | `Wikipedia/Code/` | 変更行のViewModel |
| 1-3 | DiffListContextItemViewModel | `Wikipedia/Code/` | コンテキスト行のViewModel |

**読解のコツ**: DiffListViewModelは差分データを保持し、各セルのViewModelを提供します。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DiffListViewController.swift | `Wikipedia/Code/DiffListViewController.swift` | init(theme:delegate:type:)で初期化 |

**主要処理フロー**:
1. **36-45行目**: 初期化時にテーマ、デリゲート、タイプを受け取り
2. **47-59行目**: loadViewでcollectionViewを設定
3. **60-78行目**: viewDidLoadでセル登録、デリゲート設定
4. **101-139行目**: updateListViewModels()でDiffableDataSourceを更新

#### Step 3: コレクションビューレイアウトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DiffListViewController.swift | `Wikipedia/Code/DiffListViewController.swift` | createLayout()でCompositionalLayout定義 |

**主要処理フロー**:
- **188-260行目**: NSCollectionLayoutSection生成
- **211行目**: DiffListChangeCell用のレイアウト
- **224行目**: DiffListContextCell用のレイアウト
- **237行目**: DiffListUneditedCell用のレイアウト

#### Step 4: セル設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DiffListViewController.swift | `Wikipedia/Code/DiffListViewController.swift` | configureCell()でセル設定 |

**主要処理フロー**:
- **145-186行目**: セル種別ごとの設定ロジック
- **150-159行目**: DiffListChangeCell設定
- **160-169行目**: DiffListContextCell設定
- **170-179行目**: DiffListUneditedCell設定

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

```
DiffContainerViewController
    │
    └─ DiffListViewController (子VCとして追加)
           │
           ├─ loadView() → UICollectionView生成
           │
           ├─ viewDidLoad()
           │      ├─ registerCells() → セル登録
           │      └─ setupCollectionView() → DataSource/Layout設定
           │
           ├─ updateListViewModels()
           │      ├─ NSDiffableDataSourceSnapshot構築
           │      │      ├─ appendSections()
           │      │      └─ appendItems()
           │      └─ dataSource.apply(snapshot)
           │
           └─ createLayout()
                  └─ UICollectionViewCompositionalLayout
                         ├─ DiffListChangeCell レイアウト
                         ├─ DiffListContextCell レイアウト
                         └─ DiffListUneditedCell レイアウト
```

### データフロー図

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

DiffListViewModel     ──────▶ updateListViewModels()      ──────▶ NSDiffableDataSourceSnapshot
                               │
                               ▼
Snapshot              ──────▶ dataSource.apply()          ──────▶ UICollectionView更新
                               │
                               ▼
Cell tap              ──────▶ didSelectItemAt()           ──────▶ 展開/折りたたみ
                               │
                               ▼
Theme変更             ──────▶ apply(theme:)               ──────▶ セル色更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DiffListViewController.swift | `Wikipedia/Code/DiffListViewController.swift` | ソース | メインViewController |
| DiffListViewModel.swift | `Wikipedia/Code/DiffListViewModel.swift` | ソース | リスト全体のViewModel |
| DiffListChangeCell.swift | `Wikipedia/Code/DiffListChangeCell.swift` | ソース | 変更行セル |
| DiffListContextCell.swift | `Wikipedia/Code/DiffListContextCell.swift` | ソース | コンテキスト行セル |
| DiffListUneditedCell.swift | `Wikipedia/Code/DiffListUneditedCell.swift` | ソース | 未編集行セル |
| DiffListChangeItemViewModel.swift | `Wikipedia/Code/DiffListChangeItemViewModel.swift` | ソース | 変更行ViewModel |
| DiffContainerViewController.swift | `Wikipedia/Code/DiffContainerViewController.swift` | ソース | 親ViewController |
