# 機能設計書 70-WebView表示

## 概要

本ドキュメントは、WebView表示機能の設計仕様を定義する。外部URLやWeb コンテンツをアプリ内のWebViewで表示する汎用機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：ECアプリでは、決済ページや外部コンテンツなど、ネイティブ実装が困難なWebベースのコンテンツを表示する必要がある。本機能はアプリを離れることなくWebコンテンツを表示し、ユーザー体験を維持しながら外部リソースにアクセスする手段を提供する。

**機能の利用シーン**：
- 決済ゲートウェイのページ表示
- GDPR関連のWebコンテンツ表示
- 外部の利用規約・プライバシーポリシーページ表示
- サードパーティサービスのWebインターフェース表示

**主要な処理内容**：
1. 指定されたURLをInAppWebViewで読み込み
2. 認証情報（Cookie、トークン）をヘッダーに設定
3. ページ読み込み状況をプログレスバーで表示
4. ロード完了までの進捗をリアルタイムで更新

**関連システム・外部連携**：
- flutter_inappwebview パッケージ（WebViewレンダリング）
- 外部Webサーバー（表示対象URL）

**権限による制御**：表示対象のコンテンツに依存。認証が必要な場合はヘッダーにトークンを含めて送信。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 34 | WebView画面 | 主画面 | 外部URLのWebView表示処理 |
| 35 | GDPR WebView画面 | 主画面 | GDPR関連のWebコンテンツをWebViewで表示 |

## 機能種別

コンテンツ表示処理（READ操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| redirectUrl | String | No | 表示対象のURL | 有効なURL形式 |
| title | String | No | AppBarに表示するタイトル | - |

### 入力データソース

- 画面遷移時のルート引数
- アプリ内の各種ボタン・リンクからの遷移

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| loadData | double | ページ読み込み進捗（0.0〜1.0） |

### 出力先

- WebView内のコンテンツ表示
- LinearProgressIndicator（読み込み進捗）

## 処理フロー

### 処理シーケンス

```
1. 画面初期化
   └─ Scaffoldで画面構築
   └─ AppBarにtitle表示
2. InAppWebView初期化
   └─ initialUrlRequestにredirectUrlを設定
   └─ headersに認証情報を設定
3. ページ読み込み開始（onLoadStart）
   └─ デバッグログ出力
4. 進捗更新（onProgressChanged）
   └─ setStateでloadDataを更新
   └─ 進捗値 = progress / 100
5. ページ読み込み完了（onLoadStop）
   └─ デバッグログ出力
   └─ プログレスバー非表示
6. エラー発生時（onReceivedError）
   └─ エラーログ出力
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示] --> B[InAppWebView初期化]
    B --> C[URLリクエスト設定]
    C --> D[ヘッダー設定]
    D --> E[ページ読み込み開始]
    E --> F[onLoadStart]
    F --> G[onProgressChanged]
    G --> H{progress < 100?}
    H -->|Yes| I[プログレスバー表示]
    I --> G
    H -->|No| J[onLoadStop]
    J --> K[プログレスバー非表示]
    K --> L[コンテンツ表示完了]
    G --> M{エラー発生?}
    M -->|Yes| N[onReceivedError]
    N --> O[エラーログ出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-70-01 | 認証ヘッダー | 認証済みの場合、Authorizationヘッダーにトークンを設定 | ログイン時 |
| BR-70-02 | Cookie設定 | Cookieヘッダーを設定してセッション維持 | 常時 |
| BR-70-03 | ロケール設定 | x-localeヘッダーで言語設定を送信 | 常時 |
| BR-70-04 | 通貨設定 | x-currencyヘッダーで通貨設定を送信 | 常時 |
| BR-70-05 | プログレス表示 | 読み込み完了（100%）までプログレスバーを表示 | 読み込み中 |
| BR-70-06 | ナビゲーション許可 | shouldOverrideUrlLoadingでALLOWを返却 | 常時 |

### 計算ロジック

| 計算項目 | 計算式 | 備考 |
|---------|-------|------|
| loadData | progress / 100 | progressは0〜100の整数 |

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

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

本機能はWebViewでの表示のみを行い、ローカルデータベース操作は行わない。

| 操作 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| 設定読み取り | appStoragePref | READ | Cookie、トークン、言語、通貨の取得 |

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | インターネット接続なし | onReceivedErrorでエラーログ出力 |
| - | URLエラー | 無効なURL形式 | WebViewのエラー表示 |
| - | 証明書エラー | SSL証明書の問題 | WebViewのエラー表示 |
| - | タイムアウト | ページ読み込み時間超過 | WebViewのエラー表示 |

### リトライ仕様

自動リトライは実装されていない。ユーザーはブラウザのリロード機能または画面を再表示する必要がある。

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

該当なし（読み取り専用）

## パフォーマンス要件

- WebView初期化: 1秒以内
- ページ読み込み: 対象Webサーバーの応答時間に依存

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

- 認証トークンをヘッダーに含めて送信
- HTTPはHTTPSに自動アップグレードされない（対象URLに依存）
- Cookieは設定に応じて送信
- ナビゲーションは全て許可（ALLOW）
- is-cookie-existヘッダーで Cookie存在を通知

## 備考

- InAppWebViewKeepAlive()でWebViewの状態を維持
- プログレスバーは赤い背景にグレーの進捗表示
- WebUriでURL文字列をパース

---

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

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

### 推奨読解順序

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

処理の起点となるウィジェットファイルを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | common_webview.dart | `lib/widgets/common_webview.dart` | CommonWebViewウィジェット、InAppWebView設定 |

**主要処理フロー**:
1. **7-16行目**: CommonWebViewクラス定義、redirectUrlとtitleをコンストラクタで受け取る
2. **19-20行目**: 状態変数loadData（読み込み進捗）の定義
3. **23-76行目**: buildメソッドでScaffoldとWebView構築
4. **30-64行目**: InAppWebViewウィジェットの設定

#### Step 2: WebView設定を理解する

InAppWebViewの各種設定を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | common_webview.dart | `lib/widgets/common_webview.dart` | initialUrlRequest、headersの設定 |

**主要処理フロー**:
- **31行目**: keepAliveでWebView状態維持
- **32-41行目**: initialUrlRequestでURL設定とヘッダー設定
- **34-41行目**: headersに認証情報を含むカスタムヘッダー設定

#### Step 3: コールバック処理を理解する

ページ読み込み時の各種コールバックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | common_webview.dart | `lib/widgets/common_webview.dart` | onLoadStart、onLoadStop、onProgressChanged、onReceivedError |

**主要処理フロー**:
- **43-45行目**: onLoadStartでページ読み込み開始ログ
- **46-48行目**: onLoadStopでページ読み込み完了ログ
- **49-54行目**: onProgressChangedで進捗値更新
- **55-58行目**: onReceivedErrorでエラーログ
- **59-63行目**: shouldOverrideUrlLoadingでナビゲーション許可

#### Step 4: プログレスバー表示を理解する

読み込み進捗の表示を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | common_webview.dart | `lib/widgets/common_webview.dart` | LinearProgressIndicatorの条件付き表示 |

**主要処理フロー**:
- **65-73行目**: Positionedでプログレスバーを上部に配置
- **68-69行目**: loadData < 1 の場合のみ表示
- **70-72行目**: LinearProgressIndicatorでグレー/赤のプログレスバー

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

```
CommonWebView (common_webview.dart)
    │
    ├─ build
    │      ├─ Scaffold
    │      │      ├─ AppBar (title表示)
    │      │      └─ Stack
    │      │             ├─ InAppWebView
    │      │             │      ├─ keepAlive: InAppWebViewKeepAlive()
    │      │             │      ├─ initialUrlRequest
    │      │             │      │      ├─ url: WebUri(redirectUrl)
    │      │             │      │      └─ headers: {...}
    │      │             │      ├─ onLoadStart
    │      │             │      ├─ onLoadStop
    │      │             │      ├─ onProgressChanged → setState(loadData)
    │      │             │      ├─ onReceivedError
    │      │             │      └─ shouldOverrideUrlLoading → ALLOW
    │      │             │
    │      │             └─ Positioned (top)
    │      │                    └─ Visibility (loadData < 1)
    │      │                           └─ LinearProgressIndicator
```

### データフロー図

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

redirectUrl ───────────▶ WebUri.parse ───────────▶ InAppWebView.initialUrlRequest
                                                          │
title ─────────────────────────────────────────▶ AppBar.title
                                                          │
appStoragePref ────────▶ headers設定 ───────────▶ URLRequest.headers
    │                                                     │
    ├─ getCookieGet()                                     │
    ├─ getCustomerToken()                                 │
    ├─ GlobalData.currencyCode                            │
    └─ GlobalData.locale                                  │
                                                          │
                                                          ▼
                                               InAppWebView.onProgressChanged
                                                          │
                                                          ▼
                                               setState(loadData = progress / 100)
                                                          │
                                                          ▼
                                               LinearProgressIndicator表示
                                               (loadData < 1 の場合)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| common_webview.dart | `lib/widgets/common_webview.dart` | ソース | WebView表示ウィジェット |
| app_storage_pref.dart | `lib/utils/app_storage_pref.dart` | ソース | SharedPreferencesラッパー |
| app_global_data.dart | `lib/utils/app_global_data.dart` | ソース | グローバルデータ（currencyCode、locale） |
| app_constants.dart | `lib/utils/app_constants.dart` | 設定 | AppSizes定数 |
| index.dart | `lib/utils/index.dart` | ソース | 共通ユーティリティのエクスポート |
