Adds a server-computed tier/division (Bronze..Diamond, III-I) to the ratings profile endpoint and surfaces it next to the numeric ELO in the shared header badge, matching the coin balance display already there.
167 lines
6.2 KiB
GDScript
167 lines
6.2 KiB
GDScript
extends PanelContainer
|
|
|
|
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
|
const SHIELD_ICON := preload("res://assets/icons/lucide/shield.svg")
|
|
const STAR_ICON := preload("res://assets/icons/lucide/star.svg")
|
|
const CHEVRON_ICON := preload("res://assets/icons/lucide/chevron-down.svg")
|
|
|
|
var rank_icon_panel: PanelContainer
|
|
var rank_icon_texture: TextureRect
|
|
var rank_tier_label: Label
|
|
var rank_elo_label: Label
|
|
var divider: ColorRect
|
|
|
|
var icon_panel: PanelContainer
|
|
var icon_texture: TextureRect
|
|
var value_label: Label
|
|
var caption_label: Label
|
|
var displayed_value := 0
|
|
var _initialized := false
|
|
|
|
|
|
func _ready() -> void:
|
|
custom_minimum_size = Vector2(230, 44)
|
|
size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
_build_ui()
|
|
refresh_theme_controls()
|
|
_on_credits_changed()
|
|
_on_ratings_changed()
|
|
CreditsService.credits_changed.connect(_on_credits_changed)
|
|
QuestionBankService.ratings_changed.connect(_on_ratings_changed)
|
|
resized.connect(func(): pivot_offset = size * 0.5)
|
|
|
|
|
|
func _build_ui() -> void:
|
|
var margin := MarginContainer.new()
|
|
margin.add_theme_constant_override("margin_left", 10)
|
|
margin.add_theme_constant_override("margin_right", 10)
|
|
margin.add_theme_constant_override("margin_top", 6)
|
|
margin.add_theme_constant_override("margin_bottom", 6)
|
|
add_child(margin)
|
|
|
|
var row := HBoxContainer.new()
|
|
row.add_theme_constant_override("separation", 8)
|
|
margin.add_child(row)
|
|
|
|
rank_icon_panel = PanelContainer.new()
|
|
rank_icon_panel.custom_minimum_size = Vector2(28, 28)
|
|
rank_icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
rank_icon_texture = TextureRect.new()
|
|
rank_icon_texture.texture = SHIELD_ICON
|
|
rank_icon_texture.custom_minimum_size = Vector2(16, 16)
|
|
rank_icon_texture.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
|
rank_icon_texture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
rank_icon_panel.add_child(rank_icon_texture)
|
|
row.add_child(rank_icon_panel)
|
|
|
|
var rank_copy := VBoxContainer.new()
|
|
rank_copy.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
rank_copy.add_theme_constant_override("separation", 0)
|
|
rank_tier_label = Label.new()
|
|
rank_tier_label.add_theme_font_override("font", Brand.font)
|
|
rank_tier_label.add_theme_font_size_override("font_size", 15)
|
|
rank_copy.add_child(rank_tier_label)
|
|
rank_elo_label = Label.new()
|
|
rank_elo_label.add_theme_font_override("font", Brand.font)
|
|
rank_elo_label.add_theme_font_size_override("font_size", 10)
|
|
rank_copy.add_child(rank_elo_label)
|
|
row.add_child(rank_copy)
|
|
|
|
divider = ColorRect.new()
|
|
divider.custom_minimum_size = Vector2(1, 26)
|
|
divider.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
row.add_child(divider)
|
|
|
|
icon_panel = PanelContainer.new()
|
|
icon_panel.custom_minimum_size = Vector2(28, 28)
|
|
icon_panel.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
icon_texture = TextureRect.new()
|
|
icon_texture.texture = STAR_ICON
|
|
icon_texture.custom_minimum_size = Vector2(16, 16)
|
|
icon_texture.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
|
icon_texture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
icon_panel.add_child(icon_texture)
|
|
row.add_child(icon_panel)
|
|
|
|
var copy := VBoxContainer.new()
|
|
copy.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
copy.add_theme_constant_override("separation", 0)
|
|
value_label = Label.new()
|
|
value_label.add_theme_font_override("font", Brand.font)
|
|
value_label.add_theme_font_size_override("font_size", 15)
|
|
copy.add_child(value_label)
|
|
caption_label = Label.new()
|
|
caption_label.text = "RZ Points"
|
|
caption_label.add_theme_font_override("font", Brand.font)
|
|
caption_label.add_theme_font_size_override("font_size", 10)
|
|
copy.add_child(caption_label)
|
|
row.add_child(copy)
|
|
|
|
var chevron := TextureRect.new()
|
|
chevron.texture = CHEVRON_ICON
|
|
chevron.custom_minimum_size = Vector2(14, 14)
|
|
chevron.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
|
chevron.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
chevron.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
chevron.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
|
row.add_child(chevron)
|
|
|
|
|
|
func refresh_theme_controls() -> void:
|
|
var dark := UIThemeService.is_dark_mode()
|
|
add_theme_stylebox_override("panel", Brand.content_card_box(dark, true, Brand.ROYAL_BLUE))
|
|
rank_icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.ROYAL_BLUE, 14))
|
|
rank_icon_texture.modulate = Brand.ROYAL_BLUE
|
|
rank_tier_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
|
rank_elo_label.add_theme_color_override("font_color", Brand.ROYAL_BLUE)
|
|
divider.color = Color("2a365a") if dark else Brand.LIGHT_BORDER
|
|
icon_panel.add_theme_stylebox_override("panel", Brand.icon_circle_box(dark, Brand.AMBER, 14))
|
|
icon_texture.modulate = Brand.AMBER
|
|
value_label.add_theme_color_override("font_color", Brand.text_color(dark))
|
|
caption_label.add_theme_color_override("font_color", Brand.muted_color(dark))
|
|
|
|
|
|
func bump() -> void:
|
|
var tween := create_tween()
|
|
tween.tween_property(self, "scale", Vector2(1.12, 1.12), 0.12).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
|
|
tween.tween_property(self, "scale", Vector2.ONE, 0.18).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
|
|
|
|
|
|
func _on_ratings_changed() -> void:
|
|
var roman := {1: "I", 2: "II", 3: "III"}
|
|
var division_label: String = roman.get(QuestionBankService.rank_division, "")
|
|
rank_tier_label.text = "%s %s" % [QuestionBankService.rank_tier, division_label]
|
|
rank_elo_label.text = "%d ELO" % QuestionBankService.overall_elo
|
|
|
|
|
|
func _on_credits_changed() -> void:
|
|
if not CreditsService.loaded:
|
|
_initialized = false
|
|
displayed_value = 0
|
|
value_label.text = "--"
|
|
return
|
|
if not _initialized:
|
|
_initialized = true
|
|
displayed_value = CreditsService.credits
|
|
value_label.text = _format_thousands(displayed_value)
|
|
return
|
|
var tween := create_tween()
|
|
tween.tween_method(_set_displayed_value, displayed_value, CreditsService.credits, 0.5).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
|
|
|
|
|
func _set_displayed_value(value: int) -> void:
|
|
displayed_value = value
|
|
value_label.text = _format_thousands(value)
|
|
|
|
|
|
func _format_thousands(value: int) -> String:
|
|
var digits := str(absi(value))
|
|
var grouped := ""
|
|
var count := 0
|
|
for index in range(digits.length() - 1, -1, -1):
|
|
grouped = digits[index] + grouped
|
|
count += 1
|
|
if count % 3 == 0 and index != 0:
|
|
grouped = "," + grouped
|
|
return ("-" if value < 0 else "") + grouped
|