import { _decorator, Component, Node, Label, Sprite, UITransform, ScrollView, Button, } from "cc"; import { ChatHistoryManager, ChatMessage, } from "../../manager/ChatHistoryManager"; import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView"; import Utils from "db://assets/Scripts/Main/Common/Utils"; import { ChatContentsLayout } from "../components/ChatContentsLayout"; import { ViewManager } from "db://assets/Scripts/Main/Manager/ViewManager"; import GameRootUI from "db://assets/Scripts/Main/Common/GameRootUI"; import ResManager from "db://assets/Scripts/Main/Manager/ResManager"; import { ConfigManager } from "../../manager/ConfigManager"; import LanguageUtils from "../../../Main/Common/LanguageUtils"; import { Dialog } from "../../data/DialogData"; import { InnerMsgCode } from "../../../Main/Config/InnerMsgCode"; import { logger } from "db://assets/Scripts/Main/Common/Logger"; import { NavigationManager } from "../../manager/NavigationManager"; const { ccclass, property } = _decorator; @ccclass("RecordPanel") export class RecordPanel extends li_BaseView { @property(Label) girlName: Label = null; @property(Sprite) girlImg: Sprite = null; @property(ChatContentsLayout) layout: ChatContentsLayout = null; @property(ScrollView) scrollView: ScrollView = null; @property(Button) loadMoreBtn: Button = null; @property(Label) loadMoreLabel: Label = null; id: number; private _nodeTab: any = {}; nameKey: string; // 分页相关 private currentPage: number = 0; private pageSize: number = 20; private allMessages: ChatMessage[] = []; private displayedMessages: Dialog[] = []; private onLanguageChangeCallback = () => { if (!this.girlName) return; this.girlName.string = LanguageUtils.getText(this.nameKey); }; openUIDataCT(data) { this.id = data; } onLoadCT() { Utils.parseNode(this.node, this._nodeTab); this.register(); this.refresh(this.id); this.initLoadMoreBtn(); this.loadChatHistory(); } register() { // 注册语言变化监听 Utils.addInnerEL( InnerMsgCode.LanguageChange, this, this.onLanguageChangeCallback ); } onDestroy(): void { Utils.removeInnerEL( InnerMsgCode.LanguageChange, this, this.onLanguageChangeCallback ); } /** * 初始化加载更多按钮 */ private initLoadMoreBtn() { if (this.loadMoreBtn) { this.loadMoreBtn.node.on(Button.EventType.CLICK, this.onLoadMore, this); } this.updateLoadMoreBtn(); } refresh(id: number) { this.id = id; const data = ConfigManager.tables.TbGirls.get(this.id); const dataDetail = ConfigManager.tables.TbGirlsDetail.get(this.id); if (!data) return; this.nameKey = data.nameKey; this.girlName.string = LanguageUtils.getText(data.nameKey); // 设置角色头像 ResManager.I.changeBundleSpriteFrame( this.girlImg, data.avatarPath, "Chat18x", () => { let sizeTran = this.girlImg.node.parent.getComponent(UITransform); Utils.adjustBgPixelRatioToSize( sizeTran.contentSize, this.girlImg.node, 2 ); } ); } /** * 加载聊天历史记录并显示 */ private loadChatHistory() { // 从ChatHistoryManager获取历史记录 this.allMessages = ChatHistoryManager.Instance.loadHistory(this.id); if (this.allMessages.length === 0) { logger.log(`No chat history found for role ${this.id}`); this.updateLoadMoreBtn(); return; } // 倒序排列消息(最新的在前) this.allMessages.reverse(); // 重置分页 this.currentPage = 0; this.displayedMessages = []; // 加载第一页 this.loadMoreMessages(); } /** * 加载更多消息 */ private loadMoreMessages() { const startIndex = this.currentPage * this.pageSize; const endIndex = Math.min( startIndex + this.pageSize, this.allMessages.length ); // 获取当前页的消息 const pageMessages = this.allMessages.slice(startIndex, endIndex); // 将ChatMessage转换为Dialog格式并添加到显示列表 const newDialogs: Dialog[] = pageMessages.map((msg: ChatMessage) => ({ isPlayer: msg.role === "user", content: msg.parts[0]?.text || "", })); // 添加到已显示的消息列表 this.displayedMessages.push(...newDialogs); logger.log( `Loaded page ${this.currentPage + 1}, showing ${ this.displayedMessages.length }/${this.allMessages.length} messages` ); // 更新聊天内容布局 if (this.layout) { this.layout.UpdateDialog(this.displayedMessages); } // 更新页数 this.currentPage++; // 更新加载更多按钮状态 this.updateLoadMoreBtn(); // 如果是第一次加载,滚动到顶部 if (this.currentPage === 1 && this.scrollView) { this.scheduleOnce(() => { this.scrollView.scrollToTop(0.5); }, 0.1); } } /** * 加载更多按钮点击事件 */ private onLoadMore() { if (this.hasMoreMessages()) { this.loadMoreMessages(); } } /** * 判断是否还有更多消息 */ private hasMoreMessages(): boolean { return this.currentPage * this.pageSize < this.allMessages.length; } /** * 更新加载更多按钮状态 */ private updateLoadMoreBtn() { if (!this.loadMoreBtn) return; const hasMore = this.hasMoreMessages(); this.loadMoreBtn.node.active = hasMore; if (this.loadMoreLabel) { const remainingCount = this.allMessages.length - this.currentPage * this.pageSize; this.loadMoreLabel.string = hasMore ? `加载更多 (还有${remainingCount}条)` : "没有更多消息了"; } } /** * 清除当前角色的聊天记录 */ public clearHistory() { ChatHistoryManager.Instance.clearHistory(this.id); logger.log(`Cleared chat history for role ${this.id}`); // 重置数据 this.allMessages = []; this.displayedMessages = []; this.currentPage = 0; // 重新加载(显示空记录) this.loadChatHistory(); } /** * 刷新聊天记录显示 */ public refreshHistory() { this.loadChatHistory(); } /** * 滚动到最新记录(顶部,因为是倒序) */ public scrollToLatest() { if (this.scrollView) { this.scrollView.scrollToTop(0.5); } } /** * 滚动到最早记录(底部,因为是倒序) */ public scrollToEarliest() { if (this.scrollView) { this.scrollView.scrollToBottom(0.5); } } /** * 获取消息统计信息 */ public getMessageStats(): { total: number; displayed: number; remaining: number; } { return { total: this.allMessages.length, displayed: this.displayedMessages.length, remaining: this.allMessages.length - this.displayedMessages.length, }; } protected onEnable(): void { // NavigationPanel 始终显示,不需要隐藏 DefaultView } /** * 返回按钮点击事件 */ returnBtn() { this.onClose(); NavigationManager.Instance.closePopupPanel(this.node); } }