Merge branch 'main' of 47.107.44.202:xionglijia/18xchat

This commit is contained in:
chen wei bo
2025-10-13 17:18:05 +08:00
17 changed files with 406 additions and 275 deletions
+5 -1
View File
@@ -101,7 +101,11 @@ export class ViewManager extends Component {
// t_node.sType = "top"
GameRootUI.I.AddUIToLayer(t_node, CommonConfig.UILayerGroup.Layer_top);
} else if (type == "tips") {
GameRootUI.I.AddUIToLayer(t_node, CommonConfig.UILayerGroup.Layer_tips);
GameRootUI.I.AddUIToLayer(
t_node,
CommonConfig.UILayerGroup.Layer_tips,
-1
);
}
}
+14 -5
View File
@@ -96,7 +96,7 @@ export class PreloadUI extends Component {
this.desc = this._nodeTab.Desc.getComponent(Label);
// 设置视频为静音,提高移动端自动播放成功率
this.VideoPlayer.muted = true;
this.VideoPlayer.mute = true;
this.VideoPlayer.loop = true;
this.VideoPlayer.stayOnBottom = true;
@@ -205,16 +205,25 @@ export class PreloadUI extends Component {
// 尝试播放视频
try {
this.VideoPlayer.play();
logger.log(`PreloadUI: Video play attempted (retry: ${this.videoPlayRetryCount}/${this.maxVideoPlayRetry})`);
logger.log(
`PreloadUI: Video play attempted (retry: ${this.videoPlayRetryCount}/${this.maxVideoPlayRetry})`
);
// 延迟检查播放状态,如果失败则重试
this.scheduleOnce(() => {
if (!this.VideoPlayer.isPlaying && this.videoPlayRetryCount < this.maxVideoPlayRetry) {
if (
!this.VideoPlayer.isPlaying &&
this.videoPlayRetryCount < this.maxVideoPlayRetry
) {
this.videoPlayRetryCount++;
logger.warn(`PreloadUI: Video play failed, retrying... (${this.videoPlayRetryCount}/${this.maxVideoPlayRetry})`);
logger.warn(
`PreloadUI: Video play failed, retrying... (${this.videoPlayRetryCount}/${this.maxVideoPlayRetry})`
);
this.tryPlayVideo();
} else if (!this.VideoPlayer.isPlaying) {
logger.warn("PreloadUI: Video autoplay failed after max retries. Will retry on user interaction.");
logger.warn(
"PreloadUI: Video autoplay failed after max retries. Will retry on user interaction."
);
}
}, 0.5);
} catch (error) {
+17 -2
View File
@@ -43,6 +43,7 @@ export class ChatAIService {
private ai: GoogleGenAI;
private chatInstances: Map<number, any> = new Map();
private currentRoleId: number | null = null;
private shouldShowErrorTips: boolean = true; // 控制是否显示错误提示
private constructor() {
const config = ApiConfig.Instance.getAIConfig();
@@ -98,6 +99,14 @@ export class ChatAIService {
return this._instance;
}
/**
* 设置是否显示错误提示
* @param show 是否显示
*/
public setShouldShowErrorTips(show: boolean): void {
this.shouldShowErrorTips = show;
}
/**
* 创建或获取指定角色的聊天实例
* @param roleId 角色ID
@@ -306,7 +315,10 @@ export class ChatAIService {
return response.text;
} else {
TipsPanel.show(response.promptFeedback.blockReason);
// 只在允许显示错误提示时才显示
if (this.shouldShowErrorTips) {
TipsPanel.show(response.promptFeedback.blockReason);
}
const warningMsg = `AI返回了空响应 (角色ID: ${roleId})`;
ErrorHandler.Instance.handleError(
new Error(warningMsg),
@@ -321,7 +333,10 @@ export class ChatAIService {
roleId,
message: message,
});
TipsPanel.show("api调用失败,请使用vpn并重新启动");
// 只在允许显示错误提示时才显示
if (this.shouldShowErrorTips) {
TipsPanel.show("api调用失败,请使用vpn并重新启动");
}
return null;
}
}
+13 -2
View File
@@ -208,6 +208,12 @@ export class ChatController {
message
);
// 检查View是否仍然绑定,如果已解绑则不处理响应(用户可能已退出Panel)
if (!this.callback) {
logger.log("ChatController: View已解绑,忽略AI响应");
return false;
}
if (response) {
// 添加用户消息到模型
this.chatModel.addDialog(true, message);
@@ -232,7 +238,7 @@ export class ChatController {
return false;
}
} catch (error) {
ErrorHandler.Instance.handleApiError(
error,
"ChatController.sendMessage",
@@ -241,7 +247,12 @@ export class ChatController {
message: message.substring(0, 100) + "...",
}
);
this.handleError(error as Error);
// 只有当View仍然绑定时才调用错误处理回调
if (this.callback) {
this.handleError(error as Error);
} else {
logger.log("ChatController: View已解绑,不显示错误提示");
}
return false;
}
}
@@ -169,15 +169,21 @@ export class NavigationManager {
const hideDirection = isMovingRight ? "left" : "right";
const showDirection = isMovingRight ? "right" : "left";
// 隐藏当前面板(包括子页面
// 清空当前面板子页面
if (this.currentActivePanelType) {
logger.log(
`[NavigationManager] 切换主面板,清空当前面板的子页面栈: ${this.currentActivePanelType}`
);
this.clearSubPanelStack(this.currentActivePanelType, true);
}
// 隐藏当前面板
if (this.currentActivePanel && this.currentActivePanel.isValid) {
this.hidePanelWithAnimation(this.currentActivePanel, hideDirection);
}
// 加载并显示目标面板
this.loadOrGetPanel(panelType, (panel: Node) => {
// 清理当前面板的subPanel(在hidePanelWithAnimation中已经清理,这里不需要重复)
this.currentActivePanelType = panelType;
// 更新NavigationPanel按钮状态
@@ -192,8 +198,11 @@ export class NavigationManager {
});
}
private subPanelDic: Map<Node, Node[]> = new Map();
// 每个主面板的子页面栈(按打开顺序,最后一个元素是栈顶)
private subPanelStacks: Map<PanelType, Node[]> = new Map();
// 子面板到主面板类型的映射
private subPanelMapping: Map<Node, PanelType> = new Map();
// 子面板的动画配置
private subPanelAnimationConfigs: Map<Node, SubPanelAnimationConfig> =
new Map();
@@ -206,114 +215,6 @@ export class NavigationManager {
// 动画锁,防止动画中重复操作
private isAnimating: boolean = false;
/**
* 带动画的子面板清理方法
* @param basePanel 主面板节点
* @param callback 所有动画完成后的回调
*/
private clearSubPanelsWithAnimation(
basePanel: Node,
callback?: Function
): void {
if (!basePanel || !basePanel.isValid) {
callback && callback();
return;
}
const subPanels = this.subPanelDic.get(basePanel);
if (!subPanels || subPanels.length === 0) {
callback && callback();
return;
}
let completedCount = 0;
const totalCount = subPanels.length;
// 完成动画的回调
const onAnimationComplete = () => {
completedCount++;
if (completedCount >= totalCount) {
// 清理subPanelDic
this.subPanelDic.delete(basePanel);
callback && callback();
}
};
// 同时播放所有子面板的关闭动画
for (let i = subPanels.length - 1; i >= 0; i--) {
const subPanel = subPanels[i];
if (subPanel && subPanel.isValid) {
// 获取动画配置
let config = this.subPanelAnimationConfigs.get(subPanel);
if (!config) {
config = {
openAnimation: PageTransitionType.SCALE,
closeAnimation: PageTransitionType.SCALE,
duration: 0.2,
};
}
// 播放关闭动画
this.playSubPanelCloseAnimation(subPanel, config, () => {
// 清理映射
this.subPanelMapping.delete(subPanel);
this.subPanelAnimationConfigs.delete(subPanel);
// 销毁节点
const baseView = subPanel.getComponent(li_BaseView);
if (baseView) {
baseView.close();
} else {
subPanel.destroy();
}
onAnimationComplete();
});
} else {
onAnimationComplete();
}
}
}
/**
* 统一的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);
// 清理动画配置
this.subPanelAnimationConfigs.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,
@@ -330,6 +231,15 @@ export class NavigationManager {
return;
}
// 确定主面板类型
const basePanelType = this.getPanelType(basePanel);
if (!basePanelType) {
logger.error(
`[NavigationManager] 无法确定basePanel类型: ${basePanel.name}`
);
return;
}
// 使用默认动画配置
const defaultConfig: SubPanelAnimationConfig = {
openAnimation: PageTransitionType.SCALE,
@@ -339,6 +249,17 @@ export class NavigationManager {
};
const config = animationConfig || defaultConfig;
// 获取当前栈顶的子面板
const currentTopSubPanel = this.getTopSubPanel(basePanelType);
// 如果当前有栈顶子面板,先隐藏它
if (currentTopSubPanel && currentTopSubPanel.isValid) {
logger.log(
`[NavigationManager] 隐藏当前栈顶子面板: ${currentTopSubPanel.name}`
);
this.hideSubPanel(currentTopSubPanel);
}
// 如果需要隐藏basePanel,在打开动画前隐藏
if (config.hideBasePanel && basePanel.active) {
logger.log(`[NavigationManager] 隐藏basePanel: ${basePanel.name}`);
@@ -353,21 +274,18 @@ export class NavigationManager {
return;
}
if (!this.subPanelDic.has(basePanel)) {
this.subPanelDic.set(basePanel, []);
// 初始化栈(如果不存在)
if (!this.subPanelStacks.has(basePanelType)) {
this.subPanelStacks.set(basePanelType, []);
}
const subPanels = this.subPanelDic.get(basePanel);
subPanels.push(n);
// 将新子面板推入栈顶
const stack = this.subPanelStacks.get(basePanelType);
stack.push(n);
// 记录子面板到主面板的映射
this.subPanelMapping.set(n, basePanelType);
const basePanelType = this.getPanelType(basePanel);
if (basePanelType) {
this.subPanelMapping.set(n, basePanelType);
} else {
logger.warn(
`[NavigationManager] 无法确定basePanel类型: ${basePanel.name}`
);
}
// 存储动画配置
this.subPanelAnimationConfigs.set(n, config);
@@ -379,6 +297,10 @@ export class NavigationManager {
);
}
logger.log(
`[NavigationManager] 子面板已推入栈顶: ${n.name}, 当前栈深度: ${stack.length}`
);
// 执行打开动画
this.playSubPanelOpenAnimation(n, config);
};
@@ -579,6 +501,148 @@ export class NavigationManager {
// 确保清空集合
this.popupPanels.clear();
}
/**
* 获取指定主面板栈顶的子面板
* @param panelType 主面板类型
* @returns 栈顶子面板,如果栈为空则返回null
*/
private getTopSubPanel(panelType: PanelType): Node | null {
const stack = this.subPanelStacks.get(panelType);
if (!stack || stack.length === 0) {
return null;
}
return stack[stack.length - 1];
}
/**
* 清空指定主面板的子页面栈
* @param panelType 主面板类型
* @param withAnimation 是否播放动画
* @param callback 清空完成后的回调
*/
private clearSubPanelStack(
panelType: PanelType,
withAnimation: boolean = true,
callback?: Function
): void {
const stack = this.subPanelStacks.get(panelType);
if (!stack || stack.length === 0) {
callback && callback();
return;
}
if (!withAnimation) {
// 不播放动画,直接销毁所有子面板
for (let i = stack.length - 1; i >= 0; i--) {
const subPanel = stack[i];
if (subPanel && subPanel.isValid) {
// 清理映射
this.subPanelMapping.delete(subPanel);
this.subPanelAnimationConfigs.delete(subPanel);
this.hiddenBasePanels.delete(subPanel);
// 销毁节点
const baseView = subPanel.getComponent(li_BaseView);
if (baseView) {
baseView.close();
} else {
subPanel.destroy();
}
}
}
this.subPanelStacks.delete(panelType);
callback && callback();
return;
}
// 播放动画
let completedCount = 0;
const totalCount = stack.length;
const onAnimationComplete = () => {
completedCount++;
if (completedCount >= totalCount) {
this.subPanelStacks.delete(panelType);
callback && callback();
}
};
// 同时播放所有子面板的关闭动画
for (let i = stack.length - 1; i >= 0; i--) {
const subPanel = stack[i];
if (subPanel && subPanel.isValid) {
// 获取动画配置
let config = this.subPanelAnimationConfigs.get(subPanel);
if (!config) {
config = {
openAnimation: PageTransitionType.SCALE,
closeAnimation: PageTransitionType.SCALE,
duration: 0.2,
};
}
// 播放关闭动画
this.playSubPanelCloseAnimation(subPanel, config, () => {
// 清理映射
this.subPanelMapping.delete(subPanel);
this.subPanelAnimationConfigs.delete(subPanel);
this.hiddenBasePanels.delete(subPanel);
// 销毁节点
const baseView = subPanel.getComponent(li_BaseView);
if (baseView) {
baseView.close();
} else {
subPanel.destroy();
}
onAnimationComplete();
});
} else {
onAnimationComplete();
}
}
}
/**
* 显示子面板
* @param panel 子面板节点
* @param config 动画配置(可选)
* @param withAnimation 是否播放打开动画,默认为 true
*/
private showSubPanel(
panel: Node,
config?: SubPanelAnimationConfig,
withAnimation: boolean = true
): void {
if (!panel || !panel.isValid) {
return;
}
panel.active = true;
if (config && withAnimation) {
this.playSubPanelOpenAnimation(panel, config);
}
}
/**
* 隐藏子面板(不销毁)
* @param panel 子面板节点
* @param callback 隐藏完成后的回调
*/
private hideSubPanel(panel: Node, callback?: Function): void {
if (!panel || !panel.isValid) {
callback && callback();
return;
}
// 直接隐藏,不播放动画(因为会被新面板覆盖)
panel.active = false;
callback && callback();
}
public closeSubPanel(
panel: Node | li_BaseView,
animationConfig?: SubPanelAnimationConfig
@@ -602,6 +666,39 @@ export class NavigationManager {
return;
}
// 确定子面板所属的主面板类型
const basePanelType = this.subPanelMapping.get(panelNode);
if (!basePanelType) {
logger.warn(
`[NavigationManager] closeSubPanel: 无法确定子面板所属的主面板类型: ${panelNode.name}`
);
return;
}
// 获取栈
const stack = this.subPanelStacks.get(basePanelType);
if (!stack || stack.length === 0) {
logger.warn(
`[NavigationManager] closeSubPanel: 栈为空或不存在,无法关闭子面板: ${panelNode.name}`
);
return;
}
// 查找子面板在栈中的索引
const panelIndex = stack.indexOf(panelNode);
if (panelIndex === -1) {
logger.warn(
`[NavigationManager] closeSubPanel: 子面板不在栈中: ${panelNode.name}`
);
return;
}
// 从栈中移除
stack.splice(panelIndex, 1);
logger.log(
`[NavigationManager] 从栈中移除子面板: ${panelNode.name}, 剩余栈深度: ${stack.length}`
);
// 获取动画配置(优先使用传入的配置,然后使用存储的配置,最后使用默认配置)
let config = animationConfig;
if (!config && this.subPanelAnimationConfigs.has(panelNode)) {
@@ -616,23 +713,25 @@ export class NavigationManager {
};
}
// 检查是否需要恢复显示basePanel或显示下一层子面板
const shouldRestoreBasePanel =
config.hideBasePanel && this.hiddenBasePanels.has(panelNode);
const basePanel = shouldRestoreBasePanel
? this.hiddenBasePanels.get(panelNode)
: null;
// 获取新的栈顶子面板(如果有)
const newTopSubPanel = this.getTopSubPanel(basePanelType);
// 执行关闭动画
this.playSubPanelCloseAnimation(panelNode, config, () => {
// 如果隐藏了basePanel,需要恢复显示
// 清理映射
this.subPanelMapping.delete(panelNode);
this.subPanelAnimationConfigs.delete(panelNode);
if (this.hiddenBasePanels.has(panelNode)) {
const basePanel = this.hiddenBasePanels.get(panelNode);
if (basePanel && basePanel.isValid) {
logger.log(
`[NavigationManager] 恢复显示basePanel: ${basePanel.name}`
);
basePanel.active = true;
}
this.hiddenBasePanels.delete(panelNode);
}
// 从管理映射中移除
this.removeSubPanelFromMappings(panelNode);
// 销毁或关闭panel
try {
if (panel instanceof Node) {
@@ -643,44 +742,42 @@ export class NavigationManager {
} catch (error) {
logger.error("[NavigationManager] closeSubPanel error:", error);
}
});
}
/**
* 从管理映射中移除子面板
*/
private removeSubPanelFromMappings(panelNode: Node): void {
// 从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 {
logger.warn(`[NavigationManager] ${panelNode.name} 不在子页面列表中`);
// 关闭动画完成后,决定显示什么
if (newTopSubPanel && newTopSubPanel.isValid) {
// 栈中还有子面板,显示新的栈顶(不播放动画,直接显示)
logger.log(
`[NavigationManager] 显示新的栈顶子面板(无动画): ${newTopSubPanel.name}`
);
const newTopConfig = this.subPanelAnimationConfigs.get(newTopSubPanel);
this.showSubPanel(newTopSubPanel, newTopConfig, false); // 传入 false,不播放动画
} else if (shouldRestoreBasePanel && basePanel && basePanel.isValid) {
// 栈已空,且之前隐藏了basePanel,恢复显示basePanel
logger.log(`[NavigationManager] 恢复显示basePanel: ${basePanel.name}`);
basePanel.active = true;
} else {
// 栈已空,且没有隐藏basePanel,确保basePanel可见
const cachedBasePanel = this.panelCache.get(basePanelType);
if (
cachedBasePanel &&
cachedBasePanel.isValid &&
!cachedBasePanel.active
) {
logger.log(
`[NavigationManager] 确保basePanel可见: ${cachedBasePanel.name}`
);
cachedBasePanel.active = true;
}
}
this.subPanelMapping.delete(panelNode);
}
// 移除动画配置
if (this.subPanelAnimationConfigs.has(panelNode)) {
this.subPanelAnimationConfigs.delete(panelNode);
}
// 移除隐藏映射
if (this.hiddenBasePanels.has(panelNode)) {
this.hiddenBasePanels.delete(panelNode);
}
// 如果栈完全清空,删除映射
if (stack.length === 0) {
this.subPanelStacks.delete(basePanelType);
logger.log(
`[NavigationManager] 子页面栈已清空,删除映射: ${basePanelType}`
);
}
});
}
/**
@@ -749,8 +846,8 @@ 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,只清理引用
// 注意:子面板的清理已经在 switchToPanel 中通过 clearSubPanelStack 完成了
// 这里不需要再清理
// 特殊处理:主题面板刷新(避免重复调用Show)
if (panelType === PanelType.THEME) {
@@ -796,8 +893,8 @@ export class NavigationManager {
return;
}
// 同时开始子面板的关闭动画
this.clearSubPanelsWithAnimation(panel);
// 注意:子面板的清理已经在 switchToPanel 中通过 clearSubPanelStack 完成了
// 这里只需要播放主面板的隐藏动画
if (!panel.active) panel.active = true;
@@ -20,15 +20,7 @@ export class ChargePopPanel extends li_BaseView {
}
gotoCharge() {
NavigationManager.Instance.openSubPanel(
"PurchasePanel",
NavigationManager.Instance.getCurrentActivePanelNode(),
{ base: NavigationManager.Instance.getCurrentActivePanelNode() },
{
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
}
);
NavigationManager.Instance.openPopupPanel("PurchasePanel");
this.close();
}
@@ -14,6 +14,7 @@ import {
import "../../utils/polyfills";
import { DialogManager } from "../../manager/DialogManager";
import { ChatController, IChatPanelCallback } from "../../core/ChatController";
import { ChatAIService } from "../../core/ChatAIService";
import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView";
import Utils from "db://assets/Scripts/Main/Common/Utils";
import { InnerMsgCode } from "db://assets/Scripts/Main/Config/InnerMsgCode";
@@ -73,6 +74,7 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
private waitingAI: Node;
nameKey: string;
private currentEmotion: VideoEmotion | null = null;
private isActive: boolean = false; // 标记Panel是否处于活跃状态
private onLanguageChangeCallback = () => {
if (!this.girlName) return;
@@ -388,10 +390,14 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
protected onEnable(): void {
if (!this.manager) this.manager = DialogManager.getInstance();
this.isActive = true; // 设置为活跃状态
ChatAIService.Instance.setShouldShowErrorTips(true); // 启用错误提示
this.base.active = false;
this.refresh();
}
protected onDisable(): void {
this.isActive = false; // 设置为非活跃状态,停止响应异步操作
ChatAIService.Instance.setShouldShowErrorTips(false); // 禁用错误提示,避免在其他页面显示
this.base.active = true;
}
@@ -404,12 +410,20 @@ export class ChatPanel extends li_BaseView implements IChatPanelCallback {
}
if (this.isWaiting) {
TipsPanel.show(LanguageUtils.getText("chat_error_code_1003"));
return; // 修复:添加return,避免重复发送
}
// 通过ChatController发送消息
this.isWaiting = true;
this.waitingAI.active = true;
const succeed = await this.chatController.sendMessage(str);
// 检查Panel是否仍然活跃,如果已经关闭则不处理结果
if (!this.isActive) {
logger.log("ChatPanel已关闭,忽略AI响应结果");
return;
}
if (succeed) {
// 清空输入框
this.editBox.string = "";
@@ -329,18 +329,18 @@ export class GirlDetailPanel extends li_BaseView {
const isRelease = girlData.getIsRelease(this.category.toString(), this.id);
const isFree = girlData.isGirlFreeType(this.category.toString(), this.id);
//if (isRelease || isFree) {
// 使用带过渡动画的导航方法
NavigationManager.Instance.switchToPanel(
PanelType.PAST_GIRL_LIST,
false,
(base) => {
const chatData = { girlId: this.id, base: base };
NavigationManager.Instance.openSubPanel("ChatPanel", base, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
});
}
);
// 直接在当前页面打开ChatPanel作为子页面
const currentPanel = NavigationManager.Instance.getCurrentActivePanelNode();
if (currentPanel) {
const chatData = { girlId: this.id, base: currentPanel };
NavigationManager.Instance.openSubPanel("ChatPanel", currentPanel, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
hideBasePanel: true,
});
} else {
logger.warn("[GirlDetailPanel] 无法获取当前激活的主页面");
}
// } else {
// //未解锁
// NavigationManager.Instance.openPopupPanel("GirlListPopupPanel", {
@@ -155,18 +155,10 @@ export class PersonalPanel extends li_BaseView {
private openSettings(): void {
// TODO: 打开设置面板
NavigationManager.Instance.openSubPanel("SettingPanel", this.node);
NavigationManager.Instance.openPopupPanel("SettingPanel", this.node);
}
private openPurchase() {
NavigationManager.Instance.openSubPanel(
"PurchasePanel",
this.node,
{ base: this.node },
{
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
}
);
NavigationManager.Instance.openPopupPanel("PurchasePanel");
}
private openFavorites() {
@@ -44,10 +44,7 @@ export class PurchasePanel extends li_BaseView {
cashBtnSelecting;
web3BtnSelecting;
base: Node;
openUIDataCT(data: any): void {
this.base = data.base;
}
openUIDataCT(data: any): void {}
onLoadCT(): void {
this.node.active = false;
this.scheduleOnce(() => {
@@ -208,12 +205,11 @@ export class PurchasePanel extends li_BaseView {
payType: param.payType,
goodId: param.goodId,
networkType: this.getDefaultNetworkType(),
basePanel: this.base,
payPanel: this,
};
if (this.web3PopPanel == null)
NavigationManager.Instance.openSubPanel("Web3PopPanel", this.base, data);
NavigationManager.Instance.openPopupPanel("Web3PopPanel", data);
else {
data.networkType = undefined;
this.web3PopPanel.refreshData(data);
@@ -76,7 +76,14 @@ export class ShowPanel extends li_BaseView {
// 加载远程资源
let newPath = envData.cdn + "/" + "Girls/" + path + ".png";
ResManager.I.changeRemoteSpriteFrame(this.image, newPath, () => {
Utils.adjustBgPixelRatio(this.image.node, 3);
// 固定高度为 1334,等比缩放宽度
const targetHeight = 1334;
const uiTransform = this.image.node.getComponent(UITransform);
if (uiTransform && uiTransform.height > 0) {
const scale = targetHeight / uiTransform.height;
uiTransform.height = targetHeight;
uiTransform.width = uiTransform.width * scale;
}
});
} else {
// 使用自己的 videoPlayer 进行置顶显示
@@ -470,15 +470,7 @@ export class ThemePanel extends li_BaseView {
}
enterShop() {
NavigationManager.Instance.openSubPanel(
"PurchasePanel",
this.node,
{ base: this.node },
{
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
}
);
NavigationManager.Instance.openPopupPanel("PurchasePanel");
}
openRecomandList() {
@@ -36,7 +36,6 @@ export class Web3PopPanel extends li_BaseView {
private networkType: proto.cs.EnmNetworkType;
private goodId: number;
private basePanel: PersonalPanel;
private payPanel: PurchasePanel;
private countdownTimer: any;
@@ -112,7 +111,6 @@ export class Web3PopPanel extends li_BaseView {
this.goodId = data.goodId;
this.curType =
data.networkType != undefined ? data.networkType : this.curType;
this.basePanel = data.basePanel;
this.payPanel = data.payPanel;
}
refreshView() {
+14 -14
View File
@@ -186,15 +186,14 @@ export class GirlListItem extends Component {
currentPanel,
this.id,
{
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
openAnimation: PageTransitionType.NONE,
closeAnimation: PageTransitionType.NONE,
hideBasePanel: true, // 隐藏底层panel,实现全屏显示
}
);
} else {
logger.warn("[GirlListItem] 无法获取当前激活的主页面");
}
this.baseNode.close();
}
onClickChat() {
@@ -205,16 +204,17 @@ export class GirlListItem extends Component {
girlData.getGrilCategoryById(this.id)
);
NavigationManager.Instance.switchToPanel(
PanelType.PAST_GIRL_LIST,
false,
(base) => {
const chatData = { girlId: this.id, base: base };
NavigationManager.Instance.openSubPanel("ChatPanel", base, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
});
}
);
// 直接在当前页面打开ChatPanel作为子页面
const currentPanel = NavigationManager.Instance.getCurrentActivePanelNode();
if (currentPanel) {
const chatData = { girlId: this.id, base: currentPanel };
NavigationManager.Instance.openSubPanel("ChatPanel", currentPanel, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
hideBasePanel: true,
});
} else {
logger.warn("[GirlListItem] 无法获取当前激活的主页面");
}
}
}
@@ -220,8 +220,8 @@ export class PastGirlListItem extends Component {
currentPanel,
this.id,
{
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
openAnimation: PageTransitionType.NONE,
closeAnimation: PageTransitionType.NONE,
hideBasePanel: true, // 隐藏底层panel,实现全屏显示
}
);
@@ -238,16 +238,17 @@ export class PastGirlListItem extends Component {
girlData.getGrilCategoryById(this.id)
);
NavigationManager.Instance.switchToPanel(
PanelType.PAST_GIRL_LIST,
false,
(base) => {
const chatData = { girlId: this.id, base: base };
NavigationManager.Instance.openSubPanel("ChatPanel", base, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
});
}
);
// 直接在当前页面打开ChatPanel作为子页面
const currentPanel = NavigationManager.Instance.getCurrentActivePanelNode();
if (currentPanel) {
const chatData = { girlId: this.id, base: currentPanel };
NavigationManager.Instance.openSubPanel("ChatPanel", currentPanel, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
hideBasePanel: true,
});
} else {
logger.warn("[PastGirlListItem] 无法获取当前激活的主页面");
}
}
}
+14 -13
View File
@@ -96,17 +96,18 @@ export class RecomandItem extends Component {
girlData.getGrilCategoryById(this.id)
);
NavigationManager.Instance.switchToPanel(
PanelType.PAST_GIRL_LIST,
false,
(base) => {
const chatData = { girlId: this.id, base: base };
NavigationManager.Instance.openSubPanel("ChatPanel", base, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
});
}
);
// 直接在当前页面打开ChatPanel作为子页面
const currentPanel = NavigationManager.Instance.getCurrentActivePanelNode();
if (currentPanel) {
const chatData = { girlId: this.id, base: currentPanel };
NavigationManager.Instance.openSubPanel("ChatPanel", currentPanel, chatData, {
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
hideBasePanel: true,
});
} else {
logger.warn("[RecomandItem] 无法获取当前激活的主页面");
}
}
gotoDetail() {
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
@@ -124,8 +125,8 @@ export class RecomandItem extends Component {
currentPanel,
this.id,
{
openAnimation: PageTransitionType.SLIDE_LEFT,
closeAnimation: PageTransitionType.SLIDE_RIGHT,
openAnimation: PageTransitionType.NONE,
closeAnimation: PageTransitionType.NONE,
hideBasePanel: true, // 隐藏底层panel,实现全屏显示
}
);
+5 -3
View File
@@ -612,6 +612,8 @@
"__id__": 0
},
"fileId": "eaz1XV32NMAYZ1f8eNu4bc",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
@@ -717,13 +719,13 @@
"b": 108,
"a": 255
},
"_string": "已过期",
"_string": "Expired",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 20,
"_actualFontSize": 17,
"_fontSize": 25.6,
"_fontFamily": "Arial",
"_lineHeight": 32.4,
"_lineHeight": 48.6,
"_overflow": 2,
"_enableWrapText": true,
"_font": {