# 通知設計書 36-localization.prompt

## 概要

本ドキュメントは、VS Code エディタにおける言語パック関連の通知機能の設計を記載する。NativeLocalizationWorkbenchContributionは、言語パック拡張機能のインストール時や、システムロケールに基づく言語パック提案を行う。

### 本通知の処理概要

localization.prompt通知は、以下の2つのシナリオで言語関連の通知を表示する機能である：
1. 言語パック拡張機能のインストール後に表示言語の変更を提案する
2. システムロケールとVSCodeの表示言語が異なる場合に言語パックのインストールを提案する

**業務上の目的・背景**：VSCodeは多言語対応しており、ユーザーの言語環境に合わせた表示言語を提供することでユーザー体験を向上させる。言語パックがインストールされた際や、システムロケールに合った言語パックが存在する場合にユーザーに提案することで、シームレスな多言語サポートを実現する。

**通知の送信タイミング**：(1) 言語パック拡張機能がインストールされた直後、(2) VSCode起動時にシステムロケールと表示言語が異なり、かつ該当言語パックが利用可能な場合。

**通知の受信者**：VSCodeを使用しているユーザー本人がNotificationServiceを通じて通知を受け取る。

**通知内容の概要**：言語変更の提案メッセージと、「Change Language and Restart」または「Install and Restart」/「Search Marketplace」のアクションボタンが表示される。

**期待されるアクション**：ユーザーはアクションボタンをクリックして言語を変更・再起動するか、「Don't Show Again」で今後の提案を非表示にできる。

## 通知種別

アプリ内通知（NotificationService.prompt）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（インストール後）/ 非同期（起動時チェック） |
| 優先度 | 緊急（インストール後）/ オプション（起動時提案） |
| リトライ | なし |

### 送信先決定ロジック

VSCodeを使用しているユーザーに対して、NotificationServiceを通じてウィンドウ内に通知が表示される。

## 通知テンプレート

### シナリオ1: 言語パックインストール後

| 項目 | 内容 |
|-----|------|
| 重要度 | Info |
| 表示位置 | 画面右下の通知エリア |
| 自動消去 | なし（sticky: true） |

#### 本文テンプレート

```
Would you like to change {製品名}'s display language to {言語名} and restart?
```

#### アクションボタン

| ボタン | 説明 |
|--------|------|
| Change Language and Restart | 表示言語を変更してVSCodeを再起動 |

### シナリオ2: システムロケール言語パック提案

| 項目 | 内容 |
|-----|------|
| 重要度 | Info |
| 表示位置 | 画面右下の通知エリア |
| 自動消去 | あり（sticky: false） |

#### 本文テンプレート（言語パックが存在する場合）

```
{翻訳されたメッセージ} ({英語のメッセージ})
```

例: "日本語に変更してVisual Studio Codeを再起動しますか? (Would you like to change VS Code's display language to Japanese and restart?)"

#### アクションボタン

| ボタン | 説明 |
|--------|------|
| Install and Restart | 言語パックをインストールして再起動 |
| Don't Show Again | 今後表示しない（ストレージに保存） |

#### 本文テンプレート（言語パックが存在しない場合）

```
{翻訳されたメッセージ} ({英語のメッセージ})
```

#### アクションボタン

| ボタン | 説明 |
|--------|------|
| Search Marketplace | Marketplaceで言語パックを検索 |
| Don't Show Again | 今後表示しない |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| productService.nameLong | 製品名（長形式） | IProductService | Yes |
| languageName | 言語名 | localization.languageName | Yes |
| languageId | 言語ID | localization.languageId | Yes |
| translationsFromPack | 翻訳文字列 | galleryService.getCoreTranslation | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 拡張機能インストール | onDidInstallExtensions | 言語パック拡張機能がインストールされた | インストール後の言語変更提案 |
| 起動 | Workbench初期化 | システムロケール != 表示言語 && 言語パック利用可能 | 起動時の言語パック提案 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 同じ言語 | platform.language === localization.languageId |
| 無視リスト | languagePackSuggestionIgnoreListに含まれている |
| 既にインストール済み | 該当言語パックが既にインストールされている |
| ギャラリー無効 | galleryService.isEnabled() === false |

## 処理フロー

### 送信フロー（言語パックインストール後）

```mermaid
flowchart TD
    A[onDidInstallExtensions] --> B{言語パック拡張機能?}
    B -->|No| C[終了]
    B -->|Yes| D{現在の言語と同じ?}
    D -->|Yes| C
    D -->|No| E[notificationService.prompt]
    E --> F[言語変更提案表示]
    F --> G{ユーザーアクション}
    G -->|Change Language| H[localeService.setLocale]
    H --> I[VSCode再起動]
    G -->|Dismiss| C
```

### 送信フロー（起動時言語パック提案）

```mermaid
flowchart TD
    A[checkAndInstall] --> B{ギャラリー有効?}
    B -->|No| C[終了]
    B -->|Yes| D{言語設定チェック}
    D -->|デフォルト言語| C
    D -->|無視リストに含む| C
    D -->|言語パック既存| C
    D -->|条件OK| E[ギャラリー検索]
    E --> F{言語パック発見?}
    F -->|No| C
    F -->|Yes| G[翻訳文字列取得]
    G --> H[notificationService.prompt]
    H --> I[言語パック提案表示]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| languagePackSuggestionIgnoreList | 無視する言語のリスト | StorageService |
| platform.language | 現在の表示言語 | プラットフォームAPI |
| platform.locale | システムロケール | プラットフォームAPI |

### StorageService詳細

| キー | スコープ | 型 | 説明 |
|-----|---------|-----|------|
| extensionsAssistant/languagePackSuggestionIgnore | StorageScope.APPLICATION | string[] | 無視する言語IDのリスト |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ギャラリー検索失敗 | ネットワークエラー等 | 処理を中断（通知なし） |
| 翻訳取得失敗 | マニフェスト取得失敗 | 英語のみのメッセージを表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | 起動時に1回、インストール時に都度 |

### 配信時間帯

イベント発生時に即座に表示（時間帯制限なし）

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

- 言語パックはMarketplaceから取得されるため、信頼性はMarketplaceのセキュリティに依存
- ユーザーの言語設定情報はテレメトリに送信される

## 備考

- テレメトリで言語パック提案への反応（install, search, cancelled, neverShowAgain）が記録される
- 設定同期により言語パックがインストールされた場合も通知が表示される

---

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

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

### 推奨読解順序

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

まず、言語パック関連のデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | LANGUAGEPACK_SUGGESTION_IGNORE_STORAGE_KEY定義（24行目） |

**読解のコツ**: platform.languageとplatform.localeの違いを理解する。languageはVSCodeの表示言語、localeはシステムロケール。

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

通知が発生する起点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | コンストラクタ（26-41行目） |
| 2-2 | localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | onDidInstallExtension（52-80行目） |
| 2-3 | localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | checkAndInstall（91-215行目） |

**主要処理フロー**:
1. **38行目**: checkAndInstall()の呼び出し
2. **39-40行目**: 拡張機能インストール/アンインストールイベントの登録

#### Step 3: 言語パックインストール後の通知を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | onDidInstallExtension内のnotificationService.prompt（59-79行目） |

**主要処理フロー**:
- **53-56行目**: 言語パック以外または同じ言語の場合は早期終了
- **59行目**: Severity.Infoで通知開始
- **61行目**: 言語変更の提案メッセージ
- **62-72行目**: Change Language and Restartアクション

#### Step 4: 起動時の言語パック提案を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | checkAndInstall メソッド全体（91-215行目） |

**主要処理フロー**:
- **102-110行目**: 抑止条件のチェック
- **118-126行目**: ギャラリーで言語パック検索
- **135-153行目**: 翻訳文字列の準備
- **190-214行目**: notificationService.prompt呼び出し

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

```
NativeLocalizationWorkbenchContribution (constructor)
    │
    ├─ checkAndInstall()
    │      │
    │      ├─ galleryService.query() → 言語パック検索
    │      │
    │      ├─ galleryService.getManifest() → マニフェスト取得
    │      │
    │      ├─ galleryService.getCoreTranslation() → 翻訳取得
    │      │
    │      └─ notificationService.prompt()  ← 言語パック提案通知
    │
    └─ onDidInstallExtensions()
           │
           └─ onDidInstallExtension()
                  │
                  └─ notificationService.prompt()  ← 言語変更提案通知
```

### データフロー図

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

言語パックインストール ──▶ onDidInstallExtension()
      │                         │
      │                         ▼
      │                  言語パックか判定
      │                         │
      │                         ▼
      └────────────────▶ notificationService.prompt()
                                │
                                ▼
                        言語変更提案通知

VSCode起動 ─────────▶ checkAndInstall()
      │                    │
      │                    ▼
      │            システムロケール確認
      │                    │
      │                    ▼
      │            ギャラリー検索
      │                    │
      │                    ▼
      └───────────▶ notificationService.prompt()
                          │
                          ▼
                   言語パック提案通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| localization.contribution.ts | `src/vs/workbench/contrib/localization/electron-browser/localization.contribution.ts` | コントリビューション | Electron版の言語パック機能 |
| localization.contribution.ts | `src/vs/workbench/contrib/localization/common/localization.contribution.ts` | コントリビューション | 共通の言語パック機能 |
| minimalTranslations.ts | `src/vs/workbench/contrib/localization/electron-browser/minimalTranslations.ts` | 翻訳データ | 最小限の翻訳文字列 |
| locale.ts | `src/vs/workbench/services/localization/common/locale.ts` | サービス | ILocaleServiceの定義 |
| notification.ts | `src/vs/platform/notification/common/notification.ts` | インターフェース | INotificationServiceの定義 |
