170 lines
5.9 KiB
GDScript
170 lines
5.9 KiB
GDScript
extends VBoxContainer
|
|
|
|
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
|
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
|
|
|
var main: Control
|
|
var title_label: Label
|
|
var summary_label: Label
|
|
var status_label: Label
|
|
var another_button: Button
|
|
var results_panel: PanelContainer
|
|
var dashboard_button: Button
|
|
var launch_pending := false
|
|
var latest_remaining := 0
|
|
|
|
|
|
func _ready() -> void:
|
|
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
alignment = BoxContainer.ALIGNMENT_CENTER
|
|
add_theme_constant_override("separation", 18)
|
|
UIThemeService.theme_changed.connect(_apply_theme)
|
|
ReviewQueueService.question_loaded.connect(_on_question_loaded)
|
|
ReviewQueueService.question_failed.connect(_on_question_failed)
|
|
ReviewQueueService.pass_completed.connect(_on_pass_completed)
|
|
ReviewQueueService.attempt_synced.connect(_on_attempt_synced)
|
|
|
|
var spacer := Control.new()
|
|
spacer.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|
add_child(spacer)
|
|
results_panel = PanelContainer.new()
|
|
results_panel.custom_minimum_size = Vector2(520, 0)
|
|
results_panel.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
|
add_child(results_panel)
|
|
var content := VBoxContainer.new()
|
|
content.add_theme_constant_override("separation", 16)
|
|
results_panel.add_child(content)
|
|
title_label = _label("Review pass complete", 28, true)
|
|
content.add_child(title_label)
|
|
summary_label = _label("", 17)
|
|
summary_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|
content.add_child(summary_label)
|
|
status_label = _label("", 14)
|
|
status_label.visible = false
|
|
content.add_child(status_label)
|
|
another_button = Button.new()
|
|
another_button.text = "Start Another Review"
|
|
another_button.custom_minimum_size.y = 46
|
|
another_button.pressed.connect(_start_another)
|
|
content.add_child(another_button)
|
|
dashboard_button = Button.new()
|
|
dashboard_button.text = "Back to Dashboard"
|
|
dashboard_button.custom_minimum_size.y = 46
|
|
dashboard_button.pressed.connect(_back_to_dashboard)
|
|
content.add_child(dashboard_button)
|
|
var bottom_spacer := Control.new()
|
|
bottom_spacer.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|
add_child(bottom_spacer)
|
|
_apply_theme()
|
|
|
|
|
|
func on_show(payload: Variant = null) -> void:
|
|
var summary: Dictionary = payload if typeof(payload) == TYPE_DICTIONARY else ReviewQueueService.get_summary()
|
|
var reviewed := int(summary.get("reviewed", 0))
|
|
var cleared := int(summary.get("cleared", 0))
|
|
var remaining := int(summary.get("remaining", 0))
|
|
latest_remaining = remaining
|
|
summary_label.text = "Reviewed %d question%s\nCleared %d from the queue\n%d still need%s review" % [
|
|
reviewed,
|
|
"" if reviewed == 1 else "s",
|
|
cleared,
|
|
remaining,
|
|
"s" if remaining == 1 else ""
|
|
]
|
|
another_button.disabled = remaining <= 0 or ReviewQueueService.has_pending_submissions()
|
|
status_label.text = "Saving your review result..." if ReviewQueueService.has_pending_submissions() else ""
|
|
status_label.visible = not status_label.text.is_empty()
|
|
launch_pending = false
|
|
DashboardService.refresh()
|
|
|
|
|
|
func _start_another() -> void:
|
|
if launch_pending:
|
|
return
|
|
launch_pending = true
|
|
another_button.disabled = true
|
|
status_label.text = "Preparing another review pass..."
|
|
status_label.visible = true
|
|
if not FeatureFlags.progression_enabled():
|
|
ReviewQueueService.start_pass("", 20)
|
|
return
|
|
if not StudySessionService.session_started.is_connected(_on_review_session_started):
|
|
StudySessionService.session_started.connect(_on_review_session_started)
|
|
if not StudySessionService.session_failed.is_connected(_on_review_session_failed):
|
|
StudySessionService.session_failed.connect(_on_review_session_failed)
|
|
StudySessionService.start("due_reviews", 20, "Tutor")
|
|
|
|
|
|
func _on_review_session_started() -> void:
|
|
if launch_pending and visible:
|
|
ReviewQueueService.start_pass("", int(StudySessionService.progress.get("targetValue", 20)))
|
|
|
|
|
|
func _on_review_session_failed(message: String) -> void:
|
|
if launch_pending and visible:
|
|
_on_question_failed(message)
|
|
|
|
|
|
func _on_question_loaded(question: Dictionary) -> void:
|
|
if not launch_pending or not visible:
|
|
return
|
|
launch_pending = false
|
|
if BlockSessionService.start_review_question(question):
|
|
main.show_screen("player")
|
|
else:
|
|
_on_question_failed("The review question could not be prepared.")
|
|
|
|
|
|
func _on_question_failed(message: String) -> void:
|
|
if not launch_pending or not visible:
|
|
return
|
|
launch_pending = false
|
|
another_button.disabled = false
|
|
status_label.text = message
|
|
status_label.visible = true
|
|
|
|
|
|
func _on_pass_completed(summary: Dictionary) -> void:
|
|
if not launch_pending or not visible:
|
|
return
|
|
launch_pending = false
|
|
on_show(summary)
|
|
|
|
|
|
func _on_attempt_synced(_question_id: String, _is_correct: bool, server_pending_count: int) -> void:
|
|
if not visible:
|
|
return
|
|
var summary := ReviewQueueService.get_summary()
|
|
summary["remaining"] = server_pending_count
|
|
on_show(summary)
|
|
|
|
|
|
func _back_to_dashboard() -> void:
|
|
main.show_screen("dashboard")
|
|
|
|
|
|
func _apply_theme(_dark: bool = UIThemeService.is_dark_mode()) -> void:
|
|
var dark := UIThemeService.is_dark_mode()
|
|
if results_panel != null:
|
|
results_panel.add_theme_stylebox_override("panel", Brand.panel_box(dark))
|
|
for label in [title_label, summary_label]:
|
|
if label != null:
|
|
label.add_theme_color_override("font_color", Brand.text_color(dark))
|
|
if status_label != null:
|
|
status_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
|
if another_button != null:
|
|
another_button.add_theme_stylebox_override("normal", Brand.secondary_button_box(dark))
|
|
if dashboard_button != null:
|
|
dashboard_button.add_theme_stylebox_override("normal", Brand.secondary_button_box(dark))
|
|
|
|
|
|
func _label(text: String, font_size: int, bold: bool = false) -> Label:
|
|
var label := Label.new()
|
|
label.text = text
|
|
label.add_theme_font_override("font", Brand.font)
|
|
label.add_theme_font_size_override("font_size", font_size)
|
|
label.add_theme_color_override("font_color", Brand.text_color(UIThemeService.is_dark_mode()))
|
|
if bold:
|
|
label.add_theme_constant_override("outline_size", 0)
|
|
return label
|