extends Control const AUTH_LOGOUT_URL := "https://pauth.ranaze.com/api/Auth/logout" @onready var _status_label: Label = %StatusLabel @onready var _character_list: ItemList = %CharacterList @onready var _name_input: LineEdit = %NameInput @onready var _logout_request: HTTPRequest = %LogoutRequest var _characters: Array = [] func _ready() -> void: if not AuthState.is_logged_in: get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn") return _load_characters() func _log_failure(action: String, response: Dictionary) -> void: push_warning("%s failed: status=%s error=%s body=%s" % [ action, response.get("status", "n/a"), response.get("error", ""), response.get("body", "") ]) func _load_characters() -> void: _status_label.text = "Loading characters..." var response := await CharacterService.list_characters() if not response.get("ok", false): _log_failure("List characters", response) _status_label.text = "Failed to load characters." return var parsed: Variant = JSON.parse_string(String(response.get("body", ""))) if typeof(parsed) != TYPE_ARRAY: _status_label.text = "Unexpected character response." return _characters = parsed _character_list.clear() for character in _characters: var character_name := String(character.get("name", "Unnamed")) _character_list.add_item(character_name) if _characters.is_empty(): _status_label.text = "No characters yet. Add one below." else: _status_label.text = "" func _on_add_button_pressed() -> void: var character_name := _name_input.text.strip_edges() if character_name.is_empty(): _status_label.text = "Enter a character name first." return _status_label.text = "Creating character..." var response := await CharacterService.create_character(character_name) if not response.get("ok", false): _log_failure("Create character", response) _status_label.text = "Failed to create character." return var parsed: Variant = JSON.parse_string(String(response.get("body", ""))) if typeof(parsed) == TYPE_DICTIONARY: _characters.append(parsed) _character_list.add_item(String(parsed.get("name", character_name))) _name_input.text = "" _status_label.text = "Character added." else: _status_label.text = "Character created, but response was unexpected." func _on_delete_button_pressed() -> void: var selected := _character_list.get_selected_items() if selected.is_empty(): _status_label.text = "Select a character to delete." return var index := selected[0] if index < 0 or index >= _characters.size(): _status_label.text = "Invalid selection." return var character: Dictionary = _characters[index] var character_id := String(character.get("id", character.get("Id", ""))) if character_id.is_empty(): _status_label.text = "Missing character id." return _status_label.text = "Deleting character..." var response := await CharacterService.delete_character(character_id) if not response.get("ok", false): _log_failure("Delete character", response) _status_label.text = "Failed to delete character." return _characters.remove_at(index) _character_list.remove_item(index) _status_label.text = "Character deleted." func _on_refresh_button_pressed() -> void: _load_characters() func _on_back_button_pressed() -> void: get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn") func _on_logout_button_pressed() -> void: _request_logout() func _request_logout() -> void: if AuthState.access_token.is_empty(): AuthState.clear_session() get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn") return var headers := PackedStringArray([ "Authorization: Bearer %s" % AuthState.access_token, ]) var err := _logout_request.request(AUTH_LOGOUT_URL, headers, HTTPClient.METHOD_POST) if err != OK: push_warning("Failed to send logout request: %s" % err) AuthState.clear_session() get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn") func _on_logout_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void: var body_text := body.get_string_from_utf8() if result != HTTPRequest.RESULT_SUCCESS or response_code < 200 or response_code >= 300: push_warning("Logout failed (%s/%s): %s" % [result, response_code, body_text]) AuthState.clear_session() get_tree().change_scene_to_file("res://scenes/UI/start_screen.tscn")