This commit is contained in:
2025-09-21 14:28:17 +08:00
parent 11e8e516b7
commit d823fa9083
16 changed files with 635 additions and 701 deletions
@@ -92,18 +92,6 @@ export class ChatContentsLayout extends Component {
playerBubble.node.active = true;
playerBubble.updateBubbleContent(dialog.content, true);
this.bubbles.push(playerBubble);
// 创建等待回复气泡(插入到首位,显示在玩家消息上面)
// this.waitingBubble = this.createOrGetBubble(false);
// this.waitingBubble.node.active = true;
// this.waitingBubble.updateBubbleContent("...", false, undefined, true);
// this.waitingBubble.node.setSiblingIndex(0);
// this.bubbles.push(this.waitingBubble);
this.node.position = Vec3.ZERO;
// 滚动到底部(等待下一帧Layout更新完成)
this.scheduleOnce(() => {
this.scrollView.scrollToBottom();
}, 0);
}
/**
* 更新AI回复的对话
@@ -120,6 +108,12 @@ export class ChatContentsLayout extends Component {
// 逐个添加AI对话,带延时
this.addAIDialogsWithDelay(dialogs, 0);
this.node.position = Vec3.ZERO;
// 滚动到底部(等待下一帧Layout更新完成)
this.scheduleOnce(() => {
this.scrollView.scrollToBottom();
}, 0);
}
/**
+12 -2
View File
@@ -84,6 +84,13 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
targetSize;
videoAreaPos;
base: Node;
openUIDataCT(data: any) {
this.base = data.base;
}
onLoadCT() {
Utils.parseNode(this.node, this._nodeTab);
@@ -395,8 +402,12 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
protected onEnable(): void {
if (!this.manager) this.manager = DialogManager.getInstance();
this.base.active = false;
this.refresh();
}
protected onDisable(): void {
this.base.active = true;
}
isWaiting: boolean = false;
public async OnClickSend() {
@@ -501,8 +512,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
}
returnBtn() {
// Navigate back to GirlDetailPanel with current girlId using smooth transition
NavigationManager.Instance.switchToPanel(PanelType.GIRL_DETAIL);
NavigationManager.Instance.closeSubPanel(this);
}
onClickRecord() {
NavigationManager.Instance.openPopupPanel("RecordPanel", this.id);
@@ -311,17 +311,15 @@ export class GirlDetailPanel extends li_BaseView {
OnClickChatBtn() {
// 使用带过渡动画的导航方法
NavigationManager.Instance.switchToPanel(PanelType.PAST_GIRL_LIST);
// 延迟打开 ChatPanel,确保 PastGirlListPanel 已经完全加载
this.scheduleOnce(() => {
// 获取当前活动的 PastGirlListPanel 节点
const baseNode = NavigationManager.Instance.getCurrentActivePanelNode();
if (baseNode) {
const chatData = { girlId: this.id };
NavigationManager.Instance.openSubPanel("ChatPanel", baseNode, chatData);
NavigationManager.Instance.switchToPanel(
PanelType.PAST_GIRL_LIST,
false,
(base) => {
const chatData = { girlId: this.id ,base:base};
NavigationManager.Instance.openSubPanel("ChatPanel", base, chatData);
}
}, 0.5); // 延迟 0.5 秒,确保动画完成
);
}
returnBtn() {
@@ -1,4 +1,4 @@
import { _decorator, Component, Node, instantiate } from "cc";
import { _decorator, Component, Node, instantiate, tween, Vec3 } from "cc";
import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView";
import Utils from "db://assets/Scripts/Main/Common/Utils";
import { GButton } from "db://assets/Scripts/Main/Common/GButton";
@@ -8,6 +8,7 @@ import { DataManager, DataId } from "../../data/DataManager";
import { GirlData } from "../../data/GirlData";
import proto from "db://assets/Scripts/proto/proto.pb.js";
import { NavigationManager, PanelType } from "../../manager/NavigationManager";
import { UITransitionHelper } from "../../utils/UITransitionHelper";
const { ccclass, property } = _decorator;
@@ -99,7 +100,8 @@ export class GirlListPanel extends li_BaseView {
girlData.setGirlList(category.toString(), res.data);
// 根据数据,刷新界面
const allId = girlData.getGirlIds(category.toString());
for (let id of allId) {
for (let i = 0; i < allId.length; i++) {
let id = allId[i];
let item = this.getItemFromPool();
item.refreshData(category, id, this.node);
item.node.active = true;
@@ -113,6 +115,28 @@ export class GirlListPanel extends li_BaseView {
}
}
private addSlideInAnimation(itemNode: Node, index: number) {
// 保存节点的目标位置
const targetPosition = itemNode.getPosition();
// 设置初始位置为屏幕右侧外(偏移300像素)
const startPosition = new Vec3(
targetPosition.x + 300,
targetPosition.y,
targetPosition.z
);
itemNode.setPosition(startPosition);
// 添加递进延时,每个item延迟0.05秒
const delay = index * 0.05;
// 执行滑入动画
tween(itemNode)
.delay(delay)
.to(0.4, { position: targetPosition }, { easing: "cubicOut" })
.start();
}
hide() {
this.node.active = false;
}
@@ -121,8 +145,7 @@ export class GirlListPanel extends li_BaseView {
GButton.BandClick(this._nodeTab.ReturnBtn, this.Return, this);
}
Return() {
// 直接关闭,不需要动画
this.node.active = false;
NavigationManager.Instance.closeSubPanel(this);
}
onDestroy() {
@@ -141,16 +164,5 @@ export class GirlListPanel extends li_BaseView {
}
}
this.cache = [];
// 清理 content 中所有的 GirlListItem 节点
for (let i = this.content.children.length - 1; i >= 0; i--) {
let child = this.content.children[i];
if (child !== this.itemInst.node) {
let item = child.getComponent(GirlListItem);
if (item) {
child.destroy();
}
}
}
}
}
@@ -36,7 +36,7 @@ export class NavigationPanel extends li_BaseView {
NavigationManager.Instance.registerNavigationPanel(this);
this.registerListener();
this.updateButtonStates(PanelType.PAST_GIRL_LIST);
this.updateButtonStates(PanelType.THEME);
// 初次打开时通过NavigationManager切换到主题面板
this.initializeFirstPanel();
@@ -101,13 +101,15 @@ export class NavigationPanel extends li_BaseView {
this.girlDetailBtn.setFocus(
this.currentActivePanel === PanelType.GIRL_DETAIL
);
this.pastGirlListBtn.setFocus(this.currentActivePanel === PanelType.PAST_GIRL_LIST);
this.pastGirlListBtn.setFocus(
this.currentActivePanel === PanelType.PAST_GIRL_LIST
);
this.settingBtn.setFocus(this.currentActivePanel === PanelType.PERSONAL);
}
private initializeFirstPanel() {
// 初次打开时通过NavigationManager切换到历史女孩列表面板
NavigationManager.Instance.switchToPanel(PanelType.PAST_GIRL_LIST, true);
NavigationManager.Instance.switchToPanel(PanelType.THEME, true);
}
public showPanel() {
@@ -5,6 +5,7 @@ import { GButton } from "db://assets/Scripts/Main/Common/GButton";
import { PastGirlListItem } from "../../uiitems/PastGirlListItem";
import { DataManager, DataId } from "../../data/DataManager";
import { GirlData } from "../../data/GirlData";
import { ChatHistoryManager } from "../../manager/ChatHistoryManager";
const { ccclass, property } = _decorator;
@@ -68,13 +69,9 @@ export class PastGirlListPanel extends li_BaseView {
// TODO: 实现获取已解锁女孩列表的逻辑
// 这个方法需要遍历所有分类,找出 isRelease === true 的女孩
private getUnlockedGirls(): number[] {
// TODO: 实现获取已解锁女孩列表逻辑
// 需要实现的逻辑:
// 1. 遍历 GirlData 中的所有分类
// 2. 对每个分类中的每个女孩检查 getIsRelease 状态
// 3. 返回所有已解锁女孩的 {category, id} 列表
console.log("TODO: 实现获取已解锁女孩列表逻辑");
return [10001, 10002];
const GirlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
const allids = GirlData.getAllReleaseGirlIds();
return allids;
}
refresh() {
@@ -90,10 +87,22 @@ export class PastGirlListPanel extends li_BaseView {
// 获取已解锁女孩列表
const ids = this.getUnlockedGirls();
// 根据数据,刷新界面
// 创建带时间戳的数组用于排序
const girlsWithTime: {id: number, lastTime: number}[] = [];
// 收集每个女孩的最后聊天时间
for (let id of ids) {
const lastTime = ChatHistoryManager.Instance.getLastChatTime(id) || 0;
girlsWithTime.push({id, lastTime});
}
// 按最后聊天时间降序排序(最近的在前)
girlsWithTime.sort((a, b) => b.lastTime - a.lastTime);
// 根据排序后的数据刷新界面
for (let girlData of girlsWithTime) {
let item = this.getItemFromPool();
item.refreshData(id, this.node);
item.refreshData(girlData.id, this.node);
item.node.active = true;
this.cache.push(item);
@@ -120,8 +120,7 @@ export class PurchasePanel extends li_BaseView {
GButton.BandClick(
this._nodeTab.ReturnBtn,
() => {
this.onClose();
// NavigationPanel 始终显示,不需要显示 DefaultView
NavigationManager.Instance.closeSubPanel(this);
},
this
);
@@ -17,6 +17,7 @@ import LanguageUtils, {
} from "../../../Main/Common/LanguageUtils";
import AudioManager from "../../../Main/Manager/AudioManager";
import PlayerDataManager from "../../../Main/Manager/PlayerDataManager";
import { NavigationManager } from "../../manager/NavigationManager";
const { ccclass, property } = _decorator;
interface LanguageButton {
@@ -58,8 +59,6 @@ export class SettingPanel extends li_BaseView {
this.currentSelectedLang = LanguageUtils.CurrentLanguage;
this.updateSelection();
this.updateAudioButtonStates();
this.playEnterAnimation();
}
private music_on: Node;
@@ -163,7 +162,7 @@ export class SettingPanel extends li_BaseView {
// GButton.BandClick(this._nodeTab.Language1, this.switchToEn, this);
// GButton.BandClick(this._nodeTab.Language2, this.swithcToHi, this);
GButton.BandClick(this._nodeTab.closeBtn, this.close, this);
GButton.BandClick(this._nodeTab.closeBtn, this.onClickClose, this);
this.languageButtons.forEach((langBtn) => {
if (langBtn.button) {
@@ -273,23 +272,7 @@ export class SettingPanel extends li_BaseView {
.start();
}
private playEnterAnimation() {
if (this.panelBg) {
this.panelBg.scale = new Vec3(0.8, 0.8, 1);
tween(this.panelBg)
.to(0.3, { scale: new Vec3(1, 1, 1) }, { easing: "backOut" })
.start();
}
}
private playExitAnimation(callback: () => void) {
if (this.panelBg) {
tween(this.panelBg)
.to(0.2, { scale: new Vec3(0.8, 0.8, 1) }, { easing: "backIn" })
.call(callback)
.start();
} else {
callback();
}
onClickClose() {
NavigationManager.Instance.closeSubPanel(this);
}
}