The panel's shared Brand.panel_box background is ~80% opaque, which compounded with the dialog's own dim backdrop let the screen behind show through and washed out the card against it. Force full opacity on this dialog's panel specifically, since other panel_box overlays still rely on the shared translucency.
183 lines
5.7 KiB
GDScript
183 lines
5.7 KiB
GDScript
extends Control
|
|
|
|
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
|
|
|
signal logout_requested
|
|
|
|
var panel: PanelContainer
|
|
var title_label: Label
|
|
var message_label: Label
|
|
var error_label: Label
|
|
var stay_button: Button
|
|
var logout_button: Button
|
|
|
|
|
|
func _ready() -> void:
|
|
visible = false
|
|
top_level = true
|
|
mouse_filter = Control.MOUSE_FILTER_STOP
|
|
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
_build_ui()
|
|
AuthState.session_warning.connect(_show_warning)
|
|
AuthState.session_countdown_changed.connect(_update_countdown)
|
|
AuthState.session_refresh_started.connect(_refresh_started)
|
|
AuthState.session_refreshed.connect(_refresh_succeeded)
|
|
AuthState.session_refresh_failed.connect(_refresh_failed)
|
|
UIThemeService.theme_changed.connect(func(_dark: bool): _apply_theme())
|
|
resized.connect(_refresh_size)
|
|
_refresh_size()
|
|
_apply_theme()
|
|
|
|
|
|
func _build_ui() -> void:
|
|
var dim := ColorRect.new()
|
|
dim.color = Color(0, 0, 0, 0.74)
|
|
dim.mouse_filter = Control.MOUSE_FILTER_STOP
|
|
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
add_child(dim)
|
|
|
|
var center := CenterContainer.new()
|
|
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
add_child(center)
|
|
|
|
panel = PanelContainer.new()
|
|
panel.custom_minimum_size = Vector2(520, 280)
|
|
center.add_child(panel)
|
|
|
|
var content := VBoxContainer.new()
|
|
content.add_theme_constant_override("separation", 16)
|
|
panel.add_child(content)
|
|
|
|
title_label = Label.new()
|
|
title_label.text = "Stay logged in?"
|
|
title_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
title_label.add_theme_font_size_override("font_size", 28)
|
|
content.add_child(title_label)
|
|
|
|
message_label = Label.new()
|
|
message_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
message_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|
message_label.add_theme_font_size_override("font_size", 17)
|
|
content.add_child(message_label)
|
|
|
|
error_label = Label.new()
|
|
error_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
error_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|
error_label.add_theme_font_size_override("font_size", 14)
|
|
content.add_child(error_label)
|
|
|
|
var actions := HBoxContainer.new()
|
|
actions.add_theme_constant_override("separation", 12)
|
|
content.add_child(actions)
|
|
|
|
logout_button = Button.new()
|
|
logout_button.text = "Log out"
|
|
logout_button.custom_minimum_size = Vector2(150, 48)
|
|
logout_button.pressed.connect(_request_logout)
|
|
actions.add_child(logout_button)
|
|
|
|
stay_button = Button.new()
|
|
stay_button.text = "Stay logged in"
|
|
stay_button.custom_minimum_size = Vector2(0, 48)
|
|
stay_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
stay_button.pressed.connect(AuthState.request_session_refresh)
|
|
actions.add_child(stay_button)
|
|
|
|
|
|
func _show_warning(seconds_remaining: int) -> void:
|
|
error_label.text = ""
|
|
stay_button.disabled = false
|
|
logout_button.disabled = false
|
|
stay_button.text = "Stay logged in"
|
|
visible = true
|
|
_update_countdown(seconds_remaining)
|
|
move_to_front()
|
|
BlockSessionService.pause_current_question_timer()
|
|
|
|
|
|
func _update_countdown(seconds_remaining: int) -> void:
|
|
if not visible:
|
|
return
|
|
var minutes := floori(float(seconds_remaining) / 60.0)
|
|
var seconds := seconds_remaining % 60
|
|
message_label.text = "Your session expires in %02d:%02d. Renew it to continue studying." % [minutes, seconds]
|
|
|
|
|
|
func _refresh_started() -> void:
|
|
if not visible:
|
|
return
|
|
stay_button.disabled = true
|
|
logout_button.disabled = true
|
|
stay_button.text = "Renewing..."
|
|
error_label.text = ""
|
|
|
|
|
|
func _refresh_succeeded() -> void:
|
|
_hide_dialog()
|
|
|
|
|
|
func _refresh_failed(message: String, terminal: bool) -> void:
|
|
if not visible:
|
|
return
|
|
error_label.text = message
|
|
stay_button.text = "Stay logged in"
|
|
stay_button.disabled = terminal
|
|
logout_button.disabled = false
|
|
|
|
|
|
func _request_logout() -> void:
|
|
logout_requested.emit()
|
|
|
|
|
|
func _hide_dialog() -> void:
|
|
visible = false
|
|
error_label.text = ""
|
|
stay_button.text = "Stay logged in"
|
|
stay_button.disabled = false
|
|
logout_button.disabled = false
|
|
BlockSessionService.resume_current_question_timer()
|
|
|
|
|
|
func dismiss_for_logout() -> void:
|
|
if visible:
|
|
_hide_dialog()
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if visible and event.is_action_pressed("ui_cancel"):
|
|
get_viewport().set_input_as_handled()
|
|
|
|
|
|
func _refresh_size() -> void:
|
|
if panel == null:
|
|
return
|
|
panel.custom_minimum_size = Vector2(
|
|
minf(520.0, maxf(288.0, size.x - 32.0)),
|
|
minf(280.0, maxf(250.0, size.y - 32.0)))
|
|
|
|
|
|
func _apply_theme() -> void:
|
|
if panel == null:
|
|
return
|
|
var dark := UIThemeService.is_dark_mode()
|
|
var panel_style := Brand.panel_box(dark)
|
|
panel_style.bg_color.a = 1.0
|
|
panel_style.content_margin_left = 32
|
|
panel_style.content_margin_right = 32
|
|
panel_style.content_margin_top = 30
|
|
panel_style.content_margin_bottom = 30
|
|
panel.add_theme_stylebox_override("panel", panel_style)
|
|
for label in [title_label, message_label]:
|
|
label.add_theme_color_override("font_color", Brand.text_color(dark))
|
|
error_label.add_theme_color_override("font_color", Color("fb7185") if dark else Color("be123c"))
|
|
stay_button.add_theme_stylebox_override("normal", Brand.gradient_button_box())
|
|
stay_button.add_theme_stylebox_override("hover", Brand.gradient_button_box())
|
|
stay_button.add_theme_stylebox_override("pressed", Brand.gradient_button_box())
|
|
stay_button.add_theme_color_override("font_color", Color.WHITE)
|
|
stay_button.add_theme_color_override("font_hover_color", Color.WHITE)
|
|
logout_button.add_theme_stylebox_override("normal", Brand.secondary_button_box(dark))
|
|
logout_button.add_theme_stylebox_override("hover", Brand.secondary_button_box(dark, true))
|
|
logout_button.add_theme_stylebox_override("pressed", Brand.secondary_button_box(dark, true))
|
|
logout_button.add_theme_color_override("font_color", Brand.text_color(dark))
|
|
logout_button.add_theme_color_override("font_hover_color", Brand.text_color(dark))
|