# 画面設計書 34-TalkPage画面

## 概要

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

### 本画面の処理概要

TalkPage画面は、Wikipedia記事やユーザーに関連するトークページ（議論ページ）を表示・操作する画面です。トピック一覧の表示、トピックの展開/折りたたみ、トピックへの購読、新規トピックの投稿、コメントの返信など、トークページに関する包括的な機能を提供します。

**業務上の目的・背景**：
Wikipediaの編集者間でのコミュニケーションを促進するための画面です。記事の内容に関する議論、ユーザーへのメッセージ、編集方針の相談など、Wikiコミュニティの協働作業を支える重要な機能です。

**画面へのアクセス方法**：
1. Article画面のメニューから「Talk page」を選択
2. ユーザーページから「User talk」をタップ
3. 通知センターからトークページ関連通知をタップ
4. ディープリンク（トピック名を指定したURL）

**主要な操作・処理内容**：
1. トピック一覧の表示（折りたたみ可能）
2. トピックの購読/購読解除（通知設定）
3. 新規トピックの投稿
4. コメントへの返信
5. ページ内検索（Find in page）
6. ソース編集
7. 言語切り替え
8. アーカイブ/編集履歴/関連リンクへの遷移

**画面遷移**：
- 遷移元：Article画面、UserPage画面、NotificationsCenter画面
- 遷移先：TalkPageCoffeeRoll画面、PageHistory画面、Editor画面、TalkPageArchives画面、Article画面

**権限による表示制御**：
- ログインユーザー：トピック投稿、コメント返信、購読機能使用可能
- 未ログインユーザー：閲覧のみ（投稿時にログインを促す）
- 一時アカウント：IP警告表示付きで投稿可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | トークページ表示・投稿 | 主機能 | トークページの表示と投稿 |
| 24 | 編集履歴 | 補助機能 | 編集履歴への遷移 |

## 画面種別

一覧（トピック一覧）

## URL/ルーティング

ディープリンク対応：
- `topicTitle`: トピック名（ディープリンクスクロール用）
- `replyText`: 返信テキスト（スクロール先特定用）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| theme | 入力 | Theme | テーマ設定 |
| viewModel | 入力 | TalkPageViewModel | トークページデータ |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| TalkPageHeaderView | UIView | ヘッダー（記事タイトル、Coffee Roll） |
| collectionView | UICollectionView | トピック一覧 |
| toolbar | UIToolbar | 下部ツールバー |
| emptyView | UIView | 空状態表示 |
| errorView | UIView | エラー状態表示 |

## イベント仕様

### 1-トピック展開/折りたたみ

トピックセルをタップすると、そのトピックのスレッドを展開または折りたたみます。展開時にはすべてのコメントが表示されます。

### 2-トピック購読

トピックの購読ボタンをタップすると、そのトピックに新しいコメントが投稿された際に通知を受け取るように設定します。

### 3-新規トピック投稿

ツールバーの「+」ボタンをタップすると、新規トピック投稿画面（TalkPageTopicComposeViewController）がモーダル表示されます。

### 4-コメント返信

コメントの返信ボタンをタップすると、返信入力UIが表示されます。投稿ボタンでコメントが送信されます。

### 5-ページ内検索

ツールバーの検索ボタンをタップすると、Find in Page機能が起動します。すべてのスレッドが自動展開されます。

### 6-共有

ツールバーの共有ボタンをタップすると、トークページのURLを共有できます。

### 7-編集履歴表示

ツールバーまたはオーバーフローメニューから編集履歴画面に遷移します。

### 8-ソース編集

オーバーフローメニューから「Edit source」を選択すると、トークページ全体のソースを編集するEditorViewControllerに遷移します。

### 9-言語切り替え

オーバーフローメニューから言語を切り替えると、該当言語版のトークページを読み込みます。

### 10-Coffee Roll詳細表示

ヘッダーのCoffee Rollセクションの「Read more」をタップすると、TalkPageCoffeeRollViewControllerに遷移します。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 新規トピック投稿 | - | API Call | MediaWiki API経由で投稿 |
| コメント返信 | - | API Call | MediaWiki API経由で投稿 |
| トピック購読 | UserDefaults | UPDATE | 購読状態をローカル保存 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| talk-pages-view-title | タイトル | "Talk" | 常時 |
| talk-page-subscribed-alert-title | 成功 | "You have subscribed!" | 購読成功時 |
| talk-page-unsubscribed-alert-title | 成功 | "You have unsubscribed." | 購読解除時 |
| talk-pages-topic-added-alert-title | 成功 | "Your topic was added" | トピック投稿成功時 |
| talk-pages-comment-added-alert-title | 成功 | "Your comment was added" | コメント投稿成功時 |
| talk-page-publish-reply-error-title | エラー | "Unable to publish your comment." | コメント投稿失敗時 |
| talk-page-publish-topic-error-title | エラー | "Unable to publish new topic." | トピック投稿失敗時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ネットワークエラー（トークページ取得失敗） | errorView表示、「Try again」ボタン |
| ネットワークエラー（投稿失敗） | エラーアラート表示 |
| 購読/購読解除失敗 | エラーアラート表示、状態ロールバック |
| 未ログイン時の投稿試行 | オンボーディング表示後、ログイン促進 |
| 一時アカウント/IP時の投稿 | 警告トースト表示 |

## 備考

- TalkPageFormattingToolbarViewによるテキスト装飾サポート
- Find in Page機能のためのキーボードバー
- ReachabilityNotifierによるオフライン検知
- TalkPagesFunnelによるアナリティクスロギング
- EditAttemptFunnelによる編集フロー分析
- VoiceOver対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TalkPageViewModel | `Wikipedia/Code/` | トピック、購読状態、投稿ロジック |
| 1-2 | TalkPageCellViewModel | `Wikipedia/Code/` | トピックセルのViewModel |
| 1-3 | TalkPageCellCommentViewModel | `Wikipedia/Code/` | コメントのViewModel |

**読解のコツ**: TalkPageViewModelがAPIとの通信、データ管理を担当し、各セルのViewModelに分配します。

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

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

**主要処理フロー**:
1. **161-166行目**: init時にviewModelとthemeを受け取り
2. **205-225行目**: viewDidLoadでCollectionView設定、fetchTalkPage()呼び出し
3. **177-203行目**: fetchTalkPage()でAPI呼び出し、成功/失敗ハンドリング
4. **963-1007行目**: UICollectionViewDataSourceの実装

#### Step 3: トピック操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TalkPageViewController.swift | `Wikipedia/Code/TalkPageViewController.swift` | TalkPageCellDelegateの実装 |

**主要処理フロー**:
- **1013-1032行目**: userDidTapDisclosureButton()で展開/折りたたみ
- **1034-1059行目**: userDidTapSubscribeButton()で購読処理

#### Step 4: 投稿処理を理解する

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

**主要処理フロー**:
- **430-453行目**: showAddTopic()で新規トピック画面表示
- **1073-1104行目**: tappedReply()で返信UI表示
- **1124-1206行目**: tappedPublish()で返信投稿
- **1219-1295行目**: TalkPageTopicComposeViewControllerDelegateで新規トピック投稿

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

```
TalkPageViewController
    │
    ├─ init(theme:viewModel:)
    │
    ├─ viewDidLoad()
    │      ├─ setupOverflowMenu()
    │      ├─ fetchTalkPage() → viewModel.fetchTalkPage()
    │      │      └─ configure(viewModel:) / showErrorView()
    │      └─ setupToolbar()
    │
    ├─ TalkPageCellDelegate
    │      ├─ userDidTapDisclosureButton() → 展開/折りたたみ
    │      └─ userDidTapSubscribeButton() → viewModel.subscribe()
    │
    ├─ TalkPageCellReplyDelegate
    │      └─ tappedReply() → replyComposeController.setupAndDisplay()
    │
    ├─ TalkPageReplyComposeDelegate
    │      ├─ closeReplyView()
    │      └─ tappedPublish() → viewModel.postReply()
    │
    ├─ TalkPageTopicComposeViewControllerDelegate
    │      └─ tappedPublish() → viewModel.postTopic()
    │
    └─ Overflow Menu Actions
           ├─ pushToRevisionHistory()
           ├─ pushToEditor()
           ├─ pushToArchives()
           └─ pushToPageInfo(), pushToWhatLinksHere(), etc.
```

### データフロー図

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

TalkPageViewModel      ──────▶ fetchTalkPage()            ──────▶ collectionView.reloadData()
                               │
                               ▼
Topic tap              ──────▶ userDidTapDisclosureButton ──────▶ cell.configure() (展開状態変更)
                               │
                               ▼
Subscribe tap          ──────▶ viewModel.subscribe()      ──────▶ 購読アラート表示
                               │
                               ▼
Reply tap              ──────▶ replyComposeController     ──────▶ 返信UI表示
                               .setupAndDisplay()
                               │
                               ▼
Publish tap            ──────▶ viewModel.postReply()      ──────▶ 成功アラート/エラー表示
                               │
                               ▼
New Topic              ──────▶ TalkPageTopicComposeVC     ──────▶ viewModel.postTopic()
                               │
                               ▼
                               fetchTalkPage() (再読み込み)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TalkPageViewController.swift | `Wikipedia/Code/TalkPageViewController.swift` | ソース | メインViewController |
| TalkPageView.swift | `Wikipedia/Code/TalkPageView.swift` | ソース | メインView |
| TalkPageViewModel.swift | `Wikipedia/Code/TalkPageViewModel.swift` | ソース | ビジネスロジック |
| TalkPageCell.swift | `Wikipedia/Code/TalkPageCell.swift` | ソース | トピックセル |
| TalkPageCellViewModel.swift | `Wikipedia/Code/TalkPageCellViewModel.swift` | ソース | セルViewModel |
| TalkPageHeaderView.swift | `Wikipedia/Code/TalkPageHeaderView.swift` | ソース | ヘッダービュー |
| TalkPageReplyComposeController.swift | `Wikipedia/Code/TalkPageReplyComposeController.swift` | ソース | 返信入力制御 |
| TalkPageTopicComposeViewController.swift | `Wikipedia/Code/TalkPageTopicComposeViewController.swift` | ソース | 新規トピック投稿 |
| TalkPageFormattingToolbarView.swift | `Wikipedia/Code/TalkPageFormattingToolbarView.swift` | ソース | 書式ツールバー |
| TalkPageFindInPageState.swift | `Wikipedia/Code/TalkPageFindInPageState.swift` | ソース | ページ内検索状態 |
| TalkPageCoffeeRollViewController.swift | `Wikipedia/Code/TalkPageCoffeeRollViewController.swift` | ソース | Coffee Roll画面 |
| TalkPageArchivesViewController.swift | `Wikipedia/Code/TalkPageArchivesViewController.swift` | ソース | アーカイブ画面 |
