# 画面設計書 36-NotificationsCenter画面

## 概要

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

### 本画面の処理概要

NotificationsCenter画面は、Wikipediaアカウントに関連するすべての通知を一覧表示・管理する画面です。編集への感謝、トークページへの投稿、メンション、アラートなど、様々な種類の通知を確認し、既読/未読の管理、フィルタリング、詳細への遷移などの機能を提供します。

**業務上の目的・背景**：
Wikipediaの編集活動やコミュニティ活動に関する通知をユーザーに集約して提供することが目的です。他の編集者からのフィードバック、トークページへの返信、システムアラートなどを見逃さずに確認できるようにします。

**画面へのアクセス方法**：
1. タブバーの「Notifications」タブをタップ
2. Article画面のプロファイルボタンから遷移
3. プッシュ通知のタップ
4. ディープリンク

**主要な操作・処理内容**：
1. 通知一覧の表示（UICollectionView + DiffableDataSource）
2. 通知のフィルタリング（種類別、プロジェクト別）
3. 通知の既読/未読管理
4. 通知の一括既読化
5. 通知詳細への遷移
6. Pull to Refresh
7. 編集モードでの複数選択
8. セルスワイプアクション

**画面遷移**：
- 遷移元：TabBar、Article画面、プッシュ通知
- 遷移先：NotificationsCenterDetail画面、Article画面、UserPage画面、TalkPage画面等

**権限による表示制御**：
- ログインユーザー：全機能利用可能
- 未ログインユーザー：ログインを促すメッセージ表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | 通知センター | 主機能 | 通知一覧と管理 |

## 画面種別

一覧（通知一覧）

## URL/ルーティング

NSUserActivity対応：
- `wmf_notificationsCenterActivity()`: 通知センターへのディープリンク

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| theme | 入力 | Theme | テーマ設定 |
| viewModel | 入力 | NotificationsCenterViewModel | 通知データ・ビジネスロジック |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| collectionView | UICollectionView | 通知一覧 |
| NotificationsCenterCell | UICollectionViewCell | 通知セル |
| toolbar | UIToolbar | 下部ツールバー |
| typeFilterButton | IconBarButtonItem | 種類フィルターボタン |
| projectFilterButton | IconBarButtonItem | プロジェクトフィルターボタン |
| statusBarButton | StatusTextBarButtonItem | フィルター状態表示 |
| refreshControl | UIRefreshControl | Pull to Refresh |
| emptyView | UIView | 空状態表示 |

## イベント仕様

### 1-通知タップ

通知セルをタップすると、その通知を既読にしてNotificationsCenterDetailViewControllerに遷移します。

### 2-種類フィルター

ツールバーの種類フィルターボタンをタップすると、NotificationsCenterFiltersViewがモーダル表示され、通知種類でフィルタリングできます。

### 3-プロジェクトフィルター

ツールバーのプロジェクトフィルターボタンをタップすると、NotificationsCenterInboxViewがモーダル表示され、Wikiプロジェクト（言語版）でフィルタリングできます。

### 4-編集モード

ナビゲーションバーの「Edit」ボタンをタップすると編集モードに入り、複数の通知を選択できます。選択した通知を一括で既読/未読にできます。

### 5-全て既読化

編集モードで「Mark all as read」をタップすると、確認ダイアログ後に全ての未読通知を既読にします。

### 6-セルスワイプ

セルを左にスワイプすると、「More」「既読/未読」のアクションボタンが表示されます。

### 7-Pull to Refresh

画面を下に引っ張ると通知を再取得します。

### 8-無限スクロール

一覧の末尾に到達すると、次のページの通知を自動取得します。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 通知既読化 | - | API Call | MediaWiki API経由で既読化 |
| 通知未読化 | - | API Call | MediaWiki API経由で未読化 |
| 全て既読化 | - | API Call | MediaWiki API経由で一括既読化 |
| 通知取得 | CoreData | UPDATE | ローカルキャッシュ更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| notifications-center-title | タイトル | "Notifications" | ナビゲーションバー |
| notifications-center-mark | ボタン | "Mark" | 編集モード時 |
| notifications-center-mark-all-as-read | ボタン | "Mark all as read" | 編集モード時 |
| notifications-center-mark-all-as-read-confirmation-format | 確認 | "Are you sure that you want to mark all %d messages..." | 全既読化確認時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ネットワークエラー | refreshControl終了、エラー表示 |
| 通知が0件 | emptyView表示 |
| 未ログイン | ログイン促進メッセージ表示 |

## 備考

- UICollectionViewDiffableDataSourceによるモダンなデータ管理
- RemoteNotificationsFunnelによるアナリティクス
- NotificationsCenterOnboardingの初回表示
- プッシュ通知オプトインの提案
- VoiceOver対応
- セルスワイプのカスタム実装（UIPanGestureRecognizer）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NotificationsCenterViewModel | `Wikipedia/Code/` | 通知データ、フィルター、ページング |
| 1-2 | NotificationsCenterCellViewModel | `Wikipedia/Code/` | 通知セルのViewModel |
| 1-3 | NotificationsCenterSection | `Wikipedia/Code/` | DiffableDataSource用セクション |

**読解のコツ**: NotificationsCenterViewModelがremoteNotificationsControllerと連携してデータを取得・管理します。

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

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

**主要処理フロー**:
1. **77-84行目**: init時にviewModelのdelegateを設定
2. **95-99行目**: loadView()でNotificationsCenterViewを生成
3. **101-120行目**: viewDidLoadでセットアップ、fetchFirstPage()呼び出し
4. **129-139行目**: viewDidAppearでrefreshNotifications()、オンボーディング表示

#### Step 3: データソースを理解する

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

**主要処理フロー**:
- **244-261行目**: UICollectionViewDiffableDataSourceの設定
- **263-277行目**: applySnapshot()でスナップショット適用
- **279-287行目**: selectedCellViewModelsで選択中のセル取得

#### Step 4: 編集モードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | NotificationsCenterViewController.swift | `Wikipedia/Code/NotificationsCenterViewController.swift` | setEditing()のオーバーライド |

**主要処理フロー**:
- **196-213行目**: 編集モードの切り替え処理
- **336-397行目**: マークボタンのメニュー生成
- **463-489行目**: 全既読化の確認ダイアログ

#### Step 5: セルスワイプを理解する

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

**主要処理フロー**:
- **715-726行目**: closeSwipeActionsPanelIfNecessary()
- **740-750行目**: animateSwipePanel()でアニメーション
- **752-836行目**: userDidPanCell()でパンジェスチャー処理

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

```
NotificationsCenterViewController
    │
    ├─ init(theme:viewModel:)
    │      └─ viewModel.delegate = self
    │
    ├─ viewDidLoad()
    │      ├─ setupBarButtons()
    │      ├─ setupDataSource()
    │      ├─ viewModel.setup()
    │      └─ viewModel.fetchFirstPage()
    │
    ├─ viewDidAppear()
    │      ├─ viewModel.refreshNotifications()
    │      ├─ viewModel.markAllAsSeen()
    │      └─ presentOnboardingEducationModalIfNecessary()
    │
    ├─ UICollectionViewDelegate
    │      ├─ willDisplay → fetchNextPage()（無限スクロール）
    │      ├─ didSelectItemAt → 詳細遷移 or 選択
    │      └─ didDeselectItemAt → 選択解除
    │
    ├─ NotificationsCenterViewModelDelegate
    │      └─ update(types:) → UI更新
    │
    └─ NotificationsCenterCellDelegate
           ├─ userDidTapMoreActionForCell()
           └─ userDidTapMarkAsReadUnreadActionForCell()
```

### データフロー図

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

viewModel.setup()      ──────▶ fetchFirstPage()           ──────▶ applySnapshot()
                               │                                   → collectionView更新
                               ▼
Pull to Refresh        ──────▶ refreshNotifications()     ──────▶ applySnapshot()
                               │
                               ▼
Scroll to end          ──────▶ fetchNextPage()            ──────▶ applySnapshot()
                               │
                               ▼
Cell tap               ──────▶ didSelectItemAt()          ──────▶ push(DetailVC)
                               │
                               ▼
Mark as read/unread    ──────▶ viewModel.markAsReadOrUnread() ──▶ reconfigureCells()
                               │
                               ▼
Filter change          ──────▶ viewModel.resetAndRefreshData() ─▶ applySnapshot()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NotificationsCenterViewController.swift | `Wikipedia/Code/NotificationsCenterViewController.swift` | ソース | メインViewController |
| NotificationsCenterView.swift | `Wikipedia/Code/NotificationsCenterView.swift` | ソース | メインView |
| NotificationsCenterViewModel.swift | `Wikipedia/Code/NotificationsCenterViewModel.swift` | ソース | ビジネスロジック |
| NotificationsCenterCell.swift | `Wikipedia/Code/NotificationsCenterCell.swift` | ソース | 通知セル |
| NotificationsCenterCellViewModel.swift | `Wikipedia/Code/NotificationsCenterCellViewModel.swift` | ソース | セルViewModel |
| NotificationsCenterDetailViewController.swift | `Wikipedia/Code/NotificationsCenterDetailViewController.swift` | ソース | 詳細画面 |
| NotificationsCenterFiltersViewModel.swift | `Wikipedia/Code/NotificationsCenterFiltersViewModel.swift` | ソース | フィルターViewModel |
| NotificationsCenterFilterView.swift | `Wikipedia/Code/NotificationsCenterFilterView.swift` | ソース | フィルターView (SwiftUI) |
| NotificationsCenterInboxView.swift | `Wikipedia/Code/NotificationsCenterInboxView.swift` | ソース | Inbox View (SwiftUI) |
| NotificationsCenterOnboardingHostingViewController.swift | `Wikipedia/Code/NotificationsCenterOnboardingHostingViewController.swift` | ソース | オンボーディング |
| RemoteNotificationsFunnel.swift | `Wikipedia/Code/RemoteNotificationsFunnel.swift` | ソース | アナリティクス |
