AIのコードレビューで見つかったバグを直す中で「なるほど」と思った設計の話を、勉強のためにまとめた学習メモです。
同じ画面を iOS / Android / Mac / Windows で出していて、モバイルとデスクトップでレイアウトが違うので、画面ごとに「mobile版」「desktop版」を用意して出し分けています。その出し分けの基準を画面幅でやっていたら、デスクトップのウィンドウを狭めたときだけ「フォルダから綴る」導線が消えるバグになっていた。Codex のレビューで指摘されて、原因をたどったら「分岐の基準が2本あって、それがねじれていた」という話だった。
何が起きていたか
綴る画面(写真を選んで言葉を添える画面)は、画面幅が広ければデスクトップ用、狭ければモバイル用を出すようにしていました。デスクトップアプリのウィンドウは最小幅まで縮められます。縮めて幅が閾値を下回ると、デスクトップOSなのにモバイル用の画面が出ます。
モバイル用の綴る画面は「端末のカメラロールから写真を読む」前提で作ってあります。でもデスクトップにカメラロールはありません。デスクトップは「フォルダを選んで、その中の写真を読む」。だからデスクトップOSで幅だけモバイル用に切り替わると、モード選択で選んだフォルダのパスがどこにも渡らず、写真が一枚も出ないまま固まります。フォルダは選んだのに、その先が空っぽ。
分岐の基準が2本あった
Codex が指摘したのは「ウィンドウの最小幅とレイアウト閾値の数値のズレ」だった。そこから「なぜ数値を揃えるだけでは根治にならないか」を自分でたどったら、分岐の軸が2本あってねじれているという話に行き着いた。
整理したら、この画面には性質の違う分岐が2つ混ざっていた。
// レイアウトの分岐:画面幅で決める(広い=横並び、狭い=縦)
if (画面幅 >= 800) デスクトップ用レイアウト
else モバイル用レイアウト
// データソースの分岐:OSで決まる(PC=フォルダ、スマホ=カメラロール)
// ← 本来は上とは別の軸。でも綴る画面では上の「画面幅」と同じ条件で切り替えていた
if (デスクトップOS) フォルダから読む
else カメラロールから読むこの2つは別の基準で動くべきなのに、綴る画面では「画面幅」1本でまとめて切り替えていた。
さらに厄介だったのは、同じ綴るフローの入口にあたる「モード選択画面」は、ちゃんとOSで分岐していたこと。2つの画面は別のタイミングで実装していて、後から幅分岐でレスポンシブ対応を足したときに綴る画面だけ軸が変わった(モード選択は手を付けなかった)。
普段は気づかない。デスクトップを最小幅近くまで狭めた、その帯(綴Photo だと 600〜800px のあいだ)でだけ噛み合わなくなります。
軸を揃えた
直し方は、綴る画面の分岐も画面幅からOSに揃えるだけだった。
// 修正後:綴る画面もOSで分岐(モード選択と同じ基準にする)
if (デスクトップOS) デスクトップ用(フォルダのパスを受け取る)
else モバイル用(カメラロール)ついでにウィンドウの最小幅もレイアウト閾値と同じ 800px に揃えて、そもそも中途半端な幅にならないようにした。
気づきとして大きかったのは、「mobile/desktop の出し分け」と一口に言っても、見た目を分ける軸とデータの出どころを分ける軸は別物で、たまたま多くの場面で一致して見えていただけ、ということ。一致して見えるから1本にまとめたくなるけど、ズレる瞬間(狭いデスクトップ)が来ると破綻します。
学びポイント
- 「mobile/desktop で分ける」には、レイアウトの軸(画面幅)とデータソースの軸(OS)が混ざっています。普段は一致して見えるだけで、別物
- 同じフロー内で分岐の基準が画面ごとに食い違うと、特定の条件(綴Photo なら狭いデスクトップ)でだけ噛み合わなくなります。入口と次の画面で軸を揃えます
- 「広い/狭い」で全部まとめて切り替えると楽だけど、その楽さが効くのは2軸がたまたま一致している間だけ
おわりに
このバグは、デスクトップを最小幅まで縮めるという、自分ではあまりやらない操作でだけ出ます。Codex のレビューが「ウィンドウの最小幅とレイアウト閾値がズレている」と幅の数字から指摘してくれて、たどったら軸のねじれに行き着いた。直し自体は分岐を1本書き換えるだけだったけど、「レイアウトとデータソースは別の軸」という見方を持てたのが収穫だった。
この記事は2026年6月時点の自分の理解で書いています。仕様や認識が変わってる可能性があります。