# 画面設計書 84-ReadingListHint画面

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるReadingListHint画面の設計仕様を定義するものである。この画面は、記事保存後にリーディングリストへの追加を促すヒントバナーを表示するコンポーネントである。

### 本画面の処理概要

ReadingListHint画面は、ユーザーが記事を保存した直後に画面下部に表示されるヒントバナーである。このバナーをタップすることで、保存した記事を特定のリーディングリストに追加する画面へ遷移できる。追加完了後は確認メッセージとリスト詳細への遷移ボタンが表示される。

**業務上の目的・背景**：記事を保存した際、デフォルトでは「保存済み」リストに追加されるが、ユーザーは複数のリーディングリストを作成して記事を整理することができる。本ヒントバナーは、保存直後のタイミングでリスト整理のオプションを提示し、ユーザーが記事を適切なリストに分類するきっかけを提供する。これにより、リーディングリスト機能の認知度向上と活用促進を図る。

**画面へのアクセス方法**：記事詳細画面（Article画面）で記事を保存した際に、画面下部に自動的にスライドインして表示される。HintControllerによって管理され、一定時間後または他の操作により自動的に非表示になる。

**主要な操作・処理内容**：
1. ヒントバナーのタップでリーディングリスト選択画面（AddArticlesToReadingList）を表示
2. リスト選択後、確認表示に切り替わり記事サムネイルとリスト名を表示
3. 確認状態でのタップでリーディングリスト詳細画面（ReadingListDetail）を表示
4. 外部タップやスクロールによる自動非表示

**画面遷移**：
- 遷移元：Article画面（記事保存時に自動表示）
- 遷移先：AddArticlesToReadingList画面（リスト選択）、ReadingListDetail画面（確認後遷移）

**権限による表示制御**：特になし。ただし、リーディングリスト機能はログインユーザーの場合に同期が有効になる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | 記事保存 | 補助機能 | リスト保存のヒント表示 |
| 15 | リーディングリスト管理 | 遷移先機能 | リスト選択・詳細表示 |

## 画面種別

オーバーレイ（ヒントバナー）

## URL/ルーティング

iOSネイティブアプリのため、URLルーティングなし。HintControllerを通じてViewControllerコンテナに追加される。

## 入出力項目

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|------|---------|------|------|
| article | WMFArticle? | 入力 | 任意 | 保存対象の記事 |
| dataStore | MWKDataStore? | 入力 | 必須 | データストアへの参照 |
| theme | Theme | 入力 | 必須 | 現在のテーマ設定 |

## 表示項目

### デフォルト表示（viewType = .default）

| 項目名 | 説明 | 表示形式 |
|--------|------|----------|
| ヒントアイコン | リストへの追加を示すアイコン | 画像（add-to-list） |
| ヒントテキスト | 「Add "記事タイトル" to a reading list?」 | テキスト |

### 確認表示（viewType = .confirmation）

| 項目名 | 説明 | 表示形式 |
|--------|------|----------|
| 記事サムネイル | 追加した記事のサムネイル画像 | 画像 |
| 確認テキスト | 「Article added to "リスト名"」 | テキスト |
| 遷移アイコン | 右矢印（chevron-right） | アイコン |

## イベント仕様

### 1-デフォルトアクション（バナータップ）

デフォルト状態でヒントバナーをタップした際の処理。

1. `performDefaultAction(sender:)`が呼び出される
2. articleとdataStoreの存在を確認
3. `AddArticlesToReadingListViewController`を生成（articles: [article]）
4. `WMFComponentNavigationController`でラップしてモーダル表示
5. delegateを自身に設定してコールバックを受信

### 2-リスト追加完了

AddArticlesToReadingListで記事がリストに追加された際の処理。

1. `addArticlesToReadingList(_:didAddArticles:to:)`が呼び出される
2. readingListプロパティに追加先リストを保存
3. 記事のimageURLがあればconfirmationImageViewに画像を設定
4. confirmationLabelにリスト名を含む確認メッセージを設定
5. viewTypeを.confirmationに変更

### 3-確認アクション（確認状態でのバナータップ）

確認状態でヒントバナーをタップした際の処理。

1. `performConfirmationAction(sender:)`が呼び出される
2. readingListとdataStoreの存在を確認
3. `ReadingListDetailViewController`を生成（displayType: .modal）
4. `WMFComponentNavigationController`でラップしてモーダル表示
5. delegateの`hintViewControllerDidPeformConfirmationAction`を呼び出し

### 4-リスト追加キャンセル

AddArticlesToReadingListがキャンセルされた際の処理。

1. `addArticlesToReadingListWillClose(_:)`が呼び出される
2. delegateの`hintViewControllerDidFailToCompleteDefaultAction`を呼び出し
3. ヒントバナーが非表示になる

### 5-記事プロパティ変更

表示中にarticleプロパティが変更された際の処理。

1. `article` didSetオブザーバーが呼び出される
2. viewIfLoadedで画面がロード済みか確認
3. article != oldValueで実際に変更があったか確認
4. defaultLabel.textを新しいヒントタイトルで更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| リスト追加 | ReadingListEntry | INSERT | AddArticlesToReadingList画面経由で実行 |

### テーブル別更新項目詳細

本画面では直接的なデータベース操作は行わない。AddArticlesToReadingListViewControllerを通じてReadingListEntryの追加が行われる。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| reading-list-add-hint-title | ヒント | Add "%1$@" to a reading list? | デフォルト表示時（記事タイトルあり） |
| reading-list-add-generic-hint-title | ヒント | Add this article to a reading list? | デフォルト表示時（記事タイトルなし） |
| reading-lists-article-added-confirmation | 確認 | Article added to "%1$@" | リスト追加完了時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| article未設定 | 汎用ヒントテキストを表示 |
| dataStore未設定 | performDefaultAction/ConfirmationActionで処理をスキップ |
| 記事タイトル取得失敗 | displayTitleまたはURL.wmf_titleにフォールバック |
| 画像URL未取得 | confirmationImageViewを非表示 |

## 備考

- HintViewControllerを継承し、デフォルト/確認/警告の3つの表示タイプをサポート
- 確認表示では記事のサムネイル画像を顔認識付きで読み込み（detectFaces: true）
- themeableNavigationControllerをプロパティに保持し、ReadingListDetail画面のテーマ適用を管理
- nibNameは親クラスで"HintViewController"を返す

---

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

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

### 推奨読解順序

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

ヒント表示に関連するデータモデルを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | WMFArticle | `WMF/Sources/WMF/DataStore/WMFArticle*.swift` | displayTitle、imageURL(forWidth:)メソッド |
| 1-2 | ReadingList | `WMF/Sources/WMF/DataStore/ReadingList*.swift` | nameプロパティ |

**読解のコツ**: WMFArticleのdisplayTitleは表示用タイトルで、nilの場合はURLからタイトルを取得する。

#### Step 2: 親クラスを理解する

HintViewControllerの基本構造と表示タイプを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HintViewController.swift | `Wikipedia/Code/HintViewController.swift` | ViewType enum、IBOutlet、viewTypeプロパティ |

**主要処理フロー**:
1. **41-45行目**: `ViewType` enum - default、confirmation、warningの3タイプ
2. **47-65行目**: `viewType` didSet - タイプに応じたビュー表示切り替え
3. **118-124行目**: `performDefaultAction`、`performConfirmationAction` - オーバーライドポイント

#### Step 3: サブクラス実装を理解する

ReadingListHintViewControllerの具体的な実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ReadingListHintViewController.swift | `Wikipedia/Code/ReadingListHintViewController.swift` | configureSubviews、performDefaultAction、performConfirmationAction |

**主要処理フロー**:
- **8-18行目**: `article` didSet - タイトル更新
- **20-35行目**: `hintButtonTitle` - ローカライズ対応タイトル生成
- **37-41行目**: `configureSubviews()` - アイコンとテキスト設定
- **46-54行目**: `performDefaultAction` - AddArticlesToReadingList表示
- **56-67行目**: `performConfirmationAction` - ReadingListDetail表示

#### Step 4: デリゲート実装を理解する

AddArticlesToReadingListDelegateのコールバック処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ReadingListHintViewController.swift | `Wikipedia/Code/ReadingListHintViewController.swift` | AddArticlesToReadingListDelegate実装 |

**主要処理フロー**:
- **75-89行目**: `addArticlesToReadingList(_:didAddArticles:to:)` - 追加成功時の確認表示
- **91-93行目**: `addArticlesToReadingListWillClose` - キャンセル時のdelegateコールバック

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

```
ReadingListHintViewController
    │
    ├─ configureSubviews()
    │      ├─ defaultImageView.image設定
    │      ├─ confirmationAccessoryButton.image設定
    │      └─ defaultLabel.text設定（hintButtonTitle）
    │
    ├─ article (didSet)
    │      └─ defaultLabel.text更新
    │
    ├─ performDefaultAction()
    │      ├─ AddArticlesToReadingListViewController生成
    │      ├─ WMFComponentNavigationController生成
    │      └─ present(navigationController, animated:)
    │
    ├─ AddArticlesToReadingListDelegate
    │      ├─ didAddArticles → viewType = .confirmation
    │      └─ willClose → delegate?.didFailToCompleteDefaultAction
    │
    └─ performConfirmationAction()
           ├─ ReadingListDetailViewController生成
           ├─ WMFComponentNavigationController生成
           ├─ present(navigationController, animated:)
           └─ delegate?.hintViewControllerDidPeformConfirmationAction
```

### データフロー図

```
[Article画面]           [ヒント]                    [モーダル]

記事保存 ─────────▶ ReadingListHint ─────────▶ AddArticlesToReadingList
                    (default表示)                     │
                         │                            │ (追加完了)
                         ▼                            ▼
                    viewType切替 ◀───────────── didAddArticles
                    (confirmation)
                         │
                         ▼ (タップ)
                    ReadingListDetail
                    (モーダル表示)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ReadingListHintViewController.swift | `Wikipedia/Code/ReadingListHintViewController.swift` | ソース | メインViewController |
| HintViewController.swift | `Wikipedia/Code/HintViewController.swift` | ソース | ヒント表示基底クラス |
| HintViewController.xib | `Wikipedia/Code/HintViewController.xib` | XIB | ヒントUIレイアウト |
| AddArticlesToReadingListViewController.swift | `Wikipedia/Code/AddArticlesToReadingListViewController.swift` | ソース | リスト選択画面 |
| ReadingListDetailViewController.swift | `Wikipedia/Code/ReadingListDetailViewController.swift` | ソース | リスト詳細画面 |
| WMFComponentNavigationController | `WMFComponents` | ソース | テーマ対応ナビゲーション |
| WMFArticle | `WMF/Sources/WMF/DataStore/` | ソース | 記事データモデル |
| ReadingList | `WMF/Sources/WMF/DataStore/` | ソース | リストデータモデル |
