公会系统:guild_chat_panel.lua

管理员
```lua -- game/ui/guild_chat_panel.lua -- 公会聊天面板UI,实现完整的聊天界面 local utils = require("core.utils") local class = require("core.class") local mvc = require("core.mvc") local event = require("core.event") local chatManager = require("modules.chat_manager") local guildManager = require("modules.guild_manager") local GuildChatPanelView = mvc.View:extend("GuildChatPanelView") function GuildChatPanelView:onBind() -- 获取UI组件 self.chatContainer = self:getComponent("ChatContainer", "Transform") self.chatTemplate = self:getComponent("ChatTemplate", "GameObject") self.chatInput = self:getComponent("ChatInput", "InputField") self.sendButton = self:getComponent("SendButton", "Button") -- 频道切换按钮 self.worldButton = self:getComponent("WorldButton", "Button") self.guildButton = self:getComponent("GuildButton", "Button") self.privateButton = self:getComponent("PrivateButton", "Button") -- 成员列表 self.memberList = self:getComponent("MemberList", "Transform") self.memberTemplate = self:getComponent("MemberTemplate", "GameObject") -- 私聊面板 self.privatePanel = self:getComponent("PrivatePanel", "GameObject") self.privateChatContainer = self:getComponent("PrivateChatContainer", "Transform") -- 表情按钮 self.emojiButton = self:getComponent("EmojiButton", "Button") self.emojiPanel = self:getComponent("EmojiPanel", "GameObject") -- 隐藏模板 self.chatTemplate:SetActive(false) self.memberTemplate:SetActive(false) self.emojiPanel:SetActive(false) -- 创建聊天消息缓存池 self.messagePool = {} self.maxPoolSize = 20 -- 绑定按钮事件 self:BindButtonEvents() -- 注册UI事件 self:RegisterUIEvents() -- 初始化表情面板 self:InitEmojiPanel() end function GuildChatPanelView:BindButtonEvents() -- 发送按钮 self.sendButton.onClick:AddListener(function() event.emit("GUILD_CHAT_SEND_CLICKED") end) -- 频道切换 self.worldButton.onClick:AddListener(function() event.emit("GUILD_CHAT_SWITCH_CHANNEL", chatManager.ChannelType.WORLD) end) self.guildButton.onClick:AddListener(function() event.emit("GUILD_CHAT_SWITCH_CHANNEL", chatManager.ChannelType.GUILD) end) self.privateButton.onClick:AddListener(function() event.emit("GUILD_CHAT_OPEN_PRIVATE_LIST") end) -- 表情按钮 self.emojiButton.onClick:AddListener(function() self.emojiPanel:SetActive(not self.emojiPanel.activeSelf) end) end function GuildChatPanelView:RegisterUIEvents() -- 监听频道切换 event.on("CHAT_CHANNEL_CHANGED", function(channelType) self:UpdateChannelUI(channelType) end) -- 监听新消息 event.on("CHAT_MESSAGE_ADDED", function(chatMessage) self:OnNewMessage(chatMessage) end) -- 监听历史消息加载 event.on("CHAT_HISTORY_LOADED", function(channelType, messages) if channelType == chatManager:GetCurrentChannel() then self:RefreshMessageList(messages) end end) -- 监听成员列表加载 event.on("GUILD_MEMBERS_LOADED", function(members) self:RefreshMemberList(members) end) -- 监听私聊会话添加 event.on("CHAT_PRIVATE_SESSION_ADDED", function(session) self:OnPrivateSessionAdded(session) end) end function GuildChatPanelView:InitEmojiPanel() local emojis = {"笑", "哭", "色", "嘘", "酷", "怒", "怕", "棒", "拉"} for i, emoji in ipairs(emojis) do local emojiButton = CS.UnityEngine.Object.Instantiate(self.emojiButton.transform, self.emojiPanel.transform) emojiButton.gameObject:SetActive(true) local text = emojiButton:GetComponentInChildren(typeof(CS.UnityEngine.UI.Text)) if text then text.text = emoji end local btn = emojiButton:GetComponent(typeof(CS.UnityEngine.UI.Button)) btn.onClick:AddListener(function() self.chatInput.text = self.chatInput.text .. emoji end) end self.emojiButton.transform:SetAsLastSibling() end -- 更新频道UI function GuildChatPanelView:UpdateChannelUI(channelType) local buttons = { [chatManager.ChannelType.WORLD] = self.worldButton, [chatManager.ChannelType.GUILD] = self.guildButton, [chatManager.ChannelType.PRIVATE] = self.privateButton } -- 更新按钮状态 for type, button in pairs(buttons) do local colors = button.colors if type == channelType then colors.normalColor = CS.UnityEngine.Color(0.3, 0.5, 1, 1) colors.highlightedColor = CS.UnityEngine.Color(0.4, 0.6, 1, 1) else colors.normalColor = CS.UnityEngine.Color(0.8, 0.8, 0.8, 1) colors.highlightedColor = CS.UnityEngine.Color(0.9, 0.9, 0.9, 1) end button.colors = colors end -- 刷新消息列表 self:RefreshMessageList(chatManager:GetMessages(channelType)) end -- 刷新消息列表 function GuildChatPanelView:RefreshMessageList(messages) -- 清空现有消息 for i = 1, self.chatContainer.childCount do local child = self.chatContainer:GetChild(i - 1) self:RecycleMessageItem(child.gameObject) end -- 添加新消息 for i, chatMessage in ipairs(messages) do self:AddMessageItem(chatMessage) end -- 滚动到底部 CS.CoroutineUtility.StartCoroutine(function() CS.UnityEngine.Yield(CS.UnityEngine.WaitForEndOfFrame()) local scrollRect = self.chatContainer:GetComponent(typeof(CS.UnityEngine.UI.ScrollRect)) if scrollRect then scrollRect.verticalNormalizedPosition = 0 end end) end -- 添加消息项 function GuildChatPanelView:AddMessageItem(chatMessage) local messageItem = self:GetMessageItem() messageItem.transform:SetParent(self.chatContainer, false) -- 获取组件 local nameLabel = messageItem.transform:Find("NameLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local timeLabel = messageItem.transform:Find("TimeLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local contentLabel = messageItem.transform:Find("ContentLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local channelLabel = messageItem.transform:Find("ChannelLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local levelLabel = messageItem.transform:Find("LevelLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) -- 填充数据 if nameLabel then nameLabel.text = chatMessage.sender_name end if timeLabel then timeLabel.text = chatManager:FormatTime(chatMessage.timestamp) end if contentLabel then contentLabel.text = chatMessage.content end if channelLabel then channelLabel.text = chatManager:GetMessageTypeName(chatMessage) end if levelLabel then levelLabel.text = "Lv." .. chatMessage.level end -- 设置VIP等级颜色 local vipColor = self:GetVIPColor(chatMessage.vip_level) if nameLabel then nameLabel.color = vipColor end -- 保存消息数据 local luaBehaviour = messageItem:GetComponent(typeof(CS.LuaBehaviour)) if not luaBehaviour then luaBehaviour = messageItem:AddComponent(typeof(CS.LuaBehaviour)) end luaBehaviour:SetLuaData("chatMessage", chatMessage) -- 绑定点击事件(用于@功能) local button = messageItem:GetComponent(typeof(CS.UnityEngine.UI.Button)) if button then button.onClick:AddListener(function() self:OnMessageClicked(chatMessage) end) end end -- 消息点击事件 function GuildChatPanelView:OnMessageClicked(chatMessage) -- 在输入框中@玩家 self.chatInput.text = self.chatInput.text .. "@" .. chatMessage.sender_name .. " " self.chatInput:ActivateInputField() end -- 获取消息项(从池中或创建新项) function GuildChatPanelView:GetMessageItem() if #self.messagePool > 0 then local item = table.remove(self.messagePool) item:SetActive(true) return item end return CS.UnityEngine.Object.Instantiate(self.chatTemplate, self.chatContainer) end -- 回收消息项到池中 function GuildChatPanelView:RecycleMessageItem(item) if #self.messagePool < self.maxPoolSize then item:SetActive(false) table.insert(self.messagePool, item) else CS.UnityEngine.Object.Destroy(item) end end -- 获取VIP颜色 function GuildChatPanelView:GetVIPColor(vipLevel) if vipLevel >= 10 then return CS.UnityEngine.Color(1, 0.5, 0, 1) -- 金色 elseif vipLevel >= 5 then return CS.UnityEngine.Color(0.8, 0.4, 1, 1) -- 紫色 elseif vipLevel >= 3 then return CS.UnityEngine.Color(0, 0.8, 1, 1) -- 蓝色 else return CS.UnityEngine.Color(1, 1, 1, 1) -- 白色 end end -- 刷新成员列表 function GuildChatPanelView:RefreshMemberList(members) -- 清空现有成员 for i = 1, self.memberList.childCount do CS.UnityEngine.Object.Destroy(self.memberList:GetChild(i - 1).gameObject) end -- 添加成员 for i, member in ipairs(members) do self:AddMemberItem(member) end end -- 添加成员项 function GuildChatPanelView:AddMemberItem(member) local memberItem = CS.UnityEngine.Object.Instantiate(self.memberTemplate, self.memberList) memberItem:SetActive(true) -- 获取组件 local nameLabel = memberItem.transform:Find("NameLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local levelLabel = memberItem.transform:Find("LevelLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local positionLabel = memberItem.transform:Find("PositionLabel"):GetComponent(typeof(CS.UnityEngine.UI.Text)) local onlineIndicator = memberItem.transform:Find("OnlineIndicator"):GetComponent(typeof(CS.UnityEngine.UI.Image)) -- 填充数据 if nameLabel then nameLabel.text = member.player_name end if levelLabel then levelLabel.text = "Lv." .. member.level end if positionLabel then positionLabel.text = guildManager.GetPositionName(member.position) end if onlineIndicator then onlineIndicator.color = member.is_online and CS.UnityEngine.Color.green or CS.UnityEngine.Color.gray end -- 绑定点击事件(私聊) local button = memberItem:GetComponent(typeof(CS.UnityEngine.UI.Button)) if button then button.onClick:AddListener(function() self:OnMemberClicked(member) end) end end -- 成员点击事件 function GuildChatPanelView:OnMemberClicked(member) -- 打开私聊 event.emit("GUILD_CHAT_OPEN_PRIVATE", member.player_id, member.player_name) end -- 私聊会话添加 function GuildChatPanelView:OnPrivateSessionAdded(session) -- 更新私聊列表UI utils.print("新的私聊会话: " .. session.user_name) end -- 新消息处理 function GuildChatPanelView:OnNewMessage(chatMessage) -- 如果是当前频道的消息,添加到列表 if chatMessage.type == chatManager:GetCurrentChannel() then self:AddMessageItem(chatMessage) -- 滚动到底部 CS.CoroutineUtility.StartCoroutine(function() CS.UnityEngine.Yield(CS.UnityEngine.WaitForEndOfFrame()) local scrollRect = self.chatContainer:GetComponent(typeof(CS.UnityEngine.UI.ScrollRect)) if scrollRect then scrollRect.verticalNormalizedPosition = 0 end end) end end -- 清理 function GuildChatPanelView:destroy() -- 清理对象池 for _, item in ipairs(self.messagePool) do CS.UnityEngine.Object.Destroy(item) end self.messagePool = {} end local GuildChatPanelController = mvc.Controller:extend("GuildChatPanelController") function GuildChatPanelController:onBind() -- 初始化聊天管理器 self.chatManager = chatManager.getModule("ChatManager") self.guildManager = guildManager.getModule("GuildManager") -- 注册事件 self:RegisterControllerEvents() -- 初始化UI self:InitializeUI() -- 加载初始数据 self:LoadInitialData() end function GuildChatPanelController:RegisterControllerEvents() -- 发送消息 event.on("GUILD_CHAT_SEND_CLICKED", function() self:OnSendClicked() end) -- 切换频道 event.on("GUILD_CHAT_SWITCH_CHANNEL", function(channelType) self:OnSwitchChannel(channelType) end) -- 发送成功 event.on("CHAT_SEND_SUCCESS", function(chatMessage) self:OnSendSuccess(chatMessage) end) -- 发送失败 event.on("CHAT_SEND_FAILED", function(errorMsg) self:OnSendFailed(errorMsg) end) -- 打开私聊 event.on("GUILD_CHAT_OPEN_PRIVATE", function(userId, userName) self:OnOpenPrivate(userId, userName) end) end function GuildChatPanelController:InitializeUI() -- 设置初始频道 self.view:UpdateChannelUI(self.chatManager:GetCurrentChannel()) -- 加载成员列表 if self.guildManager and self.guildManager:IsInGuild() then local members = self.guildManager:GetMembers() if #members > 0 then self.view:RefreshMemberList(members) else self.guildManager:RequestGuildMembers(function(success, members) if success then self.view:RefreshMemberList(members) end end) end end end function GuildChatPanelController:LoadInitialData() -- 加载当前频道的历史消息 local currentChannel = self.chatManager:GetCurrentChannel() local messages = self.chatManager:GetMessages(currentChannel) if #messages > 0 then self.view:RefreshMessageList(messages) else self.chatManager:RequestChatHistory(currentChannel) end end function GuildChatPanelController:OnSendClicked() local content = self.view.chatInput.text if not content or #content == 0 then return end -- 提取@的用户ID local atUserIds = self:ExtractAtUserIds(content) -- 发送消息 local success, errorMsg = self.chatManager:SendMessage( self.chatManager:GetCurrentChannel(), content, nil, atUserIds ) if success then -- 清空输入框 self.view.chatInput.text = "" else utils.print("发送失败: " .. errorMsg) end end function GuildChatPanelController:OnSwitchChannel(channelType) self.chatManager:SwitchChannel(channelType) end function GuildChatPanelController:OnSendSuccess(chatMessage) utils.print("消息发送成功") end function GuildChatPanelController:OnSendFailed(errorMsg) utils.print("消息发送失败: " .. errorMsg) -- 显示错误提示 self:ShowToast(errorMsg) end function GuildChatPanelController:OnOpenPrivate(userId, userName) utils.print("打开私聊: " .. userName) -- 切换到私聊频道 self.chatManager:SwitchChannel(chatManager.ChannelType.PRIVATE) end -- 提取@的用户ID function GuildChatPanelController:ExtractAtUserIds(content) local atUserIds = {} -- 解析@用户名,转换为用户ID local pattern = "@([^%s]+)" for username in string.gmatch(content, pattern) do local member = self.guildManager:GetMemberByName(username) if member then table.insert(atUserIds, member.player_id) end end return atUserIds end -- 显示Toast提示 function GuildChatPanelController:ShowToast(message) CS.UIManager.Instance:ShowToast(message, 2) end return { View = GuildChatPanelView, Controller = GuildChatPanelController } ```
评论 0

发表评论 取消回复

Shift+Enter 换行  ·  Enter 发送
还没有评论,来发表第一条吧