2025-08-11 16:08:59 +08:00
|
|
|
|
import { ViewManager } from "db://assets/Scripts/Main/Manager/ViewManager";
|
2025-08-25 20:15:42 +08:00
|
|
|
|
import { UITransitionHelper } from "../utils/UITransitionHelper";
|
2025-09-09 14:31:47 +08:00
|
|
|
|
import GameRootUI from "../../Main/Common/GameRootUI";
|
2025-09-12 18:20:41 +08:00
|
|
|
|
import { Node } from "cc";
|
|
|
|
|
|
import li_EventManager from "../../Main/Common/li_EventManager";
|
|
|
|
|
|
import { InnerMsgCode } from "../../Main/Config/InnerMsgCode";
|
|
|
|
|
|
import { ThemePanel } from "../ui/panels/ThemePanel";
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 页面过渡动画类型枚举
|
|
|
|
|
|
*/
|
|
|
|
|
|
export enum PageTransitionType {
|
|
|
|
|
|
NONE = "none",
|
|
|
|
|
|
SLIDE_LEFT = "slide_left",
|
|
|
|
|
|
SLIDE_RIGHT = "slide_right",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* NavigationPanel面板类型枚举
|
|
|
|
|
|
*/
|
|
|
|
|
|
export enum PanelType {
|
|
|
|
|
|
THEME = "ThemePanel",
|
|
|
|
|
|
GIRL_DETAIL = "GirlDetailPanel",
|
|
|
|
|
|
CHAT = "ChatPanel",
|
|
|
|
|
|
SETTING = "SettingPanel",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 页面过渡动画配置接口
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface PageTransitionConfig {
|
|
|
|
|
|
incomingTransition: PageTransitionType;
|
|
|
|
|
|
outgoingTransition: PageTransitionType;
|
|
|
|
|
|
duration?: number;
|
|
|
|
|
|
simultaneous?: boolean;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-11 16:08:59 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 导航管理器
|
2025-09-09 14:31:47 +08:00
|
|
|
|
*
|
2025-08-11 16:08:59 +08:00
|
|
|
|
* 负责管理游戏中的页面导航和路由,将导航逻辑从业务逻辑中分离出来
|
2025-09-12 18:20:41 +08:00
|
|
|
|
* 统一管理NavigationPanel和其他面板的切换
|
2025-09-09 14:31:47 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @author AI Chat System
|
2025-08-11 16:08:59 +08:00
|
|
|
|
* @version 1.0.0
|
|
|
|
|
|
*/
|
|
|
|
|
|
export class NavigationManager {
|
2025-09-09 14:31:47 +08:00
|
|
|
|
private static _instance: NavigationManager;
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
// NavigationPanel相关属性
|
|
|
|
|
|
private navigationPanel: any = null; // NavigationPanel实例引用
|
|
|
|
|
|
private currentActivePanel: PanelType = PanelType.THEME;
|
|
|
|
|
|
private panelCache: Map<PanelType, Node> = new Map(); // 面板缓存
|
|
|
|
|
|
private currentVisiblePanel: Node = null;
|
|
|
|
|
|
|
|
|
|
|
|
// 选中的角色相关信息
|
|
|
|
|
|
private selectedGirlId: number = 1; // 当前选中的角色ID
|
|
|
|
|
|
private selectedThemeId: number = 1; // 当前选中的主题ID
|
|
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取NavigationManager的单例实例
|
|
|
|
|
|
*
|
|
|
|
|
|
* @returns {NavigationManager} 导航管理器实例
|
|
|
|
|
|
* @static
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static get Instance(): NavigationManager {
|
|
|
|
|
|
if (!this._instance) {
|
|
|
|
|
|
this._instance = new NavigationManager();
|
|
|
|
|
|
}
|
|
|
|
|
|
return this._instance;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
private constructor() {
|
|
|
|
|
|
// 初始化事件监听
|
|
|
|
|
|
this.initEventListeners();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 初始化事件监听
|
|
|
|
|
|
*/
|
|
|
|
|
|
private initEventListeners(): void {
|
|
|
|
|
|
// 监听导航面板切换事件
|
|
|
|
|
|
li_EventManager.I.addInnerEL(
|
|
|
|
|
|
InnerMsgCode.Navigation_PanelSwitch,
|
|
|
|
|
|
this.onNavigationEvent,
|
|
|
|
|
|
this
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理导航事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
private onNavigationEvent(panelType: PanelType): void {
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] Received navigation event for:",
|
|
|
|
|
|
panelType
|
|
|
|
|
|
);
|
|
|
|
|
|
this.switchToPanel(panelType);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 注册NavigationPanel实例
|
|
|
|
|
|
* @param panel NavigationPanel实例
|
|
|
|
|
|
*/
|
|
|
|
|
|
public registerNavigationPanel(panel: any): void {
|
|
|
|
|
|
this.navigationPanel = panel;
|
|
|
|
|
|
console.log("[NavigationManager] NavigationPanel registered");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 统一的面板切换方法
|
|
|
|
|
|
* @param panelType 目标面板类型
|
|
|
|
|
|
*/
|
|
|
|
|
|
public switchToPanel(panelType: PanelType, force: boolean = false): void {
|
|
|
|
|
|
if (this.currentActivePanel === panelType && !force) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.navigationPanel) {
|
|
|
|
|
|
console.warn(
|
|
|
|
|
|
"[NavigationManager] NavigationPanel not registered, fallback to direct ViewManager call"
|
|
|
|
|
|
);
|
|
|
|
|
|
this.fallbackSwitchPanel(panelType);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 通知NavigationPanel显示加载状态
|
|
|
|
|
|
this.navigationPanel.showLoading?.();
|
|
|
|
|
|
|
|
|
|
|
|
// 计算动画方向
|
|
|
|
|
|
const currentIndex = this.getPanelIndex(this.currentActivePanel);
|
|
|
|
|
|
const targetIndex = this.getPanelIndex(panelType);
|
|
|
|
|
|
const isMovingRight = currentIndex < targetIndex;
|
|
|
|
|
|
|
|
|
|
|
|
const hideDirection = isMovingRight ? "left" : "right";
|
|
|
|
|
|
const showDirection = isMovingRight ? "right" : "left";
|
|
|
|
|
|
|
|
|
|
|
|
// 隐藏当前面板(包括子页面)
|
|
|
|
|
|
this.hideCurrentPanelWithChildren(hideDirection);
|
|
|
|
|
|
|
|
|
|
|
|
// 加载并显示目标面板
|
|
|
|
|
|
this.loadOrGetPanel(panelType, (panel: Node) => {
|
|
|
|
|
|
this.currentActivePanel = panelType;
|
|
|
|
|
|
this.currentVisiblePanel = panel;
|
|
|
|
|
|
|
|
|
|
|
|
// 更新NavigationPanel按钮状态
|
|
|
|
|
|
this.navigationPanel.updateButtonStates?.(panelType);
|
|
|
|
|
|
|
|
|
|
|
|
// 显示面板
|
|
|
|
|
|
this.showPanelWithAnimation(panel, showDirection, () => {
|
|
|
|
|
|
this.navigationPanel.hideLoading?.();
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取面板索引(用于动画方向计算)
|
|
|
|
|
|
*/
|
|
|
|
|
|
private getPanelIndex(panelType: PanelType): number {
|
|
|
|
|
|
switch (panelType) {
|
|
|
|
|
|
case PanelType.THEME:
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
case PanelType.GIRL_DETAIL:
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
case PanelType.CHAT:
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
case PanelType.SETTING:
|
|
|
|
|
|
return 3;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取面板名称
|
|
|
|
|
|
*/
|
|
|
|
|
|
private getPanelName(panelType: PanelType): string {
|
|
|
|
|
|
return panelType as string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取面板数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
private getPanelData(panelType: PanelType): any {
|
|
|
|
|
|
switch (panelType) {
|
|
|
|
|
|
case PanelType.GIRL_DETAIL:
|
|
|
|
|
|
return this.selectedGirlId; // 使用当前选中的角色ID
|
|
|
|
|
|
case PanelType.CHAT:
|
|
|
|
|
|
return { girlId: this.selectedGirlId }; // 使用当前选中的角色ID
|
|
|
|
|
|
default:
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 加载或获取面板
|
|
|
|
|
|
*/
|
|
|
|
|
|
private loadOrGetPanel(
|
|
|
|
|
|
panelType: PanelType,
|
|
|
|
|
|
callback: (panel: Node) => void
|
|
|
|
|
|
) {
|
|
|
|
|
|
// 检查缓存
|
|
|
|
|
|
if (this.panelCache.has(panelType)) {
|
|
|
|
|
|
const cachedPanel = this.panelCache.get(panelType);
|
|
|
|
|
|
if (cachedPanel && cachedPanel.isValid) {
|
|
|
|
|
|
// 特殊处理:主题面板刷新(避免重复调用Show)
|
|
|
|
|
|
if (panelType === PanelType.THEME) {
|
|
|
|
|
|
const themePanel = cachedPanel.getComponent(ThemePanel);
|
|
|
|
|
|
if (themePanel) {
|
|
|
|
|
|
// 不在这里调用Show(),因为ThemePanel已经有加载状态保护
|
|
|
|
|
|
// 只在必要时调用onHide()确保子页面状态正确
|
|
|
|
|
|
if (typeof themePanel.onHide === "function") {
|
|
|
|
|
|
console.log("[NavigationManager] 确保主题面板子页面状态正确");
|
|
|
|
|
|
themePanel.onHide();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
callback(cachedPanel);
|
|
|
|
|
|
return;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.panelCache.delete(panelType);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载新面板
|
|
|
|
|
|
const panelName = this.getPanelName(panelType);
|
|
|
|
|
|
const openData = this.getPanelData(panelType);
|
|
|
|
|
|
|
|
|
|
|
|
ViewManager.I.openBundlesView(panelName, openData, (panel: Node) => {
|
|
|
|
|
|
if (panel && panel.isValid) {
|
|
|
|
|
|
this.panelCache.set(panelType, panel);
|
|
|
|
|
|
callback(panel);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 隐藏当前面板及其子页面
|
|
|
|
|
|
*/
|
|
|
|
|
|
private hideCurrentPanelWithChildren(direction: "left" | "right") {
|
|
|
|
|
|
if (!this.currentVisiblePanel) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果当前是ThemePanel,需要同时处理可能的子页面(GirlListPanel)
|
|
|
|
|
|
if (this.currentActivePanel === 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 themePanelNode = this.findThemePanelNode();
|
|
|
|
|
|
if (themePanelNode) {
|
|
|
|
|
|
const themePanelComponent = themePanelNode.getComponent("ThemePanel");
|
|
|
|
|
|
if (themePanelComponent) {
|
|
|
|
|
|
// 获取子页面节点
|
|
|
|
|
|
const childPanel = this.getThemePanelChildNode(themePanelComponent);
|
|
|
|
|
|
if (childPanel && childPanel.active) {
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] Hiding ThemePanel child with animation"
|
|
|
|
|
|
);
|
|
|
|
|
|
this.hidePanelWithAnimation(childPanel, direction);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取ThemePanel的子页面节点
|
|
|
|
|
|
*/
|
|
|
|
|
|
private getThemePanelChildNode(themePanelComponent: any): Node | null {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// ThemePanel存储子页面在currentChildPanel属性中
|
|
|
|
|
|
if (
|
|
|
|
|
|
themePanelComponent.currentChildPanel &&
|
|
|
|
|
|
themePanelComponent.currentChildPanel.node
|
|
|
|
|
|
) {
|
|
|
|
|
|
return themePanelComponent.currentChildPanel.node;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有直接的引用,尝试通过ViewManager查找GirlListPanel
|
|
|
|
|
|
const viewList = (ViewManager.I as any).m_viewList;
|
|
|
|
|
|
if (viewList) {
|
|
|
|
|
|
for (let i = 0; i < viewList.length; i++) {
|
|
|
|
|
|
const view = viewList[i];
|
|
|
|
|
|
if (
|
|
|
|
|
|
view &&
|
|
|
|
|
|
view.isValid &&
|
|
|
|
|
|
view.name === "GirlListPanel" &&
|
|
|
|
|
|
view.active
|
|
|
|
|
|
) {
|
|
|
|
|
|
return view;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(
|
|
|
|
|
|
"[NavigationManager] Error getting child panel node:",
|
|
|
|
|
|
error
|
|
|
|
|
|
);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 隐藏面板动画
|
|
|
|
|
|
*/
|
|
|
|
|
|
private hidePanelWithAnimation(
|
|
|
|
|
|
panel: Node,
|
|
|
|
|
|
direction: "left" | "right",
|
|
|
|
|
|
callback?: Function
|
|
|
|
|
|
) {
|
|
|
|
|
|
if (!panel || !panel.isValid || !panel.active) {
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (direction === "left") {
|
|
|
|
|
|
UITransitionHelper.slideOutToLeft(panel, 0.3, () => {
|
|
|
|
|
|
panel.active = false;
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
UITransitionHelper.slideOutToRight(panel, 0.3, () => {
|
|
|
|
|
|
panel.active = false;
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 显示面板动画
|
|
|
|
|
|
*/
|
|
|
|
|
|
private showPanelWithAnimation(
|
|
|
|
|
|
panel: Node,
|
|
|
|
|
|
direction: "left" | "right",
|
|
|
|
|
|
callback?: Function
|
|
|
|
|
|
) {
|
|
|
|
|
|
if (!panel || !panel.isValid) {
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
panel.active = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (direction === "right") {
|
|
|
|
|
|
UITransitionHelper.slideInFromRight(panel, 0.3, () => {
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
UITransitionHelper.slideInFromLeft(panel, 0.3, () => {
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 后备切换方法(当NavigationPanel未注册时)
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fallbackSwitchPanel(panelType: PanelType): void {
|
|
|
|
|
|
const panelName = this.getPanelName(panelType);
|
|
|
|
|
|
const openData = this.getPanelData(panelType);
|
|
|
|
|
|
ViewManager.I.openBundlesView(panelName, openData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取当前激活的面板类型
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getCurrentActivePanel(): PanelType {
|
|
|
|
|
|
return this.currentActivePanel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 设置选中的角色ID
|
|
|
|
|
|
* @param girlId 角色ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setSelectedGirlId(girlId: number): void {
|
|
|
|
|
|
this.selectedGirlId = girlId;
|
|
|
|
|
|
console.log("[NavigationManager] Selected girl ID set to:", girlId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取当前选中的角色ID
|
|
|
|
|
|
* @returns 当前选中的角色ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getSelectedGirlId(): number {
|
|
|
|
|
|
return this.selectedGirlId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 设置选中的主题ID
|
|
|
|
|
|
* @param themeId 主题ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setSelectedThemeId(themeId: number): void {
|
|
|
|
|
|
this.selectedThemeId = themeId;
|
|
|
|
|
|
console.log("[NavigationManager] Selected theme ID set to:", themeId);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取当前选中的主题ID
|
|
|
|
|
|
* @returns 当前选中的主题ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getSelectedThemeId(): number {
|
|
|
|
|
|
return this.selectedThemeId;
|
|
|
|
|
|
}
|
2025-09-09 14:31:47 +08:00
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 通用页面导航方法,支持过渡动画
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {string} targetPanel - 目标面板名称
|
|
|
|
|
|
* @param {any} navigationData - 导航数据
|
|
|
|
|
|
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
|
|
|
|
|
|
* @param {any} currentPanel - 当前面板实例(可选)
|
|
|
|
|
|
* @param {Function} onComplete - 完成回调(可选)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateWithTransition(
|
|
|
|
|
|
* "ChatPanel",
|
|
|
|
|
|
* { roleId: 10001 },
|
|
|
|
|
|
* { incomingTransition: PageTransitionType.SLIDE_RIGHT, outgoingTransition: PageTransitionType.SLIDE_LEFT },
|
|
|
|
|
|
* currentPanel
|
|
|
|
|
|
* );
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public navigateWithTransition(
|
|
|
|
|
|
targetPanel: string,
|
|
|
|
|
|
navigationData: any,
|
|
|
|
|
|
transitionConfig: PageTransitionConfig,
|
|
|
|
|
|
currentPanel?: any,
|
|
|
|
|
|
onComplete?: Function
|
|
|
|
|
|
): void {
|
|
|
|
|
|
if (!targetPanel) {
|
|
|
|
|
|
console.warn("NavigationManager: Target panel name is required");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
`Navigating to ${targetPanel} with transition:`,
|
|
|
|
|
|
transitionConfig
|
|
|
|
|
|
);
|
|
|
|
|
|
//const correntPos = currentPanel.node.position;
|
|
|
|
|
|
const duration = transitionConfig.duration || 0.1;
|
|
|
|
|
|
const useTransition =
|
|
|
|
|
|
transitionConfig.incomingTransition !== PageTransitionType.NONE ||
|
|
|
|
|
|
transitionConfig.outgoingTransition !== PageTransitionType.NONE;
|
|
|
|
|
|
|
|
|
|
|
|
if (!useTransition) {
|
2025-09-12 18:20:41 +08:00
|
|
|
|
// 在没有过渡动画的情况下,也需要处理子页面逻辑
|
|
|
|
|
|
if (targetPanel && targetPanel !== "GirlListPanel") {
|
|
|
|
|
|
this.handleThemePanelChildPanelsOnNavigation();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
ViewManager.I.openBundlesView(targetPanel, navigationData, onComplete);
|
|
|
|
|
|
if (
|
|
|
|
|
|
currentPanel &&
|
|
|
|
|
|
currentPanel.onClose &&
|
|
|
|
|
|
typeof currentPanel.onClose === "function"
|
|
|
|
|
|
) {
|
|
|
|
|
|
currentPanel.onClose();
|
|
|
|
|
|
//currentPanel.node.position = correntPos;
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 18:49:27 +08:00
|
|
|
|
ViewManager.I.openBundlesView(targetPanel, navigationData, (targetNode) => {
|
|
|
|
|
|
this._executeTransition(
|
|
|
|
|
|
targetNode,
|
|
|
|
|
|
currentPanel,
|
|
|
|
|
|
transitionConfig,
|
|
|
|
|
|
duration,
|
|
|
|
|
|
onComplete
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
2025-09-11 17:07:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 执行页面过渡动画的私有方法
|
|
|
|
|
|
*
|
|
|
|
|
|
* @private
|
|
|
|
|
|
* @param {any} targetNode - 目标节点
|
|
|
|
|
|
* @param {any} currentPanel - 当前面板
|
|
|
|
|
|
* @param {PageTransitionConfig} config - 动画配置
|
|
|
|
|
|
* @param {number} duration - 动画时长
|
|
|
|
|
|
* @param {Function} onComplete - 完成回调
|
|
|
|
|
|
*/
|
|
|
|
|
|
private _executeTransition(
|
|
|
|
|
|
targetNode: any,
|
|
|
|
|
|
currentPanel: any,
|
|
|
|
|
|
config: PageTransitionConfig,
|
|
|
|
|
|
duration: number,
|
|
|
|
|
|
onComplete?: Function
|
|
|
|
|
|
): void {
|
2025-09-12 18:20:41 +08:00
|
|
|
|
const targetPanelName = targetNode ? targetNode.name : null;
|
2025-09-11 17:07:29 +08:00
|
|
|
|
const executeIncomingAnimation = (callback?: Function) => {
|
|
|
|
|
|
if (
|
|
|
|
|
|
config.incomingTransition === PageTransitionType.NONE ||
|
|
|
|
|
|
!targetNode
|
|
|
|
|
|
) {
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (config.incomingTransition) {
|
|
|
|
|
|
case PageTransitionType.SLIDE_RIGHT:
|
|
|
|
|
|
UITransitionHelper.slideInFromRight(targetNode, duration, callback);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case PageTransitionType.SLIDE_LEFT:
|
|
|
|
|
|
UITransitionHelper.slideInFromLeft(targetNode, duration, callback);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const executeOutgoingAnimation = (callback?: Function) => {
|
|
|
|
|
|
if (
|
|
|
|
|
|
config.outgoingTransition === PageTransitionType.NONE ||
|
|
|
|
|
|
!currentPanel ||
|
|
|
|
|
|
!currentPanel.node ||
|
|
|
|
|
|
!currentPanel.node.isValid
|
|
|
|
|
|
) {
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (config.outgoingTransition) {
|
|
|
|
|
|
case PageTransitionType.SLIDE_LEFT:
|
|
|
|
|
|
UITransitionHelper.slideOutToLeft(
|
|
|
|
|
|
currentPanel.node,
|
|
|
|
|
|
duration,
|
|
|
|
|
|
callback
|
|
|
|
|
|
);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case PageTransitionType.SLIDE_RIGHT:
|
|
|
|
|
|
UITransitionHelper.slideOutToRight(
|
|
|
|
|
|
currentPanel.node,
|
|
|
|
|
|
duration,
|
|
|
|
|
|
callback
|
|
|
|
|
|
);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
callback && callback();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const closeCurrentPanel = () => {
|
|
|
|
|
|
if (
|
|
|
|
|
|
currentPanel &&
|
|
|
|
|
|
currentPanel.onClose &&
|
|
|
|
|
|
typeof currentPanel.onClose === "function"
|
|
|
|
|
|
) {
|
2025-09-12 18:20:41 +08:00
|
|
|
|
if (currentPanel.node.name !== "ThemePanel") {
|
|
|
|
|
|
currentPanel.onClose();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果当前面板是 ThemePanel,检查是否需要关闭子页面
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] ThemePanel detected, checking for child panels"
|
|
|
|
|
|
);
|
|
|
|
|
|
if (
|
|
|
|
|
|
currentPanel.closeChildPanel &&
|
|
|
|
|
|
typeof currentPanel.closeChildPanel === "function"
|
|
|
|
|
|
) {
|
|
|
|
|
|
currentPanel.closeChildPanel();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-11 17:07:29 +08:00
|
|
|
|
}
|
2025-09-12 18:20:41 +08:00
|
|
|
|
|
|
|
|
|
|
// 检查目标面板是否会导致需要隐藏 ThemePanel 的子页面
|
|
|
|
|
|
if (targetPanelName && targetPanelName !== "GirlListPanel") {
|
|
|
|
|
|
this.handleThemePanelChildPanelsOnNavigation();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
onComplete && onComplete();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (config.simultaneous) {
|
|
|
|
|
|
let completedAnimations = 0;
|
|
|
|
|
|
const animationComplete = () => {
|
|
|
|
|
|
completedAnimations++;
|
|
|
|
|
|
if (completedAnimations >= 2) {
|
|
|
|
|
|
closeCurrentPanel();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
executeIncomingAnimation(animationComplete);
|
|
|
|
|
|
executeOutgoingAnimation(animationComplete);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
executeOutgoingAnimation(() => {
|
|
|
|
|
|
executeIncomingAnimation(closeCurrentPanel);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
2025-09-12 18:20:41 +08:00
|
|
|
|
* 进入角色列表页面(作为 ThemePanel 的子页面)
|
2025-09-09 14:31:47 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @param {number} themeId - 主题ID,用于筛选角色
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateToGirlList(1);
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
2025-09-12 18:20:41 +08:00
|
|
|
|
public navigateToGirlList(themeId: number): void {
|
2025-09-09 14:31:47 +08:00
|
|
|
|
if (themeId == null || themeId < 0) {
|
|
|
|
|
|
console.warn("Invalid theme ID for girl list navigation:", themeId);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
// 更新选中的主题ID
|
|
|
|
|
|
this.setSelectedThemeId(themeId);
|
2025-09-11 17:07:29 +08:00
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
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, themeId);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果面板不存在,创建新的
|
|
|
|
|
|
console.log("[NavigationManager] Creating new GirlListPanel");
|
|
|
|
|
|
ViewManager.I.openBundlesView(
|
2025-09-11 17:07:29 +08:00
|
|
|
|
"GirlListPanel",
|
2025-09-12 18:20:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
themeId: themeId,
|
|
|
|
|
|
parentPanel: "ThemePanel", // 标记父页面
|
|
|
|
|
|
},
|
|
|
|
|
|
(girlListPanelNode) => {
|
|
|
|
|
|
// 获取 ThemePanel 实例并设置子页面关系
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] GirlListPanel opened, setting up parent-child relationship"
|
|
|
|
|
|
);
|
|
|
|
|
|
this.setupParentChildRelationship(girlListPanelNode);
|
2025-09-11 17:07:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
);
|
2025-09-12 18:20:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查找已存在的GirlListPanel
|
|
|
|
|
|
*/
|
|
|
|
|
|
private findExistingGirlListPanel(): any {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const viewList = (ViewManager.I as any).m_viewList;
|
|
|
|
|
|
if (viewList) {
|
|
|
|
|
|
for (let i = 0; i < viewList.length; i++) {
|
|
|
|
|
|
const view = viewList[i];
|
|
|
|
|
|
if (view && view.isValid && view.name === "GirlListPanel") {
|
|
|
|
|
|
return view;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(
|
|
|
|
|
|
"[NavigationManager] Error finding existing GirlListPanel:",
|
|
|
|
|
|
error
|
|
|
|
|
|
);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 重新激活已存在的GirlListPanel
|
|
|
|
|
|
*/
|
|
|
|
|
|
private reactivateGirlListPanel(panelNode: any, themeId: number): void {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 重新激活面板
|
|
|
|
|
|
panelNode.active = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取面板组件并刷新数据
|
|
|
|
|
|
const girlListComponent = panelNode.getComponent("GirlListPanel");
|
|
|
|
|
|
if (girlListComponent) {
|
|
|
|
|
|
// 如果有刷新方法,调用它来更新主题数据
|
|
|
|
|
|
if (typeof girlListComponent.refreshWithTheme === "function") {
|
|
|
|
|
|
girlListComponent.refreshWithTheme(themeId);
|
|
|
|
|
|
} else if (typeof girlListComponent.Show === "function") {
|
|
|
|
|
|
girlListComponent.Show(themeId);
|
|
|
|
|
|
}
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] GirlListPanel reactivated with theme:",
|
|
|
|
|
|
themeId
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 重新建立父子关系
|
|
|
|
|
|
this.setupParentChildRelationship(panelNode);
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(
|
|
|
|
|
|
"[NavigationManager] Error reactivating GirlListPanel:",
|
|
|
|
|
|
error
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 建立父子页面关系的私有方法
|
|
|
|
|
|
* @private
|
|
|
|
|
|
* @param girlListPanelNode GirlListPanel 节点
|
|
|
|
|
|
*/
|
|
|
|
|
|
private setupParentChildRelationship(girlListPanelNode: any): void {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 查找 ThemePanel 实例
|
|
|
|
|
|
const themePanelNode = this.findThemePanelNode();
|
|
|
|
|
|
if (themePanelNode) {
|
|
|
|
|
|
const themePanelComponent = themePanelNode.getComponent("ThemePanel");
|
|
|
|
|
|
const girlListPanelComponent =
|
|
|
|
|
|
girlListPanelNode.getComponent("GirlListPanel");
|
|
|
|
|
|
|
|
|
|
|
|
if (themePanelComponent && girlListPanelComponent) {
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] Setting up parent-child relationship"
|
|
|
|
|
|
);
|
|
|
|
|
|
themePanelComponent.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(): any {
|
|
|
|
|
|
console.log("[NavigationManager] Finding ThemePanel node...");
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 通过 ViewManager 的视图列表查找 ThemePanel
|
|
|
|
|
|
const viewList = (ViewManager.I as any).m_viewList;
|
|
|
|
|
|
if (viewList) {
|
|
|
|
|
|
for (let i = 0; i < viewList.length; i++) {
|
|
|
|
|
|
const view = viewList[i];
|
|
|
|
|
|
if (view && view.isValid && view.name === "ThemePanel") {
|
|
|
|
|
|
console.log("[NavigationManager] Found ThemePanel node");
|
|
|
|
|
|
return view;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log("[NavigationManager] ThemePanel not found in view list");
|
|
|
|
|
|
return null;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("[NavigationManager] Error finding ThemePanel:", error);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理导航时 ThemePanel 子页面的隐藏逻辑
|
|
|
|
|
|
* @private
|
|
|
|
|
|
*/
|
|
|
|
|
|
private handleThemePanelChildPanelsOnNavigation(): void {
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"[NavigationManager] Handling ThemePanel child panels on navigation"
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const themePanelNode = this.findThemePanelNode();
|
|
|
|
|
|
if (themePanelNode) {
|
|
|
|
|
|
const themePanelComponent = themePanelNode.getComponent("ThemePanel");
|
|
|
|
|
|
if (themePanelComponent && themePanelComponent.closeChildPanel) {
|
|
|
|
|
|
console.log("[NavigationManager] Closing ThemePanel child panels");
|
|
|
|
|
|
themePanelComponent.closeChildPanel();
|
|
|
|
|
|
}
|
2025-09-11 17:07:29 +08:00
|
|
|
|
}
|
2025-09-09 14:31:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 进入聊天页面
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {number} roleId - 角色ID
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateToChat(10001);
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
2025-09-11 17:07:29 +08:00
|
|
|
|
public navigateToChat(roleId: number): void;
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 进入聊天页面(带过渡动画)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {number} roleId - 角色ID
|
|
|
|
|
|
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
|
|
|
|
|
|
* @param {any} currentPanel - 当前面板实例(可选)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateToChat(10001,
|
|
|
|
|
|
* { incomingTransition: PageTransitionType.FADE, outgoingTransition: PageTransitionType.SLIDE_LEFT },
|
|
|
|
|
|
* this
|
|
|
|
|
|
* );
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public navigateToChat(
|
|
|
|
|
|
roleId: number,
|
|
|
|
|
|
transitionConfig?: PageTransitionConfig,
|
|
|
|
|
|
currentPanel?: any
|
|
|
|
|
|
): void;
|
|
|
|
|
|
public navigateToChat(
|
|
|
|
|
|
roleId: number,
|
|
|
|
|
|
transitionConfig?: PageTransitionConfig,
|
|
|
|
|
|
currentPanel?: any
|
|
|
|
|
|
): void {
|
2025-09-09 14:31:47 +08:00
|
|
|
|
if (roleId == null || roleId <= 0) {
|
|
|
|
|
|
console.warn("Invalid role ID for chat navigation:", roleId);
|
|
|
|
|
|
return;
|
2025-08-11 16:08:59 +08:00
|
|
|
|
}
|
2025-09-12 18:20:41 +08:00
|
|
|
|
|
|
|
|
|
|
// 更新选中的角色ID
|
|
|
|
|
|
this.setSelectedGirlId(roleId);
|
|
|
|
|
|
|
|
|
|
|
|
// NavigationPanel 始终显示,不需要隐藏 DefaultView
|
2025-09-09 14:31:47 +08:00
|
|
|
|
console.log(`Navigating to chat with role ID: ${roleId}`);
|
2025-09-11 17:07:29 +08:00
|
|
|
|
|
|
|
|
|
|
if (transitionConfig) {
|
|
|
|
|
|
this.navigateWithTransition(
|
|
|
|
|
|
"ChatPanel",
|
|
|
|
|
|
roleId,
|
|
|
|
|
|
transitionConfig,
|
|
|
|
|
|
currentPanel
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ViewManager.I.openBundlesView("ChatPanel", roleId);
|
|
|
|
|
|
}
|
2025-09-09 14:31:47 +08:00
|
|
|
|
}
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 带过渡动画进入聊天页面
|
|
|
|
|
|
* 从GirlDetailPanel平滑过渡到ChatPanel
|
|
|
|
|
|
*
|
2025-09-11 17:07:29 +08:00
|
|
|
|
* @param {string} categoryId - 类别ID
|
2025-09-09 14:31:47 +08:00
|
|
|
|
* @param {number} roleId - 角色ID
|
|
|
|
|
|
* @param {any} currentPanel - 当前面板实例(GirlDetailPanel)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
2025-09-11 17:07:29 +08:00
|
|
|
|
* NavigationManager.Instance.navigateToChatWithTransition("1", 10001, this);
|
2025-09-09 14:31:47 +08:00
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public navigateToChatWithTransition(
|
2025-09-10 16:43:46 +08:00
|
|
|
|
categoryId: string,
|
2025-09-09 14:31:47 +08:00
|
|
|
|
roleId: number,
|
|
|
|
|
|
currentPanel?: any
|
|
|
|
|
|
): void {
|
|
|
|
|
|
if (roleId == null || roleId <= 0) {
|
|
|
|
|
|
console.warn(
|
|
|
|
|
|
"Invalid role ID for chat navigation with transition:",
|
|
|
|
|
|
roleId
|
|
|
|
|
|
);
|
|
|
|
|
|
return;
|
2025-08-11 16:08:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
// 更新选中的角色ID和主题ID
|
|
|
|
|
|
this.setSelectedGirlId(roleId);
|
|
|
|
|
|
if (categoryId != null) {
|
|
|
|
|
|
this.setSelectedThemeId(parseInt(categoryId));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
const navigationData = {
|
|
|
|
|
|
categoryId: categoryId,
|
|
|
|
|
|
roleId: roleId,
|
|
|
|
|
|
};
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-11 17:07:29 +08:00
|
|
|
|
const transitionConfig: PageTransitionConfig = {
|
|
|
|
|
|
incomingTransition: PageTransitionType.SLIDE_RIGHT,
|
|
|
|
|
|
outgoingTransition: PageTransitionType.SLIDE_LEFT,
|
|
|
|
|
|
duration: 0.3,
|
|
|
|
|
|
simultaneous: true,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
this.navigateWithTransition(
|
2025-09-09 14:31:47 +08:00
|
|
|
|
"ChatPanel",
|
2025-09-11 17:07:29 +08:00
|
|
|
|
navigationData,
|
|
|
|
|
|
transitionConfig,
|
|
|
|
|
|
currentPanel
|
2025-09-09 14:31:47 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 进入角色详情页面
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {number} roleId - 角色ID
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateToGirlDetail(10001);
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
2025-09-11 17:07:29 +08:00
|
|
|
|
public navigateToGirlDetail(roleId: number): void;
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 进入角色详情页面(带过渡动画)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {number} roleId - 角色ID
|
|
|
|
|
|
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
|
|
|
|
|
|
* @param {any} currentPanel - 当前面板实例(可选)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateToGirlDetail(10001,
|
|
|
|
|
|
* { incomingTransition: PageTransitionType.SLIDE_RIGHT, outgoingTransition: PageTransitionType.SLIDE_LEFT },
|
|
|
|
|
|
* this
|
|
|
|
|
|
* );
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public navigateToGirlDetail(
|
|
|
|
|
|
roleId: number,
|
|
|
|
|
|
transitionConfig?: PageTransitionConfig,
|
|
|
|
|
|
currentPanel?: any
|
|
|
|
|
|
): void;
|
|
|
|
|
|
public navigateToGirlDetail(
|
|
|
|
|
|
roleId: number,
|
|
|
|
|
|
transitionConfig?: PageTransitionConfig,
|
|
|
|
|
|
currentPanel?: any
|
|
|
|
|
|
): void {
|
2025-09-09 14:31:47 +08:00
|
|
|
|
if (roleId == null || roleId <= 0) {
|
|
|
|
|
|
console.warn("Invalid role ID for detail navigation:", roleId);
|
|
|
|
|
|
return;
|
2025-08-11 16:08:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 18:20:41 +08:00
|
|
|
|
// 更新选中的角色ID
|
|
|
|
|
|
this.setSelectedGirlId(roleId);
|
|
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
console.log(`Navigating to girl detail with role ID: ${roleId}`);
|
2025-09-11 17:07:29 +08:00
|
|
|
|
|
|
|
|
|
|
if (transitionConfig) {
|
|
|
|
|
|
this.navigateWithTransition(
|
|
|
|
|
|
"GirlDetailPanel",
|
|
|
|
|
|
roleId,
|
|
|
|
|
|
transitionConfig,
|
|
|
|
|
|
currentPanel
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ViewManager.I.openBundlesView("GirlDetailPanel", roleId);
|
|
|
|
|
|
}
|
2025-09-09 14:31:47 +08:00
|
|
|
|
}
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 返回主界面
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* NavigationManager.Instance.navigateToMainMenu();
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public navigateToMainMenu(): void {
|
|
|
|
|
|
console.log("Navigating to main menu");
|
|
|
|
|
|
// TODO: 实现返回主界面的逻辑
|
|
|
|
|
|
// ViewManager.I.openBundlesView("MainMenu");
|
|
|
|
|
|
}
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 检查是否可以导航到指定页面
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {string} pageName - 页面名称
|
|
|
|
|
|
* @returns {boolean} 是否可以导航
|
|
|
|
|
|
*/
|
|
|
|
|
|
public canNavigateTo(pageName: string): boolean {
|
|
|
|
|
|
const allowedPages = ["GirlListPanel", "ChatPanel", "GirlDetailPanel"];
|
|
|
|
|
|
return allowedPages.indexOf(pageName) >= 0;
|
|
|
|
|
|
}
|
2025-08-11 16:08:59 +08:00
|
|
|
|
|
2025-09-09 14:31:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取当前页面的导航历史(预留功能)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @returns {string[]} 导航历史数组
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getNavigationHistory(): string[] {
|
|
|
|
|
|
// TODO: 实现导航历史记录功能
|
|
|
|
|
|
console.log("Navigation history feature not implemented yet");
|
|
|
|
|
|
return [];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 返回上一页(预留功能)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public goBack(): void {
|
|
|
|
|
|
// TODO: 实现返回上一页功能
|
|
|
|
|
|
console.log("Go back feature not implemented yet");
|
|
|
|
|
|
}
|
2025-09-11 17:07:29 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取预设的过渡动画配置
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static getTransitionPresets() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
SLIDE_LEFT_TO_RIGHT: {
|
|
|
|
|
|
incomingTransition: PageTransitionType.SLIDE_RIGHT,
|
|
|
|
|
|
outgoingTransition: PageTransitionType.SLIDE_LEFT,
|
|
|
|
|
|
duration: 0.1,
|
|
|
|
|
|
simultaneous: true,
|
|
|
|
|
|
} as PageTransitionConfig,
|
|
|
|
|
|
|
|
|
|
|
|
SLIDE_RIGHT_TO_LEFT: {
|
|
|
|
|
|
incomingTransition: PageTransitionType.SLIDE_LEFT,
|
|
|
|
|
|
outgoingTransition: PageTransitionType.SLIDE_RIGHT,
|
|
|
|
|
|
duration: 0.1,
|
|
|
|
|
|
simultaneous: true,
|
|
|
|
|
|
} as PageTransitionConfig,
|
|
|
|
|
|
|
|
|
|
|
|
SLIDE_OVER: {
|
|
|
|
|
|
incomingTransition: PageTransitionType.SLIDE_RIGHT,
|
|
|
|
|
|
outgoingTransition: PageTransitionType.NONE,
|
|
|
|
|
|
duration: 0.1,
|
|
|
|
|
|
simultaneous: true,
|
|
|
|
|
|
} as PageTransitionConfig,
|
|
|
|
|
|
|
|
|
|
|
|
SLIDE_UNDER: {
|
|
|
|
|
|
incomingTransition: PageTransitionType.NONE,
|
|
|
|
|
|
outgoingTransition: PageTransitionType.SLIDE_LEFT,
|
|
|
|
|
|
duration: 0.1,
|
|
|
|
|
|
simultaneous: true,
|
|
|
|
|
|
} as PageTransitionConfig,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2025-09-09 14:31:47 +08:00
|
|
|
|
}
|