# 画面設計書 22-InsertMedia画面

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるメディア（画像）挿入機能のメイン画面（InsertMediaViewController）の設計仕様を記載したものである。

### 本画面の処理概要

InsertMedia画面は、Wikipedia記事を編集する際に、Wikimedia Commonsから画像を検索・選択し、記事に挿入するための統合的なインターフェースを提供する画面である。画面は3つの主要コンポーネント（選択画像プレビュー、検索バー、検索結果一覧）で構成され、ユーザーが直感的に画像を探して選択できるよう設計されている。

**業務上の目的・背景**：Wikipedia記事の品質向上には適切な画像の挿入が重要である。本画面は、ユーザーがCommonsの膨大な画像ライブラリから関連する画像を効率的に検索・選択し、適切な形式で記事に挿入できるようにすることで、記事の視覚的な品質向上を支援する。

**画面へのアクセス方法**：Article画面で編集モード中に、ツールバーの画像挿入ボタンをタップするとモーダル表示される。編集時のコンテキストメニューからもアクセス可能。

**主要な操作・処理内容**：
1. 検索バーにキーワードを入力してCommonsの画像を検索する
2. 検索結果のグリッドから画像をタップして選択する
3. 選択した画像のプレビューと詳細情報を確認する
4. 「Next」ボタンをタップして設定画面（InsertMediaSettings）に進む
5. 「Cancel」ボタンで画像挿入をキャンセルして閉じる

**画面遷移**：
- 遷移元：Article画面（編集モード）
- 遷移先：InsertMediaSettings画面（Next ボタンタップ）

**権限による表示制御**：特になし。編集可能な状態であれば誰でも利用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | メディア挿入 | 主機能 | 記事への画像挿入機能のメイン画面として検索・選択UIを提供 |

## 画面種別

検索 / 選択画面（モーダル表示）

## URL/ルーティング

iOSネイティブアプリのため、URLベースのルーティングは存在しない。ViewControllerの直接インスタンス化によりナビゲーションコントローラ内でモーダル表示される。

## 入出力項目

### 入力項目

| 項目名 | 種別 | データ型 | 必須 | 説明 |
|--------|------|----------|------|------|
| articleTitle | 入力 | String? | 任意 | 編集中の記事タイトル（初期検索ワードとして使用） |
| siteURL | 入力 | URL | 必須 | WikipediaサイトのURL |

### 出力項目

| 項目名 | 種別 | データ型 | 説明 |
|--------|------|----------|------|
| wikitext | 出力 | String | 生成された画像挿入用Wikitext |

## 表示項目

### ナビゲーションバー

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| タイトル | "Insert media" | CommonStrings.insertMediaTitle |
| 左ボタン | "Cancel" | 画面を閉じる |
| 右ボタン | "Next" | 初期状態disabled、画像選択後enabled |

### 選択画像プレビュー領域（上部30%）

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| 選択画像 | 選択された画像のプレビュー | InsertMediaSelectedImageViewController |
| 空状態 | 「画像が選択されていません」メッセージ | wmf_showEmptyView使用 |
| ローディング | アクティビティインジケータ | 画像読み込み中 |

### 検索領域

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| 検索バー | プレースホルダー付き検索フィールド | InsertMediaSearchViewController |
| プレースホルダー | 記事タイトルまたは"Search" | articleTitle ?? CommonStrings.searchTitle |

### 検索結果領域

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| 画像グリッド | 検索結果の画像サムネイル一覧 | InsertMediaSearchResultsCollectionViewController |
| 空状態 | 検索結果なし/インターネット接続なし | WMFEmptyViewType |

## イベント仕様

### 1-検索実行

ユーザーが検索バーに文字を入力すると、リアルタイムで検索が実行される。

**処理フロー**：
1. UISearchBarDelegateのtextDidChangeが呼び出される
2. InsertMediaSearchViewControllerのsearch(for:)メソッドを呼び出し
3. WMFSearchFetcherでCommonsのファイル検索APIを呼び出し
4. 検索結果をInsertMediaSearchResultとして変換
5. delegateを通じてInsertMediaViewControllerに結果を通知
6. searchResultsCollectionViewControllerに結果を設定

**API呼び出し**：
- エンドポイント：Wikimedia Commons API
- メソッド：fetchFiles
- 結果件数：WMFMaxSearchResultLimit

### 2-画像選択

検索結果グリッドから画像をタップすると、選択状態になる。

**処理フロー**：
1. InsertMediaSearchResultsCollectionViewControllerでセル選択
2. InsertMediaSelectedImageViewControllerDelegateを通じて通知
3. 選択画像のフル解像度URLを取得
4. 画像をダウンロードしてプレビュー表示
5. nextButtonをenabled状態に変更

### 3-Nextボタンタップ

画像選択後、Nextボタンをタップして設定画面に遷移する。

**処理フロー**：
1. goToMediaSettings(_:)メソッドが呼び出される
2. 選択された検索結果と画像を取得
3. InsertMediaSettingsViewControllerを初期化
4. navigationControllerでpush遷移

### 4-Cancelボタンタップ

画像挿入をキャンセルして画面を閉じる。

**処理フロー**：
1. delegateCloseButtonTap(_:)メソッドが呼び出される
2. delegate?.didTapCloseButton(insertMediaViewController:)を呼び出し
3. 呼び出し元で画面をdismiss

### 5-画像挿入完了

InsertMediaSettingsViewControllerから設定完了の通知を受け取る。

**処理フロー**：
1. InsertMediaSettingsViewControllerDelegateのdidTapProgressが呼び出される
2. 生成されたwikitextをdelegateに通知
3. delegate?.didPrepareWikitextToInsert(wikitext:insertMediaViewController:)

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

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

この画面ではローカルデータベースへの直接的な更新は行われない。すべての操作はAPI経由でWikimedia Commonsから情報を取得する。

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| 検索実行 | Wikimedia Commons API | SELECT | ファイル検索クエリの送信 |
| 画像情報取得 | Wikimedia Commons API | SELECT | 選択画像の詳細情報取得 |

## メッセージ仕様

| ID | 種別 | メッセージ内容 | 表示条件 |
|----|------|----------------|----------|
| MSG-01 | 空状態 | 検索結果なし | 検索結果が0件の場合 |
| MSG-02 | 空状態 | インターネット接続なし | ネットワークエラー時 |
| MSG-03 | 空状態 | 画像が選択されていません | 未選択状態 |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| ネットワークエラー | WMFEmptyViewType.noInternetConnectionを表示 |
| 検索キャンセル | emptyViewType.noneを設定し空状態を非表示 |
| 画像読み込み失敗 | アクティビティインジケータを停止し、エラー状態を表示 |
| 検索結果0件 | WMFEmptyViewType.noSearchResultsを表示 |

## 備考

- 検索は記事タイトルで自動的に初期検索が実行される（articleTitleが指定されている場合）
- スクロール時に選択画像プレビュー領域が連動してスライドするUIが実装されている
- EditingFlowViewControllerプロトコルに準拠しており、編集フローの一部として統合されている

---

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

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

### 推奨読解順序

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

検索結果のデータ構造と画像情報の形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | InsertMediaSearchResult | `Wikipedia/Code/InsertMediaSearchResult.swift` | 検索結果のデータモデル（fileTitle, displayTitle, thumbnailURL, imageInfo） |
| 1-2 | MWKImageInfo | `WMF Framework/MWKImageInfo.h` | 画像の詳細情報（filePageURL, imageDescription等） |

**読解のコツ**: InsertMediaSearchResultが保持するプロパティと、MWKImageInfoから取得できる追加情報の関係を理解することが重要。

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

InsertMediaViewControllerの初期化と子ViewControllerの構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | InsertMediaViewController.swift | `Wikipedia/Code/InsertMediaViewController.swift` | メインクラス。3つの子VCの初期化と配置 |

**主要処理フロー**:
1. **行9-11**: 3つの子ViewController（selectedImage, search, searchResults）をプロパティとして保持
2. **行16-25**: initで各コンポーネントを初期化し、delegateを設定
3. **行38-76**: viewDidLoadで子VCを追加し、Auto Layout制約を設定
4. **行121-129**: configureNavigationBarでタイトルとボタンを設定

#### Step 3: 検索処理を理解する

InsertMediaSearchViewControllerの検索ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InsertMediaSearchViewController.swift | `Wikipedia/Code/InsertMediaSearchViewController.swift` | 検索バーUI、検索API呼び出し、結果変換 |

**主要処理フロー**:
- **行46-116**: search(for:isFirstSearch:)で検索実行
- **行99-115**: fetchFilesで初回検索、結果数に応じてfullTextSearchを追加実行

#### Step 4: 検索結果表示を理解する

InsertMediaSearchResultsCollectionViewControllerの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | InsertMediaSearchResultsCollectionViewController.swift | `Wikipedia/Code/InsertMediaSearchResultsCollectionViewController.swift` | グリッド表示、セル選択、delegate通知 |

#### Step 5: 選択画像表示を理解する

InsertMediaSelectedImageViewControllerの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | InsertMediaSelectedImageViewController.swift | `Wikipedia/Code/InsertMediaSelectedImageViewController.swift` | 選択画像のプレビュー表示、空状態管理 |

**主要処理フロー**:
- **行58-82**: insertMediaSearchResultsCollectionViewControllerDidSelectで画像選択処理

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

```
InsertMediaViewController
    │
    ├─ InsertMediaSelectedImageViewController (子VC)
    │      └─ InsertMediaSelectedImageView
    │
    ├─ InsertMediaSearchViewController (子VC)
    │      ├─ UISearchBar
    │      ├─ WMFSearchFetcher (検索API)
    │      └─ MWKImageInfoFetcher (画像情報API)
    │
    ├─ InsertMediaSearchResultsCollectionViewController (子VC)
    │      └─ UICollectionView
    │             └─ InsertMediaSearchResultCollectionViewCell
    │
    └─ InsertMediaSettingsViewController (遷移先)
           └─ InsertMediaAdvancedSettingsViewController
```

### データフロー図

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

articleTitle ──────────▶ InsertMediaSearchViewController
                              │
                              ├─▶ WMFSearchFetcher.fetchFiles()
                              │        │
                              │        └─▶ Wikimedia Commons API
                              │                 │
siteURL ───────────────────▶ └─ MWKImageInfoFetcher
                                     │
                                     └─▶ [InsertMediaSearchResult]
                                              │
                                              ▼
                               SearchResultsCollectionVC
                                              │
                               ユーザー選択    │
                                              ▼
                               SelectedImageVC ─────────▶ プレビュー表示
                                              │
                               Nextタップ     │
                                              ▼
                               InsertMediaSettingsVC
                                              │
                                              ▼
                               Wikitext生成 ──────────▶ delegate通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| InsertMediaViewController.swift | `Wikipedia/Code/InsertMediaViewController.swift` | ソース | メイン画面のコントローラ |
| InsertMediaSearchViewController.swift | `Wikipedia/Code/InsertMediaSearchViewController.swift` | ソース | 検索バーと検索ロジック |
| InsertMediaSearchResultsCollectionViewController.swift | `Wikipedia/Code/InsertMediaSearchResultsCollectionViewController.swift` | ソース | 検索結果グリッド表示 |
| InsertMediaSelectedImageViewController.swift | `Wikipedia/Code/InsertMediaSelectedImageViewController.swift` | ソース | 選択画像プレビュー |
| InsertMediaSearchResult.swift | `Wikipedia/Code/InsertMediaSearchResult.swift` | ソース | 検索結果データモデル |
| InsertMediaSearchResultCollectionViewCell.swift | `Wikipedia/Code/InsertMediaSearchResultCollectionViewCell.swift` | ソース | 検索結果セル |
| InsertMediaSelectedImageView.swift | `Wikipedia/Code/InsertMediaSelectedImageView.swift` | ソース | 選択画像表示用ビュー |
| InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | ソース | 設定画面（遷移先） |
| WMFSearchFetcher.swift | `WMF Framework/WMFSearchFetcher.swift` | ソース | 検索API呼び出し |
| MWKImageInfoFetcher.swift | `WMF Framework/MWKImageInfoFetcher.swift` | ソース | 画像情報API呼び出し |
