diff --git a/init.lua b/init.lua index 7d83680..0bb4f2d 100644 --- a/init.lua +++ b/init.lua @@ -207,7 +207,6 @@ function init(ctx) bg_texture = nil, -- L.10 loads it default_teaser_texture = nil, -- L.10 loads it t = function(k) return k end, -- L.8 swaps in real t() - modal_open = nil, -- L.7 sets to "quit" | "conflict" carousel_state = {}, -- per-module-id state, L.5 populates manifest_cache = {}, -- L.3 populates launcher_dir = MODULE_DIR, -- L.4: detail.lua dofiles markdown.lua via this @@ -340,22 +339,31 @@ function update(ctx, dt) local mx, my = engine.input.get_mouse_pos() + -- C1: detail.lua's launch-button branch signals a conflict via + -- ctx._pending_modal_open; dispatch the FSM event here so state + -- actually transitions into STATE_MODAL_CONFLICT before the modal + -- branch below runs. + if ctx_panels._pending_modal_open == "conflict" then + state = fsm.next(state, "open_conflict") + ctx_panels._pending_modal_open = nil + end + -- L.7: Conflict-modal takes priority over STATE_LIST input. esc / -- Cancel close the modal back to STATE_LIST; "Launch anyway" stays -- a no-op until engine.module.switch_module_supports_fallback ships. - if ctx_panels.modal_open == "conflict" then + if state == fsm.STATE_MODAL_CONFLICT then if input.was_action_pressed("ui_back") then - ctx_panels.modal_open = nil state = fsm.next(state, "esc") + ctx_panels.modal_def = nil elseif input.was_action_pressed("ui_click") then local id = modal_panel.handle_click(ctx_panels.modal_def, mx, my) if id == "cancel" then - ctx_panels.modal_open = nil state = fsm.next(state, "cancel") + ctx_panels.modal_def = nil elseif id == "launch_anyway" then local mid = ctx_panels.modal_def.module_id - ctx_panels.modal_open = nil state = fsm.next(state, "launch_anyway") + ctx_panels.modal_def = nil if engine.module.switch_module_supports_fallback then engine.switch_module(mid, { mode = "fallback" }) end @@ -396,7 +404,7 @@ function render(ctx) detail_panel.render(ctx_panels) -- L.7: Conflict modal renders above the panels (backdrop dims them). - if ctx_panels.modal_open == "conflict" then + if state == fsm.STATE_MODAL_CONFLICT then modal_panel.render(ctx_panels.modal_def, screen_w, screen_h) end diff --git a/panels/detail.lua b/panels/detail.lua index 12df29e..33eb4e7 100644 --- a/panels/detail.lua +++ b/panels/detail.lua @@ -155,7 +155,7 @@ function M.handle_click(ctx, mx, my) body = { ctx.t("conflict_body_line1"), string.format(ctx.t("conflict_body_line2_fmt"), - r and #r.missing or 0), + r and (#(r.errors or {}) + #(r.conflicts or {})) or 0), }, buttons = { { id = "cancel", label = ctx.t("cancel") }, @@ -164,7 +164,9 @@ function M.handle_click(ctx, mx, my) }, module_id = entry.id, } - ctx.modal_open = "conflict" + -- C1: signal init.lua to dispatch open_conflict on the FSM + -- so state actually transitions into STATE_MODAL_CONFLICT. + ctx._pending_modal_open = "conflict" end return true end