feat: 2.3.1

This commit is contained in:
2026-05-11 17:24:47 +08:00
parent 57e56412e0
commit 13f3c3d591
733 changed files with 17957 additions and 798 deletions
+32 -79
View File
@@ -9,31 +9,28 @@ signal closed
# Tab buttons
@onready var _search_tab_btn: Button = %SearchTabBtn
@onready var _requests_tab_btn: Button = %RequestsTabBtn
@onready var _friends_tab_btn: Button = %FriendsTabBtn
@onready var _dm_tab_btn: Button = %DMTabBtn
@onready var _dm_tab_btn: Button = get_node_or_null("%DMTabBtn")
# Views
@onready var _search_view: VBoxContainer = %SearchView
@onready var _requests_view: VBoxContainer = %RequestsView
@onready var _friends_view: VBoxContainer = %FriendsView
@onready var _dm_view: VBoxContainer = %DMView
@onready var _dm_view: PanelContainer = %DMView
# Search tab nodes
@onready var _search_input: LineEdit = %SearchInput
@onready var _search_btn: Button = %SearchBtn
@onready var _no_search_results: Label = %NoSearchResultsLabel
@onready var _search_results_list: VBoxContainer = %SearchResultsList
@onready var _search_result_tmpl: HBoxContainer = %SearchResultTemplate
@onready var _search_results_list: GridContainer = %SearchResultsList
# Requests tab nodes
@onready var _no_requests_label: Label = %NoRequestsLabel
@onready var _requests_list: VBoxContainer = %RequestsList
@onready var _request_row_tmpl: HBoxContainer = %RequestRowTemplate
# Friends tab nodes
@onready var _no_friends_label: Label = %NoFriendsLabel
@onready var _friend_list: VBoxContainer = %FriendList
@onready var _friend_list: GridContainer = %FriendList
# DM tab nodes
@onready var _dm_back_btn: Button = %DMBackBtn
@@ -53,10 +50,12 @@ func _ready() -> void:
# Tab buttons
_search_tab_btn.pressed.connect(func(): _show_tab("search"))
_requests_tab_btn.pressed.connect(func(): _show_tab("requests"))
_friends_tab_btn.pressed.connect(func(): _show_tab("friends"))
if _dm_tab_btn:
_dm_tab_btn.pressed.connect(func(): _show_tab("dm"))
_dm_back_btn.pressed.connect(func(): _show_tab("friends"))
# Search
_search_btn.pressed.connect(_on_search_pressed)
_search_input.text_submitted.connect(func(_t): _on_search_pressed())
@@ -81,7 +80,6 @@ func _ready() -> void:
func _show_tab(tab: String) -> void:
_current_tab = tab
_search_view.visible = tab == "search"
_requests_view.visible = tab == "requests"
_friends_view.visible = tab == "friends"
_dm_view.visible = tab == "dm"
@@ -121,60 +119,26 @@ func _populate_search_results(users: Array) -> void:
_no_search_results.visible = users.is_empty()
var my_id = NakamaManager.session.user_id if NakamaManager.session else ""
var friend_row_scene := preload("res://scenes/ui/friend_row.tscn")
for u in users:
if u.user_id == my_id:
continue # skip self
var row: HBoxContainer = _search_result_tmpl.duplicate()
row.show()
row.get_node("SRNameLabel").text = u.display_name + " (@" + u.username + ")"
var add_btn: Button = row.get_node("SRAddBtn")
add_btn.pressed.connect(func():
FriendManager.add_friend_by_id(u.user_id)
add_btn.text = "Sent ✓"
add_btn.disabled = true
)
var row: Control = friend_row_scene.instantiate()
_search_results_list.add_child(row)
row.setup(u.user_id, u.username, -1, self)
# ─── Requests Tab ────────────────────────────────────────────────────────────
func _populate_requests(incoming: Array) -> void:
for ch in _requests_list.get_children():
ch.queue_free()
_no_requests_label.visible = incoming.is_empty()
for f in incoming:
var row: HBoxContainer = _request_row_tmpl.duplicate()
row.show()
row.get_node("RRNameLabel").text = f.username
var accept_btn: Button = row.get_node("RRAcceptBtn")
var decline_btn: Button = row.get_node("RRDeclineBtn")
var uid: String = f.user_id
accept_btn.pressed.connect(func():
FriendManager.add_friend_by_id(uid)
row.queue_free()
)
decline_btn.pressed.connect(func():
FriendManager.remove_friend(uid)
row.queue_free()
)
_requests_list.add_child(row)
# Badge on tab button
if incoming.is_empty():
_requests_tab_btn.text = "Requests"
else:
_requests_tab_btn.text = "Requests (%d)" % incoming.size()
# ─── Friends Tab ─────────────────────────────────────────────────────────────
func _populate_friends(mutual: Array) -> void:
func _populate_friends(friends_array: Array) -> void:
for ch in _friend_list.get_children():
ch.queue_free()
_no_friends_label.visible = mutual.is_empty()
_no_friends_label.visible = friends_array.is_empty()
var friend_row_scene := preload("res://scenes/ui/friend_row.tscn")
for f in mutual:
for f in friends_array:
var row: Control = friend_row_scene.instantiate()
_friend_list.add_child(row)
row.setup(f.user_id, f.username, f.state, self)
@@ -182,35 +146,24 @@ func _populate_friends(mutual: Array) -> void:
# ─── FriendManager Callbacks ─────────────────────────────────────────────────
func _on_friends_updated(friends: Array) -> void:
print("[SocialPanel] _on_friends_updated: total=%d" % friends.size())
var incoming := friends.filter(func(f): return f.state == FriendManager.STATE_INVITE_IN)
var mutual := friends.filter(func(f): return f.state == FriendManager.STATE_FRIEND)
print("[SocialPanel] incoming=%d mutual=%d" % [incoming.size(), mutual.size()])
_populate_requests(incoming)
_populate_friends(mutual)
# Pass both incoming and mutual friends to the friends list
var display_list := friends.filter(func(f): return f.state == FriendManager.STATE_INVITE_IN or f.state == FriendManager.STATE_FRIEND)
# Also update the badge on the Friends tab if there are incoming requests
var incoming_count = friends.filter(func(f): return f.state == FriendManager.STATE_INVITE_IN).size()
if incoming_count > 0:
_friends_tab_btn.text = "FRIENDS (%d)" % incoming_count
else:
_friends_tab_btn.text = "FRIENDS"
_populate_friends(display_list)
signal dm_requested(user_id: String, username: String)
# ─── DM ──────────────────────────────────────────────────────────────────────
func open_dm(user_id: String, username: String) -> void:
_active_dm_user_id = user_id
_dm_username_label.text = "DM: %s" % username
_dm_tab_btn.visible = true
_dm_log.clear()
_show_tab("dm")
_dm_log.append_text("[i]Loading history...[/i]\n")
var history = await FriendManager.get_dm_history(user_id)
_dm_log.clear()
_dm_history[user_id] = []
var my_id = NakamaManager.session.user_id if NakamaManager.session else ""
for entry in history:
var is_self = entry.get("from") == my_id
var sender_name = "You" if is_self else username
_dm_history[user_id].append({"from": "me" if is_self else entry.get("from"), "msg": entry.get("msg")})
_dm_log.append_text("[b]%s:[/b] %s\n" % [sender_name, entry.get("msg", "")])
FriendManager.open_dm(user_id)
emit_signal("dm_requested", user_id, username)
func _send_dm() -> void:
var text = _dm_input.text.strip_edges()