Files
18xchat/assets/Scripts/chat18x/ui/panels/GirlDetailPanel.ts
T

317 lines
8.8 KiB
TypeScript
Raw Normal View History

2025-08-13 15:37:15 +08:00
import {
_decorator,
Label,
Node,
Sprite,
VideoPlayer,
instantiate,
UITransform,
2025-09-11 00:03:22 +08:00
Size,
2025-08-13 15:37:15 +08:00
} from "cc";
2025-07-25 18:27:30 +08:00
import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView";
2025-08-01 18:28:36 +08:00
import ResManager from "db://assets/Scripts/Main/Manager/ResManager";
import { DetailImageItem } from "../../uiitems/DetailImageItem";
2025-08-11 16:08:59 +08:00
import { NavigationManager } from "../../manager/NavigationManager";
import { ConfigManager } from "../../manager/ConfigManager";
2025-08-12 19:49:50 +08:00
import LanguageUtils from "../../../Main/Common/LanguageUtils";
import Utils from "../../../Main/Common/Utils";
import { InnerMsgCode } from "../../../Main/Config/InnerMsgCode";
2025-08-25 20:15:42 +08:00
import { SimpleToggle } from "../components/SimpleToggle";
2025-09-03 11:09:35 +08:00
import { DataManager, DataId } from "../../data/DataManager";
import { GirlData } from "../../data/GirlData";
import { GirlService } from "db://assets/Scripts/chat18x/network/services/GirlService";
2025-09-10 15:48:27 +08:00
import proto from "db://assets/Scripts/proto/proto.pb.js";
2025-09-11 00:03:22 +08:00
import { SceneBgVideoLayer } from "../../../Sub/UI/SceneBgVideoLayer";
2025-08-01 18:28:36 +08:00
2025-07-22 16:43:10 +08:00
const { ccclass, property } = _decorator;
@ccclass("GirlDetailPanel")
2025-07-25 18:27:30 +08:00
export class GirlDetailPanel extends li_BaseView {
2025-09-11 00:03:22 +08:00
@property(UITransform)
videoArea: UITransform;
// 移除直接的 VideoPlayer 引用,改用 SceneBgVideoLayer 单例
// @property(VideoPlayer)
// avatarVideo: VideoPlayer;
2025-07-22 16:43:10 +08:00
@property(Label)
girlName: Label;
2025-07-30 21:52:26 +08:00
2025-09-11 00:03:22 +08:00
/** 获取 SceneBgVideoLayer 单例实例 */
private get videoLayer(): SceneBgVideoLayer | null {
return SceneBgVideoLayer.handle;
}
2025-08-25 20:15:42 +08:00
@property(SimpleToggle)
imgToggle: SimpleToggle = null;
@property(SimpleToggle)
videoToggle: SimpleToggle = null;
2025-07-30 21:52:26 +08:00
@property(Node)
starParent: Node;
@property(Label)
tags: Label;
@property(Label)
descAge: Label;
2025-07-22 16:43:10 +08:00
@property(Label)
desc: Label;
@property(Node)
chatBtn: Node;
id = 0;
2025-07-25 15:20:02 +08:00
2025-08-01 18:28:36 +08:00
@property(DetailImageItem)
2025-08-12 16:58:02 +08:00
imgItemInst: DetailImageItem;
2025-08-01 18:28:36 +08:00
@property(Node)
2025-08-12 16:58:02 +08:00
imgsLayout: Node;
2025-08-01 18:28:36 +08:00
2025-08-12 16:58:02 +08:00
openUIDataCT(data) {
2025-07-25 18:27:30 +08:00
this.id = data;
2025-07-30 21:52:26 +08:00
}
onLoadCT() {
super.onLoadCT();
2025-08-12 16:58:02 +08:00
this.imgItemInst.node.active = false;
2025-09-11 10:54:06 +08:00
// 检查 SceneBgVideoLayer 是否可用
if (!this.videoLayer) {
console.error("GirlDetailPanel: SceneBgVideoLayer.handle 未初始化");
} else {
console.log("GirlDetailPanel: 成功获取 SceneBgVideoLayer 实例");
// 初始化视频显示位置
this.initVideoPosition();
}
2025-07-25 18:27:30 +08:00
this.refresh(this.id);
2025-08-12 19:49:50 +08:00
Utils.addInnerEL(InnerMsgCode.LanguageChange, this, () => {
2025-08-15 18:17:12 +08:00
this.girlName.string = LanguageUtils.getText(this.nameKey);
2025-08-12 19:49:50 +08:00
let desc = "";
const tags = LanguageUtils.getText(this.tagKey).split("|");
for (let i = 0; i < tags.length; i++) {
if (i != 0) desc += "\n";
desc += tags[i];
}
this.tags.string = desc;
2025-09-10 15:48:27 +08:00
this.desc.string = LanguageUtils.getText(this.descKey);
2025-08-12 19:49:50 +08:00
});
2025-08-25 20:15:42 +08:00
this.imgToggle.callback = this.bindImgToggle.bind(this);
this.videoToggle.callback = this.bindVideoToggle.bind(this);
2025-07-25 18:27:30 +08:00
}
2025-08-12 16:58:02 +08:00
setVideEnable(enable: boolean) {
2025-09-11 00:03:22 +08:00
if (!this.videoLayer) {
console.error("GirlDetailPanel: SceneBgVideoLayer 不可用");
return;
}
2025-08-12 16:58:02 +08:00
if (enable) {
2025-09-11 00:03:22 +08:00
// 恢复播放
this.videoLayer.resume();
console.log("GirlDetailPanel: 开启视频播放");
} else {
// 暂停播放
this.videoLayer.pause();
console.log("GirlDetailPanel: 暂停视频播放");
2025-08-01 18:28:36 +08:00
}
}
2025-08-13 15:37:15 +08:00
2025-09-11 00:03:22 +08:00
/**
* 获取目标视频尺寸
* 从 videoArea 获取实际需要填充的区域尺寸
*/
private getTargetVideoSize(): Size | null {
// 从 videoArea 获取目标尺寸
if (this.videoArea) {
return new Size(this.videoArea.width, this.videoArea.height);
}
// 如果没有 videoArea,使用默认尺寸
console.warn("GirlDetailPanel: videoArea 未设置,使用默认尺寸");
return new Size(600, 800);
}
2025-08-12 19:49:50 +08:00
nameKey: string;
tagKey: string;
2025-09-10 15:48:27 +08:00
descKey: string;
2025-09-03 17:35:27 +08:00
category: number;
2025-09-03 11:09:35 +08:00
async refresh(index: number) {
2025-09-05 09:42:22 +08:00
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
this.category = girlData.getGrilCategoryById(this.id);
2025-09-03 11:09:35 +08:00
// 请求详细数据
const reqData = {
id: this.id,
};
2025-09-03 17:35:27 +08:00
let res = await GirlService.I.reqGetGirlDetail(reqData);
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
// 保存数据
2025-09-08 15:10:51 +08:00
girlData.setGirlDetailData(this.category.toString(), res.data);
2025-09-03 17:35:27 +08:00
// 根据数据,刷新界面
this.nameKey = girlData.getGrilName(this.category.toString(), this.id);
2025-09-10 15:48:27 +08:00
this.girlName.string = LanguageUtils.getText(this.nameKey);
this.descKey = girlData.getGrilDesc(this.category.toString(), this.id);
this.desc.string = LanguageUtils.getText(this.descKey);
2025-09-03 11:09:35 +08:00
2025-09-03 17:35:27 +08:00
let desc = "";
this.tagKey = girlData.getGrilTagKey(this.category.toString(), this.id);
const tags = LanguageUtils.getText(this.tagKey).split("|");
for (let i = 0; i < tags.length; i++) {
2025-09-10 15:48:27 +08:00
if (i != 0) desc += "\n";
2025-09-03 17:35:27 +08:00
desc += tags[i];
}
this.tags.string = desc;
for (let i = 0; i < 5; i++) {
this.starParent.children[i].active = i < 5;
}
let age = girlData.getGrilAge(this.category.toString(), this.id);
this.descAge.string =
LanguageUtils.getText("girldetailpanel.age") + age.toString();
2025-09-03 11:09:35 +08:00
2025-09-10 15:48:27 +08:00
const firstPath = girlData.getFirstGrilVideoPath(
this.category.toString(),
this.id
);
2025-09-11 00:03:22 +08:00
// 使用 SceneBgVideoLayer 加载并播放视频
if (this.videoLayer && firstPath) {
console.log(`GirlDetailPanel: 加载视频 ${firstPath}`);
// 获取 videoArea 的尺寸和位置
const targetSize = this.videoArea
? new Size(this.videoArea.width, this.videoArea.height)
: new Size(600, 800);
2025-09-11 10:54:06 +08:00
// 获取 videoArea 的中心位置作为参考节点(使用世界坐标)
const videoAreaPos = this.videoArea
? this.videoArea.node.getWorldPosition()
: undefined;
2025-09-11 00:03:22 +08:00
2025-09-11 10:54:06 +08:00
// 使用新的统一 playVideo 方法
this.videoLayer.playVideo(firstPath, {
loop: true,
2025-09-11 00:03:22 +08:00
size: targetSize,
2025-09-11 10:54:06 +08:00
position: videoAreaPos
});
2025-09-11 00:03:22 +08:00
}
2025-09-10 15:48:27 +08:00
let resIds = girlData.getAllDisplayGrilPhotoId(
this.category.toString(),
this.id
);
this.refreshImgs(
proto.cs.EnmResType.ERT_Image,
this.category,
this.id,
resIds
);
}
2025-07-22 16:43:10 +08:00
}
2025-08-25 20:15:42 +08:00
bindImgToggle() {
2025-09-03 17:35:27 +08:00
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
2025-09-10 15:48:27 +08:00
let resIds = girlData.getAllDisplayGrilPhotoId(
this.category.toString(),
this.id
);
this.refreshImgs(
proto.cs.EnmResType.ERT_Image,
this.category,
this.id,
resIds
);
2025-08-25 20:15:42 +08:00
}
bindVideoToggle() {
2025-09-03 17:35:27 +08:00
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
2025-09-10 15:48:27 +08:00
let resIds = girlData.getAllDisplayGrilVideoId(
this.category.toString(),
this.id
);
this.refreshImgs(
proto.cs.EnmResType.ERT_Video,
this.category,
this.id,
resIds
);
2025-08-25 20:15:42 +08:00
}
2025-08-29 16:23:59 +08:00
refreshImgs(
2025-09-10 10:18:27 +08:00
type: proto.cs.EnmResType,
2025-09-03 17:35:27 +08:00
category: number,
id: number,
2025-09-10 15:48:27 +08:00
resIds: number[]
2025-08-29 16:23:59 +08:00
) {
2025-08-25 20:15:42 +08:00
for (let i = this.imgsLayout.children.length - 1; i >= 0; i--) {
this.imgsLayout.children[i].destroy();
}
2025-09-10 01:00:27 +08:00
let count = resIds.length;
2025-09-03 17:35:27 +08:00
for (let i = 0; i < count; i++) {
2025-08-25 20:15:42 +08:00
let newNode = instantiate(this.imgItemInst.node);
let item = newNode.getComponent(DetailImageItem);
2025-09-10 01:00:27 +08:00
let resId = resIds[i];
item.refresh(this, type, category, id, resId);
2025-08-25 20:15:42 +08:00
newNode.active = true;
this.imgsLayout.addChild(newNode);
}
}
2025-09-11 00:03:22 +08:00
/**
* 初始化视频位置和属性
*/
private initVideoPosition() {
if (!this.videoLayer || !this.videoArea) return;
// 使用 videoArea 的世界坐标位置
const videoAreaWorldPos = this.videoArea.node.getWorldPosition();
2025-09-11 10:54:06 +08:00
// 视频位置和缩放已在 playVideo 中处理
2025-09-11 00:03:22 +08:00
this.videoLayer.setVideoScale(1);
console.log(
`GirlDetailPanel: 初始化视频世界位置到 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})`
);
}
2025-07-22 16:43:10 +08:00
OnClickChatBtn() {
2025-08-25 20:15:42 +08:00
// 使用带过渡动画的导航方法
2025-09-10 16:43:46 +08:00
NavigationManager.Instance.navigateToChatWithTransition(
this.category.toString(),
this.id,
this
);
2025-08-25 20:15:42 +08:00
// 注意:不在这里直接调用onClose,而是在动画完成后由NavigationManager调用
2025-07-25 18:27:30 +08:00
}
2025-08-12 16:58:02 +08:00
returnBtn() {
2025-07-25 18:27:30 +08:00
this.onClose();
2025-08-12 20:37:46 +08:00
NavigationManager.Instance.navigateToGirlList(this.category);
2025-07-25 18:27:30 +08:00
//ViewManager.I.openBundlesView("GirlListPanel");
2025-07-22 16:43:10 +08:00
}
2025-09-11 00:03:22 +08:00
/**
* 面板关闭时的清理工作
*/
onClose() {
// 停止视频播放,释放资源
if (this.videoLayer) {
//this.videoLayer.stop();
//console.log("GirlDetailPanel: 停止视频播放");
}
super.onClose();
}
/**
* 面板销毁时的清理工作
*/
onDestroy() {
// 确保视频资源被释放
if (this.videoLayer) {
//this.videoLayer.stop();
//console.log("GirlDetailPanel: 销毁时停止视频播放");
}
super.onDestroy();
}
2025-07-22 16:43:10 +08:00
}