Files
18xchat/assets/Scripts/chat18x/ui/panels/RecordPanel.ts
T
xionglijia 7722ccf694 ui模块优化 全部navigationmanager管理
实现pastgirllistpanel逻辑
完善图集
2025-09-21 12:05:34 +08:00

300 lines
6.9 KiB
TypeScript

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";
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) {
console.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);
console.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);
console.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();
this.close(); // 使用li_BaseView的close方法
}
}