116 lines
5.0 KiB
GDScript
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
|