# 機能設計書 28-メディア挿入

## 概要

本ドキュメントは、Wikipedia iOSアプリケーションにおけるメディア挿入機能の設計を記載する。この機能により、ユーザーは編集中の記事にWikimedia Commonsから画像を検索・挿入できる。

### 本機能の処理概要

メディア挿入機能は、Wikimedia Commonsから画像を検索し、選択した画像のWikitext記法を生成して記事に挿入する。

**業務上の目的・背景**：記事への画像追加は記事の品質と視覚的な魅力を向上させる。Wikimedia Commonsの膨大な画像リポジトリから適切な画像を簡単に見つけて挿入できることで、編集者の作業効率が向上する。

**機能の利用シーン**：記事編集中に「メディアを挿入」機能を選択した際に使用する。記事タイトルで自動検索を行い、関連画像を表示する。

**主要な処理内容**：
1. Wikimedia Commons画像検索（タイトル/全文検索）
2. 画像サムネイル・詳細情報の取得と表示
3. 画像選択と設定（キャプション、代替テキスト）
4. 詳細設定（画像タイプ、位置、サイズ）
5. Wikitext記法の生成
6. 言語別ローカライズ対応（マジックワード）

**関連システム・外部連携**：Wikimedia Commons API、MWKImageInfoFetcher、WMFSearchFetcher

**権限による制御**：編集画面からのみアクセス可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 記事編集画面 | 遷移元 | メディア挿入を開始 |
| - | メディア検索画面 | メイン画面 | 画像検索と選択 |
| - | メディア設定画面 | サブ画面 | キャプション・代替テキスト設定 |
| - | 詳細設定画面 | サブ画面 | 画像タイプ・位置・サイズ設定 |

## 機能種別

検索、UI制御、テキスト生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| articleTitle | String? | No | 記事タイトル（初期検索用） | - |
| siteURL | URL | Yes | サイトURL | - |
| image | UIImage | Yes | 選択された画像 | - |
| searchResult | InsertMediaSearchResult | Yes | 検索結果データ | - |

### 入力データソース

- Wikimedia Commons API（画像検索）
- MWKImageInfoFetcher（画像詳細情報）
- ユーザー入力（検索クエリ、キャプション、代替テキスト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| imageWikitext | String | 生成されたWikitext記法 |
| caption | String? | キャプション |
| altText | String? | 代替テキスト |
| localizedFileTitle | String | ローカライズされたファイルタイトル |

### 出力先

- InsertMediaViewControllerDelegate.didPrepareWikitextToInsert
- 親EditorViewControllerへのWikitext挿入

## 処理フロー

### 処理シーケンス

```
1. 初期化
   ├─ InsertMediaViewController生成
   ├─ 記事タイトルで初期検索実行
   └─ 子VC配置（検索結果、選択画像、検索バー）

2. 画像検索
   ├─ searchFetcher.fetchFiles（タイトル検索）
   ├─ 結果少ない場合は全文検索追加
   └─ imageInfoFetcher.fetchGalleryInfo（画像詳細）

3. 画像選択
   ├─ サムネイルタップ
   ├─ 選択画像表示更新
   └─ Nextボタン有効化

4. 設定入力
   ├─ キャプション入力
   ├─ 代替テキスト入力
   └─ 詳細設定（タイプ、位置、サイズ）

5. Wikitext生成
   ├─ imageInsertInfo生成
   ├─ ローカライズ処理
   └─ デリゲート通知
```

### フローチャート

```mermaid
flowchart TD
    A[メディア挿入開始] --> B[記事タイトルで検索]
    B --> C[検索結果表示]
    C --> D{画像選択?}
    D -->|Yes| E[選択画像プレビュー]
    D -->|No| F[検索バーで再検索]
    F --> C
    E --> G[Next]
    G --> H[設定画面]
    H --> I[キャプション・代替テキスト入力]
    I --> J{詳細設定?}
    J -->|Yes| K[詳細設定画面]
    K --> L[Insert]
    J -->|No| L
    L --> M[Wikitext生成]
    M --> N[delegate.didPrepareWikitextToInsert]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 初期検索 | 記事タイトルで自動検索実行 | 記事タイトルあり時 |
| BR-002 | 全文検索フォールバック | タイトル検索結果が12件未満の場合は全文検索追加 | 常時 |
| BR-003 | 画像タイプデフォルト | 画像タイプはthumbnailがデフォルト | 常時 |
| BR-004 | 画像位置デフォルト | 画像位置はrightがデフォルト | 常時 |
| BR-005 | 画像サイズデフォルト | 画像サイズは220x124pxがデフォルト | 常時 |
| BR-006 | マジックワードローカライズ | ファイル名・画像タイプ等を言語別に変換 | 常時 |

### 計算ロジック

| 計算項目 | 計算式・ロジック |
|---------|----------------|
| Wikitext生成 | `[[ファイル名|タイプ|サイズ|位置|alt=代替テキスト|キャプション]]` |
| サイズ文字列 | `\(width)x\(height)px` |

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

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

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 処理内容 |
|-----------|---------|---------|
| ネットワークエラー | 通信不可 | noInternetConnection表示 |
| 検索キャンセル | URLエラーキャンセル | 表示なし |
| 検索結果なし | 該当画像なし | noSearchResults表示 |
| オフライン | 接続断 | オフラインアラート表示 |

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

該当なし

## パフォーマンス要件

- 検索結果表示: サムネイル非同期読み込み
- 画像情報取得: 検索結果ごとに並列取得

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

特になし

## 備考

- InsertMediaSearchResultは検索結果と画像情報を保持
- 詳細設定はInsertMediaAdvancedSettingsViewControllerで管理
- 画像レコメンデーション機能からも利用可能（fromImageRecommendations）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | InsertMediaSearchResult.swift | `Wikipedia/Code/InsertMediaSearchResult.swift` | 検索結果データ構造 |
| 1-2 | InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | Settings構造体（L37-145） |
| 1-3 | InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | ImagePosition/ImageType/ImageSize（L48-130） |

**読解のコツ**: Settings.Advanced内の各enum（ImagePosition、ImageType、ImageSize）のrawValueがWikitext生成に使用される。

#### Step 2: メイン画面構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | InsertMediaViewController.swift | `Wikipedia/Code/InsertMediaViewController.swift` | init（L16-25） |
| 2-2 | InsertMediaViewController.swift | `Wikipedia/Code/InsertMediaViewController.swift` | viewDidLoad（L38-76） |

**主要処理フロー**:
- **L9-11**: 3つの子VC（selectedImageVC, searchVC, searchResultsVC）
- **L17-24**: 各子VCのデリゲート設定
- **L41-73**: 子VCのレイアウト配置

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InsertMediaSearchViewController.swift | `Wikipedia/Code/InsertMediaSearchViewController.swift` | search(for:)（L46-116） |
| 3-2 | InsertMediaSearchViewController.swift | `Wikipedia/Code/InsertMediaSearchViewController.swift` | 検索結果マッピング（L59-76） |

**主要処理フロー**:
- **L47-48**: 既存の検索をキャンセル
- **L99-115**: タイトル検索→結果少なければ全文検索
- **L83-97**: 各検索結果の画像詳細情報を並列取得

#### Step 4: 設定画面を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | viewModels（L222-226） |
| 4-2 | InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | tappedProgress（L300-311） |

**主要処理フロー**:
- **L222-226**: キャプション・代替テキストのビューモデル
- **L300-311**: Insertボタンタップ時のWikitext生成

#### Step 5: Wikitext生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | imageInsertInfo（L389-433） |
| 5-2 | InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | ローカライズ関数群（L435-509） |

**主要処理フロー**:
- **L389-433**: 設定値からWikitext文字列を構築
- **L435-448**: localizedFileTitle（File: → 言語別名前空間）
- **L450-472**: localizedImageTypeName（マジックワード変換）
- **L474-496**: localizedImagePositionName（マジックワード変換）

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

```
EditorViewController
    │
    └─ presentInsertMediaViewController()
           │
           └─ InsertMediaViewController
                  │
                  ├─ InsertMediaSearchViewController
                  │      ├─ search(for:)
                  │      │      ├─ searchFetcher.fetchFiles()
                  │      │      └─ imageInfoFetcher.fetchGalleryInfo()
                  │      │
                  │      └─ delegate.didFind(searchResults:)
                  │
                  ├─ InsertMediaSearchResultsCollectionViewController
                  │      └─ collectionView(_:didSelectItemAt:)
                  │             └─ delegate.didSelectSearchResult()
                  │
                  ├─ InsertMediaSelectedImageViewController
                  │      └─ setSelectedImage(from:)
                  │
                  └─ goToMediaSettings()
                         │
                         └─ InsertMediaSettingsViewController
                                │
                                ├─ InsertMediaAdvancedSettingsViewController
                                │      └─ advancedSettings
                                │
                                └─ tappedProgress()
                                       ├─ imageInsertInfo()
                                       │      ├─ localizedFileTitle()
                                       │      ├─ localizedImageTypeName()
                                       │      └─ localizedImagePositionName()
                                       │
                                       └─ delegate.didPrepareWikitextToInsert()
```

### データフロー図

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

記事タイトル           ───▶ InsertMediaSearchViewController
                                │
                                ▼
                         searchFetcher.fetchFiles()
                                │
                                ▼
                         [InsertMediaSearchResult] ───▶ CollectionView表示
                                │
                                ▼
画像選択               ───▶ InsertMediaSelectedImageViewController
                                │
                                ▼
                         画像プレビュー表示
                                │
キャプション・代替テキスト ───▶ InsertMediaSettingsViewController
                                │
                                ▼
詳細設定               ───▶ InsertMediaAdvancedSettingsViewController
                                │
                                ▼
                         Settings構造体
                                │
                                ▼
                         imageInsertInfo() ───▶ Wikitext文字列
                                │
                                ▼
                         delegate.didPrepareWikitextToInsert() ───▶ EditorViewController
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| InsertMediaViewController.swift | `Wikipedia/Code/InsertMediaViewController.swift` | ソース | メディア挿入メインVC |
| InsertMediaSearchViewController.swift | `Wikipedia/Code/InsertMediaSearchViewController.swift` | ソース | 画像検索VC |
| InsertMediaSearchResultsCollectionViewController.swift | `Wikipedia/Code/InsertMediaSearchResultsCollectionViewController.swift` | ソース | 検索結果表示VC |
| InsertMediaSelectedImageViewController.swift | `Wikipedia/Code/InsertMediaSelectedImageViewController.swift` | ソース | 選択画像プレビューVC |
| InsertMediaSettingsViewController.swift | `Wikipedia/Code/InsertMediaSettingsViewController.swift` | ソース | 設定画面VC |
| InsertMediaAdvancedSettingsViewController.swift | `Wikipedia/Code/InsertMediaAdvancedSettingsViewController.swift` | ソース | 詳細設定VC |
| InsertMediaSearchResult.swift | `Wikipedia/Code/InsertMediaSearchResult.swift` | ソース | 検索結果データ構造 |
| WMFSearchFetcher.swift | `WMF/Sources/WMF/Fetchers/WMFSearchFetcher.swift` | ソース | 検索API通信 |
| MWKImageInfoFetcher.swift | `Wikipedia/Code/MWKImageInfoFetcher.swift` | ソース | 画像情報取得 |
| MagicWordUtils.swift | `Wikipedia/Code/MagicWordUtils.swift` | ソース | マジックワード変換 |
