ui模块优化 全部navigationmanager管理
实现pastgirllistpanel逻辑 完善图集
This commit is contained in:
@@ -41,10 +41,22 @@ export class ChatHistoryManager {
|
||||
public saveHistory(roleId: number, messages: ChatMessage[]): void {
|
||||
const key = `chat_history_${roleId}`;
|
||||
try {
|
||||
// 检查是否已存在历史记录以保留创建时间
|
||||
let createdAt = Date.now();
|
||||
const existingData = sys.localStorage.getItem(key);
|
||||
if (existingData) {
|
||||
try {
|
||||
const existingHistory: ChatHistory = JSON.parse(existingData);
|
||||
createdAt = existingHistory.createdAt;
|
||||
} catch (parseError) {
|
||||
console.warn(`Failed to parse existing history for role ${roleId}, using current time as createdAt`);
|
||||
}
|
||||
}
|
||||
|
||||
const history: ChatHistory = {
|
||||
roleId: roleId,
|
||||
messages: messages,
|
||||
createdAt: Date.now(),
|
||||
createdAt: createdAt,
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
|
||||
@@ -200,6 +212,31 @@ export class ChatHistoryManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定角色的最后聊天时间
|
||||
* @param roleId 角色ID
|
||||
* @returns 最后聊天时间戳,如果没有历史记录则返回null
|
||||
*/
|
||||
public getLastChatTime(roleId: number): number | null {
|
||||
const key = `chat_history_${roleId}`;
|
||||
try {
|
||||
const data = sys.localStorage.getItem(key);
|
||||
if (data) {
|
||||
const history: ChatHistory = JSON.parse(data);
|
||||
if (history.messages && history.messages.length > 0) {
|
||||
// 获取最后一条消息的时间戳
|
||||
const lastMessage = history.messages[history.messages.length - 1];
|
||||
return lastMessage.timestamp || history.updatedAt;
|
||||
}
|
||||
// 如果有历史但没有消息,返回创建时间
|
||||
return history.createdAt;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to get last chat time for role ${roleId}:`, error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从远程服务器下载历史(预留接口)
|
||||
* @param roleId 角色ID
|
||||
|
||||
@@ -23,7 +23,7 @@ export enum PageTransitionType {
|
||||
export enum PanelType {
|
||||
THEME = "ThemePanel",
|
||||
GIRL_DETAIL = "GirlDetailPanel",
|
||||
CHAT = "ChatPanel",
|
||||
PAST_GIRL_LIST = "PastGirlListPanel",
|
||||
PERSONAL = "PersonalPanel",
|
||||
}
|
||||
|
||||
@@ -51,18 +51,14 @@ export class NavigationManager {
|
||||
|
||||
// NavigationPanel相关属性
|
||||
private navigationPanel: any = null; // NavigationPanel实例引用
|
||||
private currentActivePanelType: PanelType = PanelType.THEME;
|
||||
private currentActivePanel: Node;
|
||||
private currentActivePanelType: PanelType = PanelType.PAST_GIRL_LIST;
|
||||
private currentActivePanel: Node = null; // 初始化为null
|
||||
private panelCache: Map<PanelType, Node> = new Map(); // 面板缓存
|
||||
private currentVisiblePanel: Node = null;
|
||||
|
||||
// 选中的角色相关信息
|
||||
private selectedGirlId: number = 10002; // 当前选中的角色ID
|
||||
private selectedCategoryId: number = -1; // 当前选中的主题ID
|
||||
|
||||
private themePanel: ThemePanel = null;
|
||||
private girlListPanel: GirlListPanel = null;
|
||||
|
||||
private static LastSelectGirlID = "LastSelectGirlID";
|
||||
|
||||
/**
|
||||
@@ -119,22 +115,27 @@ export class NavigationManager {
|
||||
* @param panelType 目标面板类型
|
||||
*/
|
||||
public switchToPanel(panelType: PanelType, force: boolean = false): Node {
|
||||
if (this.currentActivePanelType === panelType && !force) {
|
||||
if (panelType === PanelType.THEME) {
|
||||
this.girlListPanel?.hide();
|
||||
}
|
||||
if (!panelType) {
|
||||
console.error("[NavigationManager] switchToPanel: panelType is invalid");
|
||||
return null;
|
||||
}
|
||||
|
||||
return;
|
||||
if (this.currentActivePanelType === panelType && !force) {
|
||||
console.log(`[NavigationManager] Already on ${panelType}, skipping switch`);
|
||||
return this.currentActivePanel;
|
||||
}
|
||||
|
||||
if (!this.navigationPanel) {
|
||||
console.warn(
|
||||
"[NavigationManager] NavigationPanel not registered, fallback to direct ViewManager call"
|
||||
);
|
||||
this.fallbackSwitchPanel(panelType);
|
||||
return;
|
||||
//this.fallbackSwitchPanel(panelType);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 切换面板前先关闭所有弹窗
|
||||
this.closeAllPopups();
|
||||
|
||||
// 通知NavigationPanel显示加载状态
|
||||
this.navigationPanel.showLoading?.();
|
||||
|
||||
@@ -147,28 +148,17 @@ export class NavigationManager {
|
||||
const showDirection = isMovingRight ? "right" : "left";
|
||||
|
||||
// 隐藏当前面板(包括子页面)
|
||||
this.hideCurrentPanelWithChildren(hideDirection);
|
||||
if (!this.currentActivePanel || !this.currentActivePanel.isValid) {
|
||||
return;
|
||||
}
|
||||
this.hidePanelWithAnimation(this.currentActivePanel, hideDirection);
|
||||
|
||||
// 加载并显示目标面板
|
||||
this.loadOrGetPanel(panelType, (panel: Node) => {
|
||||
// 清理当前面板的subPanel(在hidePanelWithAnimation中已经清理,这里不需要重复)
|
||||
|
||||
this.currentActivePanelType = panelType;
|
||||
this.currentVisiblePanel = panel;
|
||||
|
||||
if (this.subPanelDic.has(this.currentActivePanel)) {
|
||||
//如果有子页面,关闭掉
|
||||
let subs = this.subPanelDic.get(this.currentActivePanel);
|
||||
if (subs) {
|
||||
subs.forEach((n) => {
|
||||
if (n.name != "") {
|
||||
n.getComponent(li_BaseView)?.close();
|
||||
} else {
|
||||
//n.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.subPanelDic.delete(this.currentActivePanel);
|
||||
}
|
||||
// 更新NavigationPanel按钮状态
|
||||
this.navigationPanel.updateButtonStates?.(panelType);
|
||||
|
||||
@@ -181,17 +171,217 @@ export class NavigationManager {
|
||||
}
|
||||
|
||||
private subPanelDic: Map<Node, Node[]> = new Map();
|
||||
private subPanelMapping: Map<Node, PanelType> = new Map();
|
||||
|
||||
// 弹窗管理相关属性
|
||||
private popupPanels: Set<Node> = new Set(); // 管理所有打开的弹窗
|
||||
|
||||
/**
|
||||
* 统一的subPanel清理方法
|
||||
* @param basePanel 主面板节点
|
||||
* @param destroyPanels 是否销毁面板,默认为true
|
||||
*/
|
||||
private clearSubPanels(basePanel: Node, destroyPanels: boolean = true): void {
|
||||
if (!basePanel || !basePanel.isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const subPanels = this.subPanelDic.get(basePanel);
|
||||
if (!subPanels || subPanels.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 清理所有子面板
|
||||
for (let i = subPanels.length - 1; i >= 0; i--) {
|
||||
const subPanel = subPanels[i];
|
||||
if (subPanel && subPanel.isValid) {
|
||||
// 清理subPanelMapping
|
||||
this.subPanelMapping.delete(subPanel);
|
||||
|
||||
if (destroyPanels) {
|
||||
const baseView = subPanel.getComponent(li_BaseView);
|
||||
if (baseView) {
|
||||
baseView.close();
|
||||
} else {
|
||||
subPanel.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清理subPanelDic
|
||||
this.subPanelDic.delete(basePanel);
|
||||
}
|
||||
public openSubPanel(panelName: string, basePanel: Node, data: any = null) {
|
||||
if (!panelName) {
|
||||
console.error("[NavigationManager] openSubPanel: panelName is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!basePanel || !basePanel.isValid) {
|
||||
console.error("[NavigationManager] openSubPanel: basePanel is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
const callback = (n: Node) => {
|
||||
if (!n || !n.isValid) {
|
||||
console.error("[NavigationManager] openSubPanel: created panel is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.subPanelDic.has(basePanel)) {
|
||||
this.subPanelDic.set(basePanel, []);
|
||||
}
|
||||
this.subPanelDic.get(basePanel).push(n);
|
||||
|
||||
const subPanels = this.subPanelDic.get(basePanel);
|
||||
subPanels.push(n);
|
||||
|
||||
const basePanelType = this.getPanelType(basePanel);
|
||||
if (basePanelType) {
|
||||
this.subPanelMapping.set(n, basePanelType);
|
||||
} else {
|
||||
console.warn(`[NavigationManager] 无法确定basePanel类型: ${basePanel.name}`);
|
||||
}
|
||||
|
||||
n.setParent(basePanel, true);
|
||||
};
|
||||
|
||||
ViewManager.I.openBundlesView(panelName, data, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开弹窗面板
|
||||
* @param panelName 弹窗面板名称
|
||||
* @param data 传递的数据
|
||||
* @param callback 可选的回调函数
|
||||
*/
|
||||
public openPopupPanel(panelName: string, data: any = null, callback?: Function): void {
|
||||
if (!panelName) {
|
||||
console.error("[NavigationManager] openPopupPanel: panelName is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
const popupCallback = (panel: Node) => {
|
||||
if (!panel || !panel.isValid) {
|
||||
console.error("[NavigationManager] openPopupPanel: created panel is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
// 将弹窗添加到管理集合中
|
||||
this.popupPanels.add(panel);
|
||||
console.log(`[NavigationManager] Popup panel opened: ${panelName}, total popups: ${this.popupPanels.size}`);
|
||||
|
||||
if (callback) {
|
||||
callback(panel);
|
||||
}
|
||||
};
|
||||
|
||||
ViewManager.I.openBundlesPopupView(panelName, data, popupCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗面板
|
||||
* @param panel 要关闭的弹窗节点
|
||||
*/
|
||||
public closePopupPanel(panel: Node): void {
|
||||
if (!panel || !panel.isValid) {
|
||||
console.warn("[NavigationManager] closePopupPanel: panel is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
// 从弹窗管理集合中移除
|
||||
if (this.popupPanels.has(panel)) {
|
||||
this.popupPanels.delete(panel);
|
||||
console.log(`[NavigationManager] Popup panel closed: ${panel.name}, total popups: ${this.popupPanels.size}`);
|
||||
}
|
||||
|
||||
// 关闭面板
|
||||
try {
|
||||
const baseView = panel.getComponent(li_BaseView);
|
||||
if (baseView) {
|
||||
baseView.close();
|
||||
} else {
|
||||
panel.destroy();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[NavigationManager] closePopupPanel error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭所有弹窗
|
||||
*/
|
||||
private closeAllPopups(): void {
|
||||
if (this.popupPanels.size === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[NavigationManager] Closing all popups, count: ${this.popupPanels.size}`);
|
||||
|
||||
// 复制Set以避免在迭代过程中修改
|
||||
const popupPanelsToClose = Array.from(this.popupPanels);
|
||||
|
||||
for (const panel of popupPanelsToClose) {
|
||||
if (panel && panel.isValid) {
|
||||
this.closePopupPanel(panel);
|
||||
}
|
||||
}
|
||||
|
||||
// 确保清空集合
|
||||
this.popupPanels.clear();
|
||||
}
|
||||
public closeSubPanel(panel: Node | li_BaseView) {
|
||||
if (!panel) {
|
||||
console.warn("[NavigationManager] closeSubPanel: panel is null or undefined");
|
||||
return;
|
||||
}
|
||||
|
||||
let panelNode: Node;
|
||||
if (panel instanceof Node) {
|
||||
panelNode = panel;
|
||||
} else {
|
||||
panelNode = panel.node;
|
||||
}
|
||||
|
||||
if (!panelNode || !panelNode.isValid) {
|
||||
console.warn("[NavigationManager] closeSubPanel: panelNode is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
// 从subPanelMapping和subPanelDic中移除
|
||||
if (this.subPanelMapping.has(panelNode)) {
|
||||
const baseType = this.subPanelMapping.get(panelNode);
|
||||
const baseNode = this.panelCache.get(baseType);
|
||||
|
||||
if (baseNode && this.subPanelDic.has(baseNode)) {
|
||||
const subPanels = this.subPanelDic.get(baseNode);
|
||||
const index = subPanels.indexOf(panelNode);
|
||||
if (index !== -1) {
|
||||
subPanels.splice(index, 1);
|
||||
// 如果subPanels为空,删除整个条目
|
||||
if (subPanels.length === 0) {
|
||||
this.subPanelDic.delete(baseNode);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[NavigationManager] ${panelNode.name} 不在子页面列表中`);
|
||||
}
|
||||
}
|
||||
|
||||
this.subPanelMapping.delete(panelNode);
|
||||
}
|
||||
|
||||
// 销毁或关闭panel
|
||||
try {
|
||||
if (panel instanceof Node) {
|
||||
panel.destroy();
|
||||
} else {
|
||||
panel.close();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[NavigationManager] closeSubPanel error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取面板索引(用于动画方向计算)
|
||||
*/
|
||||
@@ -201,7 +391,7 @@ export class NavigationManager {
|
||||
return 0;
|
||||
case PanelType.GIRL_DETAIL:
|
||||
return 1;
|
||||
case PanelType.CHAT:
|
||||
case PanelType.PAST_GIRL_LIST:
|
||||
return 2;
|
||||
case PanelType.PERSONAL:
|
||||
return 3;
|
||||
@@ -209,6 +399,26 @@ export class NavigationManager {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
private getPanelType(node: Node): PanelType {
|
||||
if (!node || !node.isValid) {
|
||||
console.warn("[NavigationManager] getPanelType: node is invalid");
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (node.name) {
|
||||
case "ThemePanel":
|
||||
return PanelType.THEME;
|
||||
case "GirlDetailPanel":
|
||||
return PanelType.GIRL_DETAIL;
|
||||
case "PastGirlListPanel":
|
||||
return PanelType.PAST_GIRL_LIST;
|
||||
case "PersonalPanel":
|
||||
return PanelType.PERSONAL;
|
||||
default:
|
||||
console.warn(`[NavigationManager] Unknown panel type for node: ${node.name}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取面板名称
|
||||
@@ -224,8 +434,6 @@ export class NavigationManager {
|
||||
switch (panelType) {
|
||||
case PanelType.GIRL_DETAIL:
|
||||
return this.selectedGirlId; // 使用当前选中的角色ID
|
||||
case PanelType.CHAT:
|
||||
return { girlId: this.selectedGirlId }; // 使用当前选中的角色ID
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -242,6 +450,9 @@ export class NavigationManager {
|
||||
if (this.panelCache.has(panelType)) {
|
||||
const cachedPanel = this.panelCache.get(panelType);
|
||||
if (cachedPanel && cachedPanel.isValid) {
|
||||
// 确保缓存panel的subPanel状态正确,清理可能残留的subPanel引用
|
||||
this.clearSubPanels(cachedPanel, false); // 不销毁panel,只清理引用
|
||||
|
||||
// 特殊处理:主题面板刷新(避免重复调用Show)
|
||||
if (panelType === PanelType.THEME) {
|
||||
const themePanel = cachedPanel.getComponent(ThemePanel);
|
||||
@@ -268,72 +479,11 @@ export class NavigationManager {
|
||||
ViewManager.I.openBundlesView(panelName, openData, (panel: Node) => {
|
||||
if (panel && panel.isValid) {
|
||||
this.panelCache.set(panelType, panel);
|
||||
|
||||
if (panelName === "ThemePanel") {
|
||||
this.themePanel = panel.getComponent(ThemePanel);
|
||||
}
|
||||
|
||||
callback(panel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏当前面板及其子页面
|
||||
*/
|
||||
private hideCurrentPanelWithChildren(direction: "left" | "right") {
|
||||
if (!this.currentVisiblePanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果当前是ThemePanel,需要同时处理可能的子页面(GirlListPanel)
|
||||
if (this.currentActivePanelType === PanelType.THEME) {
|
||||
// 查找并隐藏GirlListPanel子页面
|
||||
this.hideThemePanelChildren(direction);
|
||||
|
||||
// 隐藏ThemePanel主面板
|
||||
this.hidePanelWithAnimation(this.currentVisiblePanel, direction);
|
||||
} else {
|
||||
// 其他面板直接隐藏
|
||||
this.hidePanelWithAnimation(this.currentVisiblePanel, direction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏ThemePanel的子页面
|
||||
*/
|
||||
private hideThemePanelChildren(direction: "left" | "right") {
|
||||
const themePanel = this.findThemePanelNode();
|
||||
if (themePanel) {
|
||||
// 获取子页面节点
|
||||
const childPanel = this.getThemePanelChildNode(themePanel);
|
||||
if (childPanel && childPanel.active) {
|
||||
console.log(
|
||||
"[NavigationManager] Hiding ThemePanel child with animation"
|
||||
);
|
||||
this.hidePanelWithAnimation(childPanel, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ThemePanel的子页面节点
|
||||
*/
|
||||
private getThemePanelChildNode(themePanel: ThemePanel): Node | null {
|
||||
try {
|
||||
// ThemePanel存储子页面在currentChildPanel属性中
|
||||
const childPanel = themePanel.getChildPanel();
|
||||
if (childPanel) return childPanel.node;
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"[NavigationManager] Error getting child panel node:",
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏面板动画
|
||||
*/
|
||||
@@ -347,16 +497,17 @@ export class NavigationManager {
|
||||
return;
|
||||
}
|
||||
|
||||
const animationCallback = () => {
|
||||
panel.active = false;
|
||||
// 使用统一的subPanel清理方法
|
||||
this.clearSubPanels(panel, true);
|
||||
callback && callback();
|
||||
};
|
||||
|
||||
if (direction === "left") {
|
||||
UITransitionHelper.slideOutToLeft(panel, 0.3, () => {
|
||||
panel.active = false;
|
||||
callback && callback();
|
||||
});
|
||||
UITransitionHelper.slideOutToLeft(panel, 0.3, animationCallback);
|
||||
} else {
|
||||
UITransitionHelper.slideOutToRight(panel, 0.3, () => {
|
||||
panel.active = false;
|
||||
callback && callback();
|
||||
});
|
||||
UITransitionHelper.slideOutToRight(panel, 0.3, animationCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,10 +526,6 @@ export class NavigationManager {
|
||||
|
||||
panel.active = true;
|
||||
|
||||
if (panel.name === "ThemePanel" && this.girlListPanel) {
|
||||
this.showPanelWithAnimation(this.girlListPanel.node, direction, callback);
|
||||
}
|
||||
|
||||
if (direction === "right") {
|
||||
UITransitionHelper.slideInFromRight(panel, 0.3, () => {
|
||||
callback && callback();
|
||||
@@ -390,15 +537,6 @@ export class NavigationManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 后备切换方法(当NavigationPanel未注册时)
|
||||
*/
|
||||
private fallbackSwitchPanel(panelType: PanelType): void {
|
||||
const panelName = this.getPanelName(panelType);
|
||||
const openData = this.getPanelData(panelType);
|
||||
ViewManager.I.openBundlesView(panelName, openData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前激活的面板类型
|
||||
*/
|
||||
@@ -440,152 +578,4 @@ export class NavigationManager {
|
||||
public getSelectedCategoryId(): number {
|
||||
return this.selectedCategoryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入角色列表页面(作为 ThemePanel 的子页面)
|
||||
*
|
||||
* @param {number} themeId - 主题ID,用于筛选角色
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* NavigationManager.Instance.navigateToGirlList(1);
|
||||
* ```
|
||||
*/
|
||||
public navigateToGirlList(themeId: number): void {
|
||||
if (themeId == null || themeId < 0) {
|
||||
console.warn("Invalid theme ID for girl list navigation:", themeId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新选中的主题ID
|
||||
this.setSelectedCategoryId(themeId);
|
||||
|
||||
console.log(
|
||||
`[NavigationManager] Navigating to girl list with theme ID: ${themeId}`
|
||||
);
|
||||
|
||||
// 先检查是否已有GirlListPanel存在
|
||||
const existingGirlListPanel = this.findExistingGirlListPanel();
|
||||
|
||||
if (existingGirlListPanel) {
|
||||
// 如果面板已存在,重新显示并刷新数据
|
||||
console.log("[NavigationManager] Reactivating existing GirlListPanel");
|
||||
this.reactivateGirlListPanel(existingGirlListPanel);
|
||||
} else {
|
||||
// 如果面板不存在,创建新的
|
||||
console.log("[NavigationManager] Creating new GirlListPanel");
|
||||
ViewManager.I.openBundlesView(
|
||||
"GirlListPanel",
|
||||
{
|
||||
themeId: themeId,
|
||||
parentPanel: "ThemePanel", // 标记父页面
|
||||
},
|
||||
(girlListPanelNode) => {
|
||||
this.girlListPanel = girlListPanelNode.getComponent(GirlListPanel);
|
||||
// 获取 ThemePanel 实例并设置子页面关系
|
||||
console.log(
|
||||
"[NavigationManager] GirlListPanel opened, setting up parent-child relationship"
|
||||
);
|
||||
this.setupParentChildRelationship(girlListPanelNode);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找已存在的GirlListPanel
|
||||
*/
|
||||
private findExistingGirlListPanel(): GirlListPanel {
|
||||
if (this.girlListPanel) return this.girlListPanel;
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新激活已存在的GirlListPanel
|
||||
*/
|
||||
private reactivateGirlListPanel(panel: GirlListPanel): void {
|
||||
try {
|
||||
// 重新激活面板
|
||||
panel.node.active = true;
|
||||
|
||||
// 获取面板组件并刷新数据
|
||||
//const girlListComponent = panelNode.getComponent("GirlListPanel");
|
||||
if (panel) {
|
||||
// 如果有刷新方法,调用它来更新主题数据
|
||||
panel.refresh();
|
||||
console.log(
|
||||
"[NavigationManager] GirlListPanel reactivated with theme:",
|
||||
this.selectedCategoryId
|
||||
);
|
||||
}
|
||||
|
||||
// 重新建立父子关系
|
||||
this.setupParentChildRelationship(panel);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"[NavigationManager] Error reactivating GirlListPanel:",
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立父子页面关系的私有方法
|
||||
* @private
|
||||
* @param girlListPanelNode GirlListPanel 节点
|
||||
*/
|
||||
private setupParentChildRelationship(girlListPanelNode: any): void {
|
||||
try {
|
||||
// 查找 ThemePanel 实例
|
||||
const themePanel = this.findThemePanelNode();
|
||||
if (themePanel) {
|
||||
const girlListPanelComponent =
|
||||
girlListPanelNode.getComponent(GirlListPanel);
|
||||
|
||||
if (themePanel && girlListPanelComponent) {
|
||||
console.log(
|
||||
"[NavigationManager] Setting up parent-child relationship"
|
||||
);
|
||||
this.themePanel.setChildPanel(girlListPanelComponent);
|
||||
} else {
|
||||
console.warn("[NavigationManager] Failed to get panel components");
|
||||
}
|
||||
} else {
|
||||
console.warn("[NavigationManager] ThemePanel not found");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"[NavigationManager] Error setting up parent-child relationship:",
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找 ThemePanel 节点的私有方法
|
||||
* @private
|
||||
* @returns ThemePanel 节点或 null
|
||||
*/
|
||||
private findThemePanelNode(): ThemePanel {
|
||||
if (this.themePanel) return this.themePanel;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理导航时 ThemePanel 子页面的隐藏逻辑
|
||||
* @private
|
||||
*/
|
||||
private handleThemePanelChildPanelsOnNavigation(): void {
|
||||
console.log(
|
||||
"[NavigationManager] Handling ThemePanel child panels on navigation"
|
||||
);
|
||||
|
||||
const themePanelNode = this.findThemePanelNode();
|
||||
if (themePanelNode) {
|
||||
if (themePanelNode && themePanelNode.hideChildPanel) {
|
||||
console.log("[NavigationManager] Closing ThemePanel child panels");
|
||||
themePanelNode.hideChildPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import { GirlData } from "../../data/GirlData";
|
||||
import { EnvData } from "../../data/EnvData";
|
||||
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
||||
import { GButton } from "../../../Main/Common/GButton";
|
||||
import { NavigationManager } from "../../manager/NavigationManager";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("ImagePopup")
|
||||
@@ -105,9 +106,9 @@ export class ImagePopup extends Component {
|
||||
url: girlData.getGrilPhotoPic(this.categoryId, this.girlId, this.resId),
|
||||
isImg: true,
|
||||
};
|
||||
ViewManager.I.openBundlesView("ShowPanel", data);
|
||||
NavigationManager.Instance.openPopupPanel("ShowPanel", data);
|
||||
} else {
|
||||
ViewManager.I.openBundlesView("PopupGirlDetailPanel", {
|
||||
NavigationManager.Instance.openPopupPanel("PopupGirlDetailPanel", {
|
||||
category: this.categoryId,
|
||||
resId: this.resId,
|
||||
girlId: this.girlId,
|
||||
|
||||
@@ -168,7 +168,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
);
|
||||
if (!isFree && !isRelease) {
|
||||
//未解锁
|
||||
ViewManager.I.openBundlesPopupView("GirlListPopupPanel", {
|
||||
NavigationManager.Instance.openPopupPanel("GirlListPopupPanel", {
|
||||
base: this,
|
||||
category: this.categoryId,
|
||||
id: this.id,
|
||||
@@ -507,7 +507,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
|
||||
NavigationManager.Instance.switchToPanel(PanelType.GIRL_DETAIL);
|
||||
}
|
||||
onClickRecord() {
|
||||
ViewManager.I.openBundlesView("RecordPanel", this.id);
|
||||
NavigationManager.Instance.openPopupPanel("RecordPanel", this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@ export class NavigationPanel extends li_BaseView {
|
||||
|
||||
private themeBtn: NavigationBtn;
|
||||
private girlDetailBtn: NavigationBtn;
|
||||
private chatBtn: NavigationBtn;
|
||||
private pastGirlListBtn: NavigationBtn;
|
||||
private settingBtn: NavigationBtn;
|
||||
|
||||
private loadingView: Node;
|
||||
@@ -26,7 +26,7 @@ export class NavigationPanel extends li_BaseView {
|
||||
this.themeBtn = this._nodeTab.themeBtn.getComponent(NavigationBtn);
|
||||
this.girlDetailBtn =
|
||||
this._nodeTab.girlDetailBtn.getComponent(NavigationBtn);
|
||||
this.chatBtn = this._nodeTab.chatBtn.getComponent(NavigationBtn);
|
||||
this.pastGirlListBtn = this._nodeTab.chatBtn.getComponent(NavigationBtn);
|
||||
this.settingBtn = this._nodeTab.settingBtn.getComponent(NavigationBtn);
|
||||
this.loadingView = this._nodeTab.loadingView;
|
||||
|
||||
@@ -36,7 +36,7 @@ export class NavigationPanel extends li_BaseView {
|
||||
NavigationManager.Instance.registerNavigationPanel(this);
|
||||
|
||||
this.registerListener();
|
||||
this.updateButtonStates(PanelType.THEME);
|
||||
this.updateButtonStates(PanelType.PAST_GIRL_LIST);
|
||||
|
||||
// 初次打开时通过NavigationManager切换到主题面板
|
||||
this.initializeFirstPanel();
|
||||
@@ -57,8 +57,8 @@ export class NavigationPanel extends li_BaseView {
|
||||
this
|
||||
);
|
||||
GButton.BandClick(
|
||||
this.chatBtn.node,
|
||||
() => NavigationManager.Instance.switchToPanel(PanelType.CHAT),
|
||||
this.pastGirlListBtn.node,
|
||||
() => NavigationManager.Instance.switchToPanel(PanelType.PAST_GIRL_LIST),
|
||||
this
|
||||
);
|
||||
GButton.BandClick(
|
||||
@@ -101,13 +101,13 @@ export class NavigationPanel extends li_BaseView {
|
||||
this.girlDetailBtn.setFocus(
|
||||
this.currentActivePanel === PanelType.GIRL_DETAIL
|
||||
);
|
||||
this.chatBtn.setFocus(this.currentActivePanel === PanelType.CHAT);
|
||||
this.pastGirlListBtn.setFocus(this.currentActivePanel === PanelType.PAST_GIRL_LIST);
|
||||
this.settingBtn.setFocus(this.currentActivePanel === PanelType.PERSONAL);
|
||||
}
|
||||
|
||||
private initializeFirstPanel() {
|
||||
// 初次打开时通过NavigationManager切换到主题面板
|
||||
NavigationManager.Instance.switchToPanel(PanelType.THEME, true);
|
||||
// 初次打开时通过NavigationManager切换到历史女孩列表面板
|
||||
NavigationManager.Instance.switchToPanel(PanelType.PAST_GIRL_LIST, true);
|
||||
}
|
||||
|
||||
public showPanel() {
|
||||
|
||||
@@ -294,6 +294,6 @@ export class RecordPanel extends li_BaseView {
|
||||
*/
|
||||
returnBtn() {
|
||||
this.onClose();
|
||||
ViewManager.I.closeView(this.node);
|
||||
this.close(); // 使用li_BaseView的close方法
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ export class ThemePanel extends li_BaseView {
|
||||
cache: ThemeItem[] = [];
|
||||
|
||||
// 子页面管理
|
||||
private listPanel: GirlListPanel = null;
|
||||
|
||||
// 加载状态保护
|
||||
private isLoading: boolean = false;
|
||||
@@ -209,7 +208,7 @@ export class ThemePanel extends li_BaseView {
|
||||
for (let id of themeIds) {
|
||||
let newNode = instantiate(this.itemInst.node);
|
||||
let item = newNode.getComponent(ThemeItem);
|
||||
item.refresh(id, this);
|
||||
item.refresh(id, this.node);
|
||||
newNode.active = true;
|
||||
this.cache.push(item);
|
||||
this.content.addChild(newNode);
|
||||
@@ -320,17 +319,11 @@ export class ThemePanel extends li_BaseView {
|
||||
} else {
|
||||
//未解锁
|
||||
|
||||
NavigationManager.Instance.openSubPanel("GirlListPopupPanel", this.node, {
|
||||
NavigationManager.Instance.openPopupPanel("GirlListPopupPanel", {
|
||||
base: this,
|
||||
category: girlData.getGrilCategoryById(this.recId),
|
||||
id: this.recId,
|
||||
});
|
||||
|
||||
// ViewManager.I.openBundlesPopupView("GirlListPopupPanel", {
|
||||
// base: this,
|
||||
// category: girlData.getGrilCategoryById(this.recId),
|
||||
// id: this.recId,
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,43 +387,11 @@ export class ThemePanel extends li_BaseView {
|
||||
}
|
||||
}
|
||||
|
||||
public getChildPanel(): GirlListPanel {
|
||||
if (this.listPanel) return this.listPanel;
|
||||
return null;
|
||||
}
|
||||
public setChildPanel(panel: GirlListPanel) {
|
||||
this.listPanel = panel;
|
||||
}
|
||||
/**
|
||||
* 隐藏子页面
|
||||
*/
|
||||
public hideChildPanel(): void {
|
||||
if (this.listPanel) {
|
||||
console.log("[ThemePanel] Closing child panel");
|
||||
if (this.listPanel.hide) {
|
||||
this.listPanel.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 关闭子页面
|
||||
*/
|
||||
public clostChildPanel(): void {
|
||||
if (this.listPanel) {
|
||||
console.log("[ThemePanel] Closing child panel");
|
||||
if (this.listPanel.close) {
|
||||
this.listPanel.close();
|
||||
}
|
||||
this.listPanel = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面被隐藏时调用
|
||||
*/
|
||||
public onHide(): void {
|
||||
console.log("[ThemePanel] onHide called");
|
||||
this.hideChildPanel();
|
||||
this.cancelCurrentOperation();
|
||||
}
|
||||
|
||||
@@ -451,9 +412,6 @@ export class ThemePanel extends li_BaseView {
|
||||
// 取消当前操作
|
||||
this.cancelCurrentOperation();
|
||||
|
||||
// 关闭子页面
|
||||
this.clostChildPanel();
|
||||
|
||||
// 清理缓存
|
||||
this.clearCache();
|
||||
|
||||
|
||||
@@ -69,21 +69,17 @@ export class DetailImageItem extends Component {
|
||||
},
|
||||
};
|
||||
if (this.url) {
|
||||
ViewManager.I.openBundlesView("ShowPanel", data);
|
||||
NavigationManager.Instance.openPopupPanel("ShowPanel", data);
|
||||
this.base.setVideEnable(false);
|
||||
}
|
||||
} else {
|
||||
NavigationManager.Instance.openSubPanel(
|
||||
"PopupGirlDetailPanel",
|
||||
this.base.node,
|
||||
{
|
||||
category: this.category,
|
||||
resId: this.resId,
|
||||
girlId: this.girlId,
|
||||
base: this,
|
||||
type: this.type,
|
||||
}
|
||||
);
|
||||
NavigationManager.Instance.openPopupPanel("PopupGirlDetailPanel", {
|
||||
category: this.category,
|
||||
resId: this.resId,
|
||||
girlId: this.girlId,
|
||||
base: this,
|
||||
type: this.type,
|
||||
});
|
||||
|
||||
// ViewManager.I.openBundlesView("PopupGirlDetailPanel", {
|
||||
// category: this.category,
|
||||
|
||||
@@ -216,16 +216,11 @@ export class GirlListItem extends Component {
|
||||
NavigationManager.Instance.switchToPanel(PanelType.GIRL_DETAIL);
|
||||
} else {
|
||||
//未解锁
|
||||
NavigationManager.Instance.openSubPanel("GirlListPopupPanel", this.baseNode, {
|
||||
NavigationManager.Instance.openPopupPanel("GirlListPopupPanel", {
|
||||
base: this,
|
||||
category: this.category,
|
||||
id: this.id,
|
||||
});
|
||||
// ViewManager.I.openBundlesPopupView("GirlListPopupPanel", {
|
||||
// base: this,
|
||||
// category: this.category,
|
||||
// id: this.id,
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { InnerMsgCode } from "../../Main/Config/InnerMsgCode";
|
||||
import { DataManager, DataId } from "../data/DataManager";
|
||||
import { GirlData } from "../data/GirlData";
|
||||
import { EnvData } from "../data/EnvData";
|
||||
import { ChatHistoryManager } from "../manager/ChatHistoryManager";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -63,11 +64,11 @@ export class PastGirlListItem extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
refreshData( girlId: number, baseNode: Node) {
|
||||
refreshData(girlId: number, baseNode: Node) {
|
||||
if (!this.stars) {
|
||||
this.stars = this.starParent.getComponentsInChildren(Sprite);
|
||||
}
|
||||
|
||||
|
||||
this.baseNode = baseNode;
|
||||
this.id = girlId;
|
||||
|
||||
@@ -120,21 +121,13 @@ export class PastGirlListItem extends Component {
|
||||
this.updateLastChatTime();
|
||||
}
|
||||
|
||||
// TODO: 实现获取最近聊天时间的逻辑
|
||||
// 需要从聊天记录中获取最后一条消息的时间戳
|
||||
private getLastChatTime(category: number, id: number): number | null {
|
||||
// TODO: 实现获取最近聊天时间的逻辑
|
||||
// 需要实现的逻辑:
|
||||
// 1. 获取该女孩的聊天记录
|
||||
// 2. 找到最后一条消息的时间戳
|
||||
// 3. 返回时间戳或null(如果没有聊天记录)
|
||||
console.log("TODO: 实现获取最近聊天时间逻辑");
|
||||
return null;
|
||||
private getLastChatTime(id: number): number | null {
|
||||
return ChatHistoryManager.Instance.getLastChatTime(id);
|
||||
}
|
||||
|
||||
// 更新最近聊天时间显示
|
||||
private updateLastChatTime() {
|
||||
const lastTime = this.getLastChatTime(this.category, this.id);
|
||||
const lastTime = this.getLastChatTime(this.id);
|
||||
this.lastChatTime.string = Utils.formatChatTime(lastTime);
|
||||
}
|
||||
|
||||
@@ -170,12 +163,17 @@ export class PastGirlListItem extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
onClickDetail() {
|
||||
// 由于都是已解锁的女孩,直接跳转到角色详情
|
||||
onClickGirl() {
|
||||
// 由于都是已解锁的女孩,直接打开聊天面板作为子面板
|
||||
// 先设置选中的角色ID
|
||||
NavigationManager.Instance.setSelectedGirlId(this.id);
|
||||
|
||||
// 通过switchToPanel切换到角色详情面板,保持动画和状态同步
|
||||
NavigationManager.Instance.switchToPanel(PanelType.GIRL_DETAIL);
|
||||
// 通过openSubPanel打开ChatPanel作为子面板
|
||||
const chatData = { girlId: this.id };
|
||||
NavigationManager.Instance.openSubPanel(
|
||||
"ChatPanel",
|
||||
this.baseNode,
|
||||
chatData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export class ThemeItem extends Component {
|
||||
|
||||
private isLocked: boolean;
|
||||
|
||||
private parentPanel: any;
|
||||
private baseNode: any;
|
||||
|
||||
key: string;
|
||||
protected onLoad(): void {
|
||||
@@ -62,9 +62,9 @@ export class ThemeItem extends Component {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
refresh(themeId: number, parentPanel?: any) {
|
||||
refresh(themeId: number, parentPanel?: Node) {
|
||||
if (this.loading) this.loading.active = true;
|
||||
this.parentPanel = parentPanel;
|
||||
this.baseNode = parentPanel;
|
||||
// 主题数据
|
||||
const themeData = DataManager.I.getDataById<ThemeData>(DataId.Theme);
|
||||
this.lockImg.node.active = this.lockCover.node.active =
|
||||
@@ -95,7 +95,7 @@ export class ThemeItem extends Component {
|
||||
"[ThemeItem] Opening GirlListPanel for category:",
|
||||
this.category
|
||||
);
|
||||
// 不使用过渡动画,直接打开
|
||||
NavigationManager.Instance.navigateToGirlList(this.category);
|
||||
NavigationManager.Instance.setSelectedCategoryId(this.category);
|
||||
NavigationManager.Instance.openSubPanel("GirlListPanel", this.baseNode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user