Fix distractor explanations rendering on unanswered questions
Guarded the answer-review render path (teaching cards, review follow-ups, distractor explanations) on current_answer/pending_correct_advance directly rather than solely on correct_review_panel.visible, and added the same guard inside _render_unselected_distractor_explanations itself. This closes a path where a fresh, never-answered question could show wrong-answer explanations immediately, before any selection or submission. Also: unselected distractors now render in the same red "wrong" card style as selected/locked-wrong choices once a question is being reviewed, instead of staying in the plain default row style. And removed the redundant percentage badge that was floating above the in-progress follow-up quiz prompt, since the choice button above it already shows the same percentage.
This commit is contained in:
@@ -943,7 +943,10 @@ func _apply_question_theme() -> void:
|
||||
_style_choice_button_for_state(index, choice_id)
|
||||
for attempted_choice_id in followup_attempt_order:
|
||||
_render_followup_state(str(attempted_choice_id))
|
||||
if correct_review_panel != null and correct_review_panel.visible:
|
||||
# Guarding on current_answer/pending_correct_advance too (not just the panel's
|
||||
# own visible flag) so these can never render for a question that hasn't
|
||||
# actually been answered yet, even if visible was left stale by some other path.
|
||||
if correct_review_panel != null and correct_review_panel.visible and (not current_answer.is_empty() or pending_correct_advance):
|
||||
_render_teaching_cards()
|
||||
_render_review_followups()
|
||||
_render_unselected_distractor_explanations()
|
||||
@@ -1671,6 +1674,10 @@ func _render_unselected_distractor_explanations() -> void:
|
||||
# nest it directly in that choice's own card instead of a repeated
|
||||
# aggregate list at the bottom. Choices that DID trigger a follow-up
|
||||
# already show this same explanation inside the resolved quiz view.
|
||||
# Guard against ever rendering on a question that hasn't actually been
|
||||
# answered yet, regardless of what triggered this call.
|
||||
if current_answer.is_empty() and not pending_correct_advance:
|
||||
return
|
||||
var question := BlockSessionService.get_current_question()
|
||||
var correct_id := str(question.get("correct_choice_id", ""))
|
||||
var choices := _get_presented_choices()
|
||||
@@ -3034,7 +3041,7 @@ func _style_choice_button_for_state(index: int, choice_id: String) -> void:
|
||||
var reviewing := pending_correct_advance or not current_answer.is_empty()
|
||||
if reviewing and choice_id == correct_id:
|
||||
state = "correct"
|
||||
elif locked_wrong_choice_ids.has(choice_id) or (reviewing and choice_id == selected_choice):
|
||||
elif locked_wrong_choice_ids.has(choice_id) or (reviewing and choice_id != "" and choice_id != correct_id):
|
||||
state = "wrong"
|
||||
elif choice_id == selected_choice:
|
||||
state = "selected"
|
||||
@@ -3170,7 +3177,6 @@ func _append_followup_attempt(choice_id: String) -> void:
|
||||
|
||||
func _render_active_followup(index: int, state: Dictionary) -> void:
|
||||
var content := choice_followup_contents[index]
|
||||
_build_followup_header(content, state)
|
||||
var body_content := _add_followup_body(content, false)
|
||||
|
||||
var prompt := Label.new()
|
||||
@@ -3269,31 +3275,6 @@ func _build_resolved_followup(index: int, state: Dictionary) -> void:
|
||||
content.add_child(explanation)
|
||||
|
||||
|
||||
func _build_followup_header(content: VBoxContainer, state: Dictionary) -> void:
|
||||
var dark := _followup_is_dark()
|
||||
var is_main_correct := bool(state.get("is_main_correct", false))
|
||||
var accent := Brand.SUCCESS if is_main_correct else Color("fb5f6d")
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 10)
|
||||
content.add_child(row)
|
||||
|
||||
# The choice button above this panel already shows the letter badge and
|
||||
# choice text, so the header only needs a spacer plus the percentage badge.
|
||||
var spacer := Control.new()
|
||||
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
row.add_child(spacer)
|
||||
|
||||
var percentage := _get_choice_selection_percentage(str(state.get("choice_id", "")))
|
||||
if percentage >= 0:
|
||||
var percentage_label := Label.new()
|
||||
percentage_label.text = "%d%%" % percentage
|
||||
percentage_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
percentage_label.custom_minimum_size = Vector2(58, 30)
|
||||
percentage_label.add_theme_stylebox_override("normal", Brand.badge_box(dark, accent))
|
||||
_set_scaled_label(percentage_label, 14, accent)
|
||||
row.add_child(percentage_label)
|
||||
|
||||
|
||||
func _add_followup_body(content: VBoxContainer, is_correct: bool) -> VBoxContainer:
|
||||
var body := PanelContainer.new()
|
||||
body.add_theme_stylebox_override("panel", _followup_body_box(_followup_is_dark(), is_correct))
|
||||
|
||||
Reference in New Issue
Block a user