Skip to content

feat(dncl): DNCL モード拡張機能ブロック制限の UX 改善(confirm ダイアログ + 通知バナー) #701

@takaokouji

Description

@takaokouji

Goal

DNCL(日本語)モードで拡張機能ボタンを押したとき、単純な alert ではなく confirm ダイアログを出し「Rubyふりがなモードに戻しますか?」を選択できるようにする。OK 選択で Rubyふりがなモードへ切り替えて拡張機能ライブラリを開く。加えて、Codeタブ上に「日本語モード中・ブロックが制限されています」通知バナーを追加し、別のきっかけでも Rubyふりがなモードに戻れるようにする。

Background

ユーザーが想定外に DNCL(日本語)モードになっており、ブロックが少ない・拡張機能が選択できないことに気づかずにいるケースが発生している。現在の実装は window.alert で「使えません」と表示するだけでモード切り替えの手段を提供していない。

アーキテクチャ概要

handleToggleDnclModeruby-tab.jsx 内部に閉じているため、Redux signal パターン で外部からトリガーする:

ExtensionButton / DnclModeNotice (OK クリック)
  → dispatch(setDnclMode(false))               ← blocks.jsx が即座に全ブロック表示に更新
  → dispatch(requestExternalExitDnclMode())    ← ruby-tab の wasDncl 復元をスキップ
  → onExtensionButtonClick() (ライブラリ即時表示)

ruby-tab の wasDncl パス(Ruby タブを開いたとき)
  ← exitDnclModeExternallyRequested = true ならば handleToggleDnclMode() を呼ばない
  ← Ruby コードを blocks から再ロードして表示(DNCL 再有効化なし)
  → dispatch(clearExternalExitDnclModeRequest())

Affected Files

  • src/reducers/dncl-mode.jsexitDnclModeExternallyRequested state + 2 actions 追加
  • src/components/extension-button/extension-button.jsxwindow.alertwindow.confirmonRequestExitDnclMode prop 追加
  • src/components/dncl-mode-notice/ — 新規:通知バナーコンポーネント
  • src/components/gui/gui.jsx — DnclModeNotice 追加・props 配線(Smalruby マーカー)
  • src/containers/gui.jsxonRequestExitDnclModeonClearExitDnclModeRequest dispatch 追加
  • src/containers/ruby-tab.jsxwasDncl パスに skipRestore ロジック追加
  • src/locales/ja.js, ja-Hira.js, en.js — 新規文字列 3 つ
  • packages/scratch-gui/.prettierignore + .claude/rules/scratch-gui/smalruby-prettier-files.md — dncl-mode-notice/ をホワイトリストに追加

UI イメージ

通知バナー(Codeタブ上部):

┌──────────────────────────────────────────────────────────────────┐
│ ⚠️ 日本語モード:ブロックが制限されています  [Rubyふりがなモードに戻す] │
└──────────────────────────────────────────────────────────────────┘
[ブロック一覧...]

confirm ダイアログ(説明付き版):

日本語モードでは拡張機能は使えません。
Rubyふりがなモードに戻すと拡張機能が使えるようになります。
戻しますか?

    [OK]     [キャンセル]

Implementation Steps

  • Phase 1: Redux — exitDnclModeExternallyRequested state + requestExternalExitDnclMode / clearExternalExitDnclModeRequest actions 追加(TDD: reducer unit test)
  • Phase 2: ExtensionButton — window.alertwindow.confirm + onRequestExitDnclMode prop 追加(TDD: component unit test)
  • Phase 3: DnclModeNotice コンポーネント新規作成 + gui.jsx / container への配線(TDD: component unit test)
  • Phase 4: ruby-tab.jsx wasDncl パスに skipRestore ロジック追加(TDD: unit test)
  • Phase 5: locale 文字列追加(ja / ja-Hira / en)+ integration テスト追加
  • Phase DoD: CI 完了待ち + Playwright MCP によるブラウザ確認

New Locale Strings

key ja en
gui.extensionButton.dnclExtensionConfirm 日本語モードでは拡張機能は使えません。\nRubyふりがなモードに戻すと拡張機能が使えるようになります。\n戻しますか? Extensions are not available in Japanese mode.\nReturn to Ruby furigana mode to enable extensions.\nSwitch now?
gui.dnclModeNotice.message 日本語モード:ブロックが制限されています Japanese mode: blocks are restricted
gui.dnclModeNotice.exitButton Rubyふりがなモードに戻す Return to Ruby furigana mode

Definition of Done

  • ユニットテスト pass(Phase 1〜4 の各 RED→GREEN)
  • Integration テスト pass
  • lint pass(zero warnings)
  • CI green
  • ブラウザ確認(Playwright MCP):
    • DNCL モードで拡張機能ボタンをクリック → confirm ダイアログが表示される(alert ではない)
    • キャンセル → モードが変わらない(日本語モードのまま、ブロック制限継続)
    • OK → 拡張機能ライブラリが開く、ブロックが全件表示に戻る
    • OK 後に Ruby タブを開く → Ruby コードが表示される(DNCL 表示に戻らない)
    • DNCL モード時に Codeタブで通知バナーが表示される
    • バナーの「Rubyふりがなモードに戻す」を押す → 拡張機能ボタンが有効化、バナー非表示
    • iPad / スマホレイアウトでバナーが崩れない(data-testid: dncl-mode-notice

Test Plan

Type Timing Target
Unit tests (TDD) 実装前(RED→GREEN) reducer, extension-button, dncl-mode-notice, ruby-tab wasDncl
Integration tests 実装後 モード切り替えフロー、バナー表示・非表示
Browser verification CI green 後 Playwright MCP で DoD 全項目確認

Risks & Open Questions

  • window.confirm はブラウザネイティブのモーダルのため外観がブラウザ依存。将来的にカスタムモーダルへ変更する余地あり(今回は window.confirm で進める)。
  • iPad / スマホで ExtensionButton が表示されるか(MobileGui での visibility を要確認)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions