# 画面設計書 44-FeedCardSettings画面

## 概要

本ドキュメントはWikipedia iOSアプリにおけるフィードカード個別設定画面（FeedCardSettingsViewController）の設計内容を記載したものです。

### 本画面の処理概要

FeedCardSettings画面は、ExploreFeedSettings画面から遷移し、特定のフィードカード（In the news、On this day等）の詳細設定を行うための画面です。複数言語を設定しているユーザーが、特定のカードを言語別にオン/オフ切り替えることができます。

**業務上の目的・背景**：複数の言語でWikipediaを利用するユーザーにとって、特定のカードを特定の言語でのみ表示/非表示にする細かな制御が求められます。例えば、「In the news」は英語のみで表示し、日本語では非表示にするといった設定が可能です。

**画面へのアクセス方法**：ExploreFeedSettings画面で特定のフィードカード行をタップすることで遷移します（複数言語モード時のみ）。

**主要な操作・処理内容**：
1. カード全体の表示/非表示切り替え（メインスイッチ）
2. 言語別のカード表示/非表示切り替え（言語がグローバルでない場合）
3. 設定変更はリアルタイムでフィードに反映

**画面遷移**：
- 遷移元：ExploreFeedSettings画面
- 遷移先：なし（設定変更のみ）

**権限による表示制御**：特になし。ExploreFeedSettings画面から遷移可能なすべてのカードに対して同じUI構成を提供します。ただし、グローバルカード（言語非依存）の場合は言語セクションが表示されません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | フィードカスタマイズ | 主機能 | フィードカード個別の設定 |

## 画面種別

設定（スイッチ切替型設定画面）

## URL/ルーティング

iOSネイティブアプリのため、URLは使用しない。画面遷移はUINavigationControllerのpush遷移で管理。

## 入出力項目

| 項目名 | 項目ID | データ型 | 入力/出力 | 必須 | 説明 |
|--------|--------|----------|-----------|------|------|
| カード表示設定 | contentGroupKind.isInFeed | Bool | 入出力 | - | カード全体の表示/非表示 |
| 言語別表示設定 | languageLink.isInFeed(for:) | Bool | 入出力 | - | 言語別のカード表示設定 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ナビゲーションタイトル | String | カード名（例："In the news"） |
| メインスイッチセクション | Section | カード全体のオン/オフ |
| Languages セクション | Section | 言語別設定（グローバルカード以外） |

## イベント仕様

### 1-メインスイッチ切替

カード全体の表示/非表示を切り替える際の処理。

1. `settingsTableViewCell(_:didToggleDisclosureSwitch:)`が呼び出される
2. controlTag=-1を検出
3. `feedContentController.toggleContentGroup(of:isOn:updateFeed:)`を実行
4. カード全体の表示設定を更新

### 2-言語別スイッチ切替

特定言語でのカード表示/非表示を切り替える際の処理。

1. `settingsTableViewCell(_:didToggleDisclosureSwitch:)`が呼び出される
2. sender.tagから対応するlanguageを特定
3. `feedContentController.toggleContentGroup(of:isOn:forSiteURL:updateFeed:)`を実行
4. 言語別のカード表示設定を更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| メインスイッチ切替 | CoreData | UPDATE | カード全体の表示設定を更新 |
| 言語別スイッチ切替 | CoreData | UPDATE | 言語別のカード表示設定を更新 |

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

#### CoreData (WMFExploreFeedContentController経由)

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| UPDATE | ContentGroup visibility | Bool | カードの表示設定（全言語） |
| UPDATE | ContentGroup visibility per site | Bool | カードの表示設定（言語別） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| explore-feed-preferences-show-news-footer-text | フッター | "Turning off the In the news card will turn the card off in all available languages." | In the newsカード |
| explore-feed-preferences-show-featured-article-footer-text | フッター | "Turning off the Featured article card will turn the card off in all available languages." | Featured articleカード |
| explore-feed-preferences-show-top-read-footer-text | フッター | "Turning off the Top read card will turn the card off in all available languages." | Top readカード |
| explore-feed-preferences-show-on-this-day-footer-text | フッター | "Turning off the On this day card will turn the card off in all available languages." | On this dayカード |
| explore-feed-preferences-global-card-footer-text | フッター | "This card is not language specific, turning off this card will remove it from your Explore feed." | グローバルカード |
| explore-feed-preferences-show-places-footer-text | フッター | "Turning off the Places card will turn the card off in all available languages." | Placesカード |
| explore-feed-preferences-show-randomizer-footer-text | フッター | "Turning off the Randomizer card will turn the card off in all available languages." | Randomizerカード |
| explore-feed-preferences-additional-languages-footer-text | フッター | "Additional languages can be added in the 'My languages' settings page." | 言語セクション |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| feedContentControllerがnil | assertionFailure発生、処理中断 |
| languageが見つからない | assertionFailure発生、処理中断 |

## 備考

- 本画面はBaseExploreFeedSettingsViewControllerを継承
- displayTypeは`.detail(contentGroupKind)`に設定される
- グローバルカード（pictureOfTheDay、continueReading、relatedPages、suggestedEdits）の場合は言語セクションが表示されない
- Suggested Editsカードの場合はImageRecommendationsFunnelでログを記録

---

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

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

### 推奨読解順序

#### Step 1: 画面の初期化を理解する

まず、画面がどのように設定されるかを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | configure(with:dataStore:contentGroupKind:theme:)メソッド（38-44行目） |

**読解のコツ**: この画面はExploreFeedSettingsViewControllerから遷移する際に`configure`メソッドで初期化されます。contentGroupKindがこの画面で設定対象となるカードを決定します。

#### Step 2: セクション構築を理解する

設定画面のセクション構成を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | togglingFeedCardFooterText遅延プロパティ（48-50行目） |
| 2-2 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | mainSection遅延プロパティ（52-54行目） |
| 2-3 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | languagesSection遅延プロパティ（56-58行目） |
| 2-4 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | sections計算プロパティ（60-66行目） |

**主要処理フロー**:
1. **48-50行目**: カード種別に応じたフッターテキストを取得
2. **52-54行目**: メインスイッチセクション（カード全体のオン/オフ）を生成
3. **56-58行目**: 言語セクションを生成
4. **60-66行目**: グローバルカードかどうかでセクション構成を決定

#### Step 3: カード種別ごとのフッターテキストを理解する

各カード種別のフッターテキスト定義を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | WMFContentGroupKind拡張（togglingFeedCardFooterText）（3-33行目） |

**主要処理フロー**:
- **5-6行目**: newsカードのフッターテキスト
- **7-8行目**: featuredArticleカードのフッターテキスト
- **9-10行目**: topReadカードのフッターテキスト
- **11-12行目**: onThisDayカードのフッターテキスト
- **14-20行目**: グローバルカード（continueReading等）のフッターテキスト

#### Step 4: スイッチ操作のハンドリングを理解する

ユーザーがスイッチを操作した際の処理フローを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | settingsTableViewCell(_:didToggleDisclosureSwitch:)（73-93行目） |

**主要処理フロー**:
- **75-76行目**: activeSwitchにsenderを保存、controlTagを取得
- **77-79行目**: feedContentControllerのnil確認
- **80-85行目**: controlTag=-1（メインスイッチ）の処理
- **81-83行目**: Suggested Editsカードの場合はログ記録
- **84行目**: toggleContentGroupでカード全体を切り替え
- **86-91行目**: 言語別スイッチの処理
- **91行目**: toggleContentGroup(of:isOn:forSiteURL:)で言語別に切り替え

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

```
FeedCardSettingsViewController
    │
    ├─ configure(with:dataStore:contentGroupKind:theme:)
    │      ├─ self.title = title
    │      ├─ self.dataStore = dataStore
    │      ├─ self.contentGroupKind = contentGroupKind
    │      ├─ self.theme = theme
    │      └─ displayType = .detail(contentGroupKind)
    │
    ├─ sections（計算プロパティ）
    │      ├─ contentGroupKind.isGlobal → [mainSection]
    │      └─ !isGlobal → [mainSection, languagesSection]
    │
    └─ settingsTableViewCell(_:didToggleDisclosureSwitch:)
           ├─ tag=-1 → feedContentController.toggleContentGroup(of:isOn:)
           │      └─ Suggested Edits時 → ImageRecommendationsFunnel.logSettingsToggle
           └─ tag≠-1 → feedContentController.toggleContentGroup(of:isOn:forSiteURL:)
```

### データフロー図

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

ExploreFeedSettings ────▶ configure() ──────────────────▶ 画面初期化
        │                      │
        │                      ▼
        │               contentGroupKind設定
        │                      │
        ▼                      ▼
カード行タップ          sections構築
                              │
                              ▼
                      mainSection + languagesSection
                             (非グローバル時)

メインスイッチ ────────▶ settingsTableViewCell
操作                   (_:didToggleDisclosureSwitch:)
                              │
                              ▼
                       feedContentController
                       .toggleContentGroup(of:isOn:)
                              │
                              ▼
                       CoreData更新 → Exploreフィード反映

言語別スイッチ ────────▶ settingsTableViewCell
操作                   (_:didToggleDisclosureSwitch:)
                              │
                              ▼
                       feedContentController
                       .toggleContentGroup(of:isOn:forSiteURL:)
                              │
                              ▼
                       CoreData更新 → Exploreフィード反映
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FeedCardSettingsViewController.swift | `Wikipedia/Code/FeedCardSettingsViewController.swift` | ソース | メインのViewController |
| BaseExploreFeedSettingsViewController.swift | `Wikipedia/Code/BaseExploreFeedSettingsViewController.swift` | ソース | 親クラス（フィード設定共通基盤） |
| ExploreFeedSettingsViewController.swift | `Wikipedia/Code/ExploreFeedSettingsViewController.swift` | ソース | 遷移元画面 |
| WMFExploreFeedContentController.swift | `WMF/Sources/WMF/DataControllers/WMFExploreFeedContentController.swift` | ソース | フィードコンテンツ管理 |
| WMFContentGroupKind.swift | `WMF/Sources/WMF/DataModel/WMFContentGroupKind.swift` | ソース | カード種別定義 |
| ImageRecommendationsFunnel.swift | `Wikipedia/Code/ImageRecommendationsFunnel.swift` | ソース | ログ記録（Suggested Edits用） |
