Add clinical progression ranks and records
This commit is contained in:
@@ -21,6 +21,7 @@ var outcome_delete: Button
|
||||
var connected_accounts_list: VBoxContainer
|
||||
var return_screen := ""
|
||||
var back_to_session_button: Button
|
||||
var progression_content: VBoxContainer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -95,6 +96,7 @@ func _build() -> void:
|
||||
right.add_theme_constant_override("separation", 14)
|
||||
columns.add_child(right)
|
||||
right.add_child(_outcome_card())
|
||||
right.add_child(_progression_card())
|
||||
right.add_child(_connected_accounts_card())
|
||||
right.add_child(_account_actions_card())
|
||||
_refresh_back_to_session_visibility()
|
||||
@@ -227,6 +229,13 @@ func _outcome_card() -> PanelContainer:
|
||||
return _card(body)
|
||||
|
||||
|
||||
func _progression_card() -> PanelContainer:
|
||||
progression_content = VBoxContainer.new()
|
||||
progression_content.add_theme_constant_override("separation", 10)
|
||||
progression_content.add_child(_section_header("Clinical Progression", "Breadth, challenge, and retention"))
|
||||
return _card(progression_content)
|
||||
|
||||
|
||||
func _account_actions_card() -> PanelContainer:
|
||||
var body := VBoxContainer.new()
|
||||
body.add_theme_constant_override("separation", 9)
|
||||
@@ -279,9 +288,73 @@ func _render() -> void:
|
||||
_set_metric("cases", str(int(data.get("ccsCasesCompleted", 0))))
|
||||
_set_metric("streak", "%d days" % int(data.get("currentStreak", 0)))
|
||||
_render_systems(data.get("systems", []))
|
||||
_render_progression(data.get("progression", {}))
|
||||
_render_outcome()
|
||||
|
||||
|
||||
func _render_progression(value: Variant) -> void:
|
||||
if progression_content == null:
|
||||
return
|
||||
_clear(progression_content)
|
||||
progression_content.add_child(_section_header("Clinical Progression", "Breadth, challenge, and retention"))
|
||||
var progression: Dictionary = value if typeof(value) == TYPE_DICTIONARY else {}
|
||||
if progression.is_empty():
|
||||
progression_content.add_child(_label("Loading progression...", 13, Brand.muted_color(_dark())))
|
||||
return
|
||||
progression_content.add_child(_label(str(progression.get("displayName", "Case Scout III")), 24, Brand.PURPLE, true))
|
||||
var badges: Array = progression.get("earnedBadges", [])
|
||||
progression_content.add_child(_label("Earned: %s" % ", ".join(PackedStringArray(badges)), 12, Brand.muted_color(_dark())))
|
||||
var ladder := GridContainer.new()
|
||||
ladder.columns = 3
|
||||
ladder.add_theme_constant_override("h_separation", 7)
|
||||
ladder.add_theme_constant_override("v_separation", 7)
|
||||
var rank_names := ["Case Scout", "Pattern Hunter", "Diagnostic Tactician", "Management Strategist", "Clinical Vanguard"]
|
||||
var divisions := ["III", "II", "I"]
|
||||
var earned_ordinal := int(progression.get("rankOrdinal", 0))
|
||||
var earned_dates: Dictionary = progression.get("earnedRanksUtc", {})
|
||||
var ladder_data: Array = progression.get("ladder", [])
|
||||
for ordinal in 15:
|
||||
var earned := ordinal <= earned_ordinal
|
||||
var caption := "%s %s" % [rank_names[floori(float(ordinal) / 3.0)], divisions[ordinal % 3]]
|
||||
var date := str(earned_dates.get(str(ordinal), "")).left(10)
|
||||
if earned and not date.is_empty():
|
||||
caption += "\n%s" % date
|
||||
var cell := _label(caption, 10, Brand.SUCCESS if earned else Brand.muted_color(_dark()), earned)
|
||||
cell.custom_minimum_size = Vector2(105, 38)
|
||||
cell.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
cell.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
if ordinal < ladder_data.size() and typeof(ladder_data[ordinal]) == TYPE_DICTIONARY:
|
||||
cell.tooltip_text = str((ladder_data[ordinal] as Dictionary).get("requirementSummary", ""))
|
||||
ladder.add_child(cell)
|
||||
progression_content.add_child(ladder)
|
||||
var next_name = progression.get("nextRankName")
|
||||
if next_name != null:
|
||||
progression_content.add_child(_label("Next: %s %s" % [str(next_name), str(progression.get("nextDivision", ""))], 14, Brand.text_color(_dark()), true))
|
||||
for requirement_value in progression.get("nextRequirements", []):
|
||||
var requirement: Dictionary = requirement_value
|
||||
var row := HBoxContainer.new()
|
||||
var text := _label(str(requirement.get("label", "Requirement")), 11, Brand.text_color(_dark()))
|
||||
text.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
row.add_child(text)
|
||||
row.add_child(_label("%d / %d" % [int(requirement.get("current", 0)), int(requirement.get("required", 0))], 11,
|
||||
Brand.SUCCESS if bool(requirement.get("complete", false)) else Brand.ROYAL_BLUE, true))
|
||||
progression_content.add_child(row)
|
||||
progression_content.add_child(HSeparator.new())
|
||||
progression_content.add_child(_label("Personal records", 15, Brand.text_color(_dark()), true))
|
||||
for record_value in progression.get("records", []):
|
||||
var record: Dictionary = record_value
|
||||
var suffix := "%d%%" % int(record.get("value", 0)) if str(record.get("key", "")) == "timed_block" else str(int(record.get("value", 0)))
|
||||
var title := _label("%s %s" % [str(record.get("label", "Record")), suffix], 12, Brand.text_color(_dark()), true)
|
||||
title.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
progression_content.add_child(title)
|
||||
var definition := str(record.get("definition", ""))
|
||||
if bool(record.get("trackingFromLaunch", false)):
|
||||
definition += " Tracking since %s." % str(progression.get("trackingStartedUtc", "")).left(10)
|
||||
var detail := _label(definition, 10, Brand.muted_color(_dark()))
|
||||
detail.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
progression_content.add_child(detail)
|
||||
|
||||
|
||||
func _render_connected_accounts(provider_values: Variant, available_values: Variant) -> void:
|
||||
if connected_accounts_list == null:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user