forked from datawhale/whale-town-front
修bug
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
extends Panel
|
||||
extends PanelContainer
|
||||
|
||||
# ============================================================================
|
||||
# ChatMessage.gd - 聊天消息气泡组件
|
||||
@@ -49,22 +49,25 @@ var user_info_container: HBoxContainer
|
||||
# ============================================================================
|
||||
|
||||
func _ready() -> void:
|
||||
# 使用 get_node 获取节点引用
|
||||
username_label = get_node_or_null("VBoxContainer/UserInfoContainer/UsernameLabel")
|
||||
timestamp_label = get_node_or_null("VBoxContainer/UserInfoContainer/TimestampLabel")
|
||||
content_label = get_node_or_null("VBoxContainer/ContentLabel")
|
||||
user_info_container = get_node_or_null("VBoxContainer/UserInfoContainer")
|
||||
|
||||
# 调试输出
|
||||
if username_label:
|
||||
print("✅ UsernameLabel found")
|
||||
else:
|
||||
print("❌ UsernameLabel NOT found!")
|
||||
# 打印所有子节点帮助调试
|
||||
print("Available children: ", _get_all_children_names(self))
|
||||
|
||||
# 应用最大宽度限制
|
||||
custom_minimum_size.x = min(max_width, get_parent().size.x)
|
||||
_cache_node_refs()
|
||||
|
||||
func _cache_node_refs() -> void:
|
||||
if not username_label:
|
||||
username_label = get_node_or_null("VBoxContainer/UserInfoContainer/UsernameLabel")
|
||||
if not timestamp_label:
|
||||
timestamp_label = get_node_or_null("VBoxContainer/UserInfoContainer/TimestampLabel")
|
||||
if not content_label:
|
||||
content_label = get_node_or_null("VBoxContainer/ContentLabel")
|
||||
if not user_info_container:
|
||||
user_info_container = get_node_or_null("VBoxContainer/UserInfoContainer")
|
||||
|
||||
# 内容换行与自适应高度
|
||||
if content_label:
|
||||
content_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
content_label.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
content_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
content_label.fit_content = true
|
||||
content_label.scroll_active = false
|
||||
|
||||
# ============================================================================
|
||||
# 成员变量
|
||||
@@ -89,10 +92,15 @@ var _is_self: bool = false
|
||||
# message.set_message("Alice", "Hello!", 1703500800.0, false)
|
||||
func set_message(from_user: String, content: String, timestamp: float, is_self: bool = false) -> void:
|
||||
_is_self = is_self
|
||||
_cache_node_refs()
|
||||
|
||||
var safe_from_user := from_user
|
||||
if safe_from_user.strip_edges().is_empty():
|
||||
safe_from_user = "我" if is_self else "玩家"
|
||||
|
||||
# 设置用户名(带空值检查)
|
||||
if username_label:
|
||||
username_label.text = from_user
|
||||
username_label.text = safe_from_user
|
||||
else:
|
||||
push_error("ChatMessage: username_label is null!")
|
||||
return
|
||||
@@ -100,7 +108,7 @@ func set_message(from_user: String, content: String, timestamp: float, is_self:
|
||||
# 设置内容
|
||||
if content_label:
|
||||
content_label.clear() # 清除默认文本和所有内容
|
||||
content_label.bbcode_text = content # 使用 bbcode_text 因为 bbcode_enabled = true
|
||||
content_label.append_text(content) # 作为纯文本追加,避免 BBCode 解析导致内容不显示
|
||||
else:
|
||||
push_error("ChatMessage: content_label is null!")
|
||||
return
|
||||
@@ -124,10 +132,6 @@ func _apply_style() -> void:
|
||||
if not username_label or not timestamp_label or not user_info_container:
|
||||
return
|
||||
|
||||
# 设置大小约束 - 宽度固定,高度适应内容
|
||||
if get_parent():
|
||||
custom_minimum_size.x = min(max_width, get_parent().size.x)
|
||||
|
||||
# 重要:设置垂直 size flags 让 Panel 适应内容高度
|
||||
size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
|
||||
@@ -142,6 +146,8 @@ func _apply_style() -> void:
|
||||
# 设置文字颜色 - ID使用金色 #FFD700
|
||||
username_label.add_theme_color_override("font_color", Color(1.0, 0.8431373, 0.0))
|
||||
timestamp_label.add_theme_color_override("font_color", Color(0.7, 0.7, 0.7))
|
||||
if content_label:
|
||||
content_label.add_theme_color_override("default_color", Color(0.95, 0.97, 1.0))
|
||||
else:
|
||||
# 他人的消息:左侧对齐,灰色背景
|
||||
size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
@@ -153,11 +159,13 @@ func _apply_style() -> void:
|
||||
# 设置文字颜色 - ID使用蓝色 #69c0ff
|
||||
username_label.add_theme_color_override("font_color", Color(0.4117647, 0.7529412, 1.0))
|
||||
timestamp_label.add_theme_color_override("font_color", Color(0.5, 0.5, 0.5))
|
||||
if content_label:
|
||||
content_label.add_theme_color_override("default_color", Color(0.15, 0.15, 0.15))
|
||||
|
||||
# 获取自己消息的样式
|
||||
func _get_self_style() -> StyleBoxFlat:
|
||||
var style := StyleBoxFlat.new()
|
||||
style.bg_color = Color(0.2, 0.6, 1.0, 0.3)
|
||||
style.bg_color = Color(0.2, 0.6, 1.0, 0.8)
|
||||
style.corner_radius_top_left = 10
|
||||
style.corner_radius_top_right = 10
|
||||
style.corner_radius_bottom_left = 10
|
||||
@@ -171,7 +179,7 @@ func _get_self_style() -> StyleBoxFlat:
|
||||
# 获取他人消息的样式
|
||||
func _get_other_style() -> StyleBoxFlat:
|
||||
var style := StyleBoxFlat.new()
|
||||
style.bg_color = Color(0.9, 0.9, 0.9, 0.5)
|
||||
style.bg_color = Color(0.9, 0.9, 0.9, 0.8)
|
||||
style.corner_radius_top_left = 10
|
||||
style.corner_radius_top_right = 10
|
||||
style.corner_radius_bottom_left = 2
|
||||
|
||||
@@ -2,19 +2,15 @@
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/prefabs/ui/ChatMessage.gd" id="1"]
|
||||
|
||||
[node name="ChatMessage" type="Panel"]
|
||||
[node name="ChatMessage" type="PanelContainer"]
|
||||
layout_mode = 2
|
||||
offset_right = 400.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 6
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="UserInfoContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
|
||||
@@ -272,8 +272,12 @@ func _on_chat_message_received(data: Dictionary) -> void:
|
||||
var content: String = data.get("content", "")
|
||||
var timestamp: float = data.get("timestamp", 0.0)
|
||||
|
||||
var is_self: bool = bool(data.get("is_self", false))
|
||||
if not data.has("is_self") and not _current_username.is_empty() and from_user == _current_username:
|
||||
is_self = true
|
||||
|
||||
# 添加到消息历史
|
||||
add_message_to_history(from_user, content, timestamp, false)
|
||||
add_message_to_history(from_user, content, timestamp, is_self)
|
||||
|
||||
# 处理聊天错误
|
||||
func _on_chat_error(data: Dictionary) -> void:
|
||||
@@ -307,15 +311,23 @@ func add_message_to_history(from_user: String, content: String, timestamp: float
|
||||
if not _is_chat_visible:
|
||||
show_chat()
|
||||
|
||||
# 每条消息用一行容器包起来,方便左右对齐且不挤在一起
|
||||
var row := HBoxContainer.new()
|
||||
row.layout_mode = 2 # 让 VBoxContainer 接管布局,否则会重叠在同一位置
|
||||
row.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
row.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
row.alignment = BoxContainer.ALIGNMENT_END if is_self else BoxContainer.ALIGNMENT_BEGIN
|
||||
|
||||
# 创建消息节点
|
||||
var message_node: ChatMessage = chat_message_scene.instantiate()
|
||||
|
||||
# 先加入场景树,再设置内容(避免 ChatMessage._ready 尚未执行导致节点引用为空)
|
||||
message_list.add_child(row)
|
||||
row.add_child(message_node)
|
||||
|
||||
# 设置消息内容
|
||||
message_node.set_message(from_user, content, timestamp, is_self)
|
||||
|
||||
# 添加到列表
|
||||
message_list.add_child(message_node)
|
||||
|
||||
# 自动滚动到底部
|
||||
call_deferred("_scroll_to_bottom")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user