Files
step3/scripts/ui/session_summary.gd

116 lines
5.0 KiB
GDScript

extends VBoxContainer
const Brand := preload("res://scripts/ui/medmind_style.gd")
var main: Control
var current_summary: Dictionary = {}
var content: VBoxContainer
var continue_pending := false
func _ready() -> void:
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
alignment = BoxContainer.ALIGNMENT_CENTER
content = VBoxContainer.new()
content.custom_minimum_size = Vector2(420, 0)
content.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
content.add_theme_constant_override("separation", 14)
add_child(content)
StudySessionService.session_started.connect(_on_continuation_started)
UIThemeService.theme_changed.connect(func(_dark: bool): _render())
func on_show(payload: Variant = null) -> void:
current_summary = payload if typeof(payload) == TYPE_DICTIONARY else StudySessionService.summary
continue_pending = false
_render()
func _render() -> void:
for child in content.get_children():
child.queue_free()
var dark := UIThemeService.is_dark_mode()
var completed := str(current_summary.get("state", "")) == "completed"
content.add_child(_label("Session complete" if completed else "Session ended", 30, Brand.SUCCESS if completed else Brand.AMBER))
var questions := int(current_summary.get("questionsCompleted", 0))
var accuracy := int(current_summary.get("accuracy", 0))
var elapsed := int(current_summary.get("elapsedSeconds", 0))
var detail := "Questions completed: %d\nFirst-attempt accuracy: %d%%\nStudy time: %d min %02d sec" % [
questions, accuracy, elapsed / 60, elapsed % 60]
if int(current_summary.get("reviewsCompleted", 0)) > 0:
detail += "\nScheduled reviews: %d · Recovered: %d" % [current_summary.get("reviewsCompleted", 0), current_summary.get("recovered", 0)]
var mastery_change: Variant = current_summary.get("masteryScoreChange", null)
if mastery_change != null:
detail += "\n%s mastery: %+d points (%s → %s)" % [
str(current_summary.get("step3System", "System")), int(mastery_change),
str(current_summary.get("initialMasteryState", "")), str(current_summary.get("finalMasteryState", ""))]
detail += "\nRZ Coins earned: %d" % int(current_summary.get("coinsEarned", 0))
var award_lines: Array[String] = []
for award in current_summary.get("coinAwards", []):
if typeof(award) == TYPE_DICTIONARY:
award_lines.append("+%d %s" % [int(award.get("amount", 0)), str(award.get("description", "RZ Coin award"))])
if not award_lines.is_empty():
detail += "\nAwards: %s" % "; ".join(award_lines)
var body := _label(detail, 17, Brand.text_color(dark))
body.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
content.add_child(body)
var readiness := _label(str(current_summary.get("readinessExplanation", "A completed exam simulation is required to update readiness.")), 13, Brand.muted_color(dark))
readiness.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
content.add_child(readiness)
var recommendation := _label(_recommendation(), 15, Brand.SKY_BLUE)
recommendation.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
content.add_child(recommendation)
var actions := HBoxContainer.new()
actions.add_theme_constant_override("separation", 12)
var finish := Button.new()
finish.text = "Finish for today"
finish.custom_minimum_size = Vector2(220, 52)
finish.size_flags_horizontal = Control.SIZE_EXPAND_FILL
finish.pressed.connect(func(): DashboardService.refresh(); main.show_screen("dashboard"))
actions.add_child(finish)
var continue_button := Button.new()
continue_button.text = "Continue with another block"
continue_button.custom_minimum_size = Vector2(220, 52)
continue_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
continue_button.pressed.connect(_continue)
actions.add_child(continue_button)
content.add_child(actions)
func _continue() -> void:
var goal := str(current_summary.get("goalType", "question_count"))
if goal == "simulation_block":
main.show_screen("simulation_break")
return
if goal == "due_reviews":
continue_pending = true
StudySessionService.start("due_reviews", 20, "Tutor", str(current_summary.get("step3System", "")))
return
main.show_screen("setup", {
"step3_system": str(current_summary.get("step3System", "All Systems")),
"question_count": int(current_summary.get("targetValue", 10)),
"goal_type": goal
})
func _on_continuation_started() -> void:
if continue_pending and visible:
continue_pending = false
ReviewQueueService.start_pass(str(current_summary.get("step3System", "")),
int(StudySessionService.progress.get("targetValue", 20)))
func _recommendation() -> String:
if int(current_summary.get("recovered", 0)) > 0:
return "Recommended next session: reinforce another weak system or complete the next scheduled reviews."
return "Recommended next session: continue the same goal, or finish for today and return refreshed."
func _label(text: String, size: int, color: Color) -> Label:
var label := Label.new()
label.text = text
label.add_theme_font_override("font", Brand.font)
label.add_theme_font_size_override("font_size", size)
label.add_theme_color_override("font_color", color)
return label