Skip to content

fix(mobile-gui): dispatch resize event when orientation gate is dismissed to restore PaletteToggle #695

@takaokouji

Description

@takaokouji

Description

MobileOrientationGate の警告オーバーレイを「このまま使う」ボタンで dismiss した直後、コードタブの PaletteToggle (ブロックパレット開閉ボタン /) が表示されない。コスチュームタブなど別タブに移動してからコードタブに戻ると正しく表示される。

PR #693 (Issue #691) で dismiss 機能を追加したことで顕在化したが、原因自体はそれ以前から存在する既存不具合の可能性が高い。実機モバイルで縦持ち → 横持ち回転した場合はブラウザ側が自動で resize イベントを発火するため気付かれていなかった。

Steps to Reproduce

  1. PC ブラウザで viewport を縦長 (例: 700×900) にリサイズして開く
  2. MobileOrientationGate の警告オーバーレイが表示される
  3. 「このまま使う」ボタンをクリックして dismiss
  4. コードタブ画面に戻る
  5. PaletteToggle (◀/▶ ボタン) が表示されない ことを確認
  6. コスチュームタブ等に切り替え → コードタブに戻る → PaletteToggle が表示される

確認した URL: https://smalruby.jp/smalruby3-editor/feature/dismiss-orientation-gate/

Expected Behavior

dismiss 直後にも PaletteToggle が表示されている (タブ切替なしで正常な状態になる)。

Actual Behavior

dismiss 直後はコードタブの toolbox/flyout のレイアウトが初期化時の状態で固定されており、PaletteToggle が描画されない。タブ切替で Blocks が再レイアウトされて初めて表示される。

Root Cause (推定)

packages/scratch-gui/src/containers/blocks.jsxshouldComponentUpdate (lines 220–232) は以下の prop 変化のみを監視している:

  • isVisible, extensionLibraryVisible, customProceduresVisible, locale, anyModalVisible, stageSize, selectedBlocks, tutorialAllowedBlocks, paletteVisible, toolboxXML

orientation gate の dismiss はこれらに該当する prop を一切変えないため、Blocks コンポーネントは再 render されず、Blockly の toolbox/flyout は overlay が画面を覆っていた時点での初期サイズで固定される。PaletteTogglerender() 内の const toolbox = this.workspace ? this.workspace.getToolbox() : null;toolbox が null の場合は描画されない。

タブ切替で復活するのは、componentDidUpdateisVisible 変化を検知して workspace.setVisible(true)vm.refreshWorkspace()window.dispatchEvent(new Event('resize'))requestToolboxUpdate() を実行するため (blocks.jsx:268–296)。

提案する修正

MobileOrientationGate.handleDismisssetDismissed(true) 後に window.dispatchEvent(new Event('resize')) を発火する。Blockly は resize イベントで再レイアウトを行うため、toolbox/flyout が正しく再計測され PaletteToggle が描画される。1 行追加で済むはず。

const handleDismiss = useCallback(() => {
    setDismissed(true);
    if (typeof window !== 'undefined' && window.sessionStorage) {
        try {
            window.sessionStorage.setItem(DISMISS_STORAGE_KEY, 'true');
        } catch (e) {}
    }
    // Blockly に再レイアウトを促す (gate に覆われていた間の不正な toolbox 計測を更新)
    if (typeof window !== 'undefined') {
        window.dispatchEvent(new Event('resize'));
    }
}, []);

Files

  • packages/scratch-gui/src/components/mobile-orientation-gate/mobile-orientation-gate.jsx — handleDismiss に resize dispatch を追加
  • packages/scratch-gui/test/unit/components/mobile-orientation-gate.test.jsx — dismiss クリック時に resize イベントが発火することを検証するテストを追加

Related

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