feat: 接入我参与的挑战接口以及UI
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { _decorator, Node, Button, instantiate, Label, ScrollView, UITransform, Sprite, SpriteFrame, Texture2D, ImageAsset, assetManager } from 'cc';
|
||||
import { BaseView } from 'db://assets/scripts/core/BaseView';
|
||||
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
|
||||
import { CreatedShareItem, ShareParticipantRankSummary } from 'db://assets/scripts/types/ApiTypes';
|
||||
import { CreatedShareItem, ParticipatedShareItem, ShareParticipantRankSummary } from 'db://assets/scripts/types/ApiTypes';
|
||||
import { ShareManager } from 'db://assets/scripts/utils/ShareManager';
|
||||
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
|
||||
const { ccclass, property } = _decorator;
|
||||
@@ -11,6 +11,9 @@ export class PagePKData extends BaseView {
|
||||
private static readonly CREATED_ITEM_TOP_PADDING = 20;
|
||||
private static readonly CREATED_ITEM_BOTTOM_PADDING = 20;
|
||||
private static readonly CREATED_ITEM_SPACING = 20;
|
||||
private static readonly PARTICIPATED_ITEM_TOP_PADDING = 20;
|
||||
private static readonly PARTICIPATED_ITEM_BOTTOM_PADDING = 20;
|
||||
private static readonly PARTICIPATED_ITEM_SPACING = 20;
|
||||
|
||||
@property({ type: Node, tooltip: '返回按钮' })
|
||||
backBtn: Node | null = null;
|
||||
@@ -21,8 +24,16 @@ export class PagePKData extends BaseView {
|
||||
@property({ type: Node, tooltip: '我创建的挑战列表条目模板 FriendsPKRankListItem' })
|
||||
createdListItemTemplate: Node | null = null;
|
||||
|
||||
@property({ type: Node, tooltip: '我参与的挑战列表 content 节点' })
|
||||
participatedListContent: Node | null = null;
|
||||
|
||||
@property({ type: Node, tooltip: '我参与的挑战列表条目模板 MyPKListItem' })
|
||||
participatedListItemTemplate: Node | null = null;
|
||||
|
||||
private _createdShares: CreatedShareItem[] = [];
|
||||
private _participatedShares: ParticipatedShareItem[] = [];
|
||||
private _createdItemNodes: Node[] = [];
|
||||
private _participatedItemNodes: Node[] = [];
|
||||
private _createdButtonBindings: Array<{ node: Node; handler: () => void }> = [];
|
||||
private _isLoading: boolean = false;
|
||||
private _renderVersion: number = 0;
|
||||
@@ -33,36 +44,44 @@ export class PagePKData extends BaseView {
|
||||
this.backBtn.on(Button.EventType.CLICK, this._onBackClick, this);
|
||||
}
|
||||
this._hideCreatedItemTemplate();
|
||||
this._hideParticipatedItemTemplate();
|
||||
}
|
||||
|
||||
onViewShow(): void {
|
||||
this._resolveNodes();
|
||||
void this._loadCreatedShares();
|
||||
void this._loadShareLists();
|
||||
}
|
||||
|
||||
onViewHide(): void {
|
||||
this._renderVersion++;
|
||||
}
|
||||
|
||||
private _onBackClick(): void {
|
||||
ViewManager.instance.back();
|
||||
}
|
||||
|
||||
private async _loadCreatedShares(): Promise<void> {
|
||||
private async _loadShareLists(): Promise<void> {
|
||||
if (this._isLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isLoading = true;
|
||||
try {
|
||||
const items = await ShareManager.instance.fetchCreatedShares();
|
||||
if (!items) {
|
||||
const [createdItems, participatedItems] = await Promise.all([
|
||||
ShareManager.instance.fetchCreatedShares(),
|
||||
ShareManager.instance.fetchParticipatedShares(),
|
||||
]);
|
||||
|
||||
if (!createdItems || !participatedItems) {
|
||||
ToastManager.instance.show('获取挑战列表失败,请稍后重试');
|
||||
return;
|
||||
}
|
||||
|
||||
this._createdShares = items;
|
||||
this._createdShares = createdItems ?? [];
|
||||
this._participatedShares = participatedItems ?? [];
|
||||
console.log('[PagePKData] 我创建的挑战列表:', this._createdShares);
|
||||
console.log('[PagePKData] 我参与的挑战列表:', this._participatedShares);
|
||||
this._renderCreatedShares();
|
||||
this._renderParticipatedShares();
|
||||
} finally {
|
||||
this._isLoading = false;
|
||||
}
|
||||
@@ -73,6 +92,7 @@ export class PagePKData extends BaseView {
|
||||
this.backBtn.off(Button.EventType.CLICK, this._onBackClick, this);
|
||||
}
|
||||
this._clearCreatedItems();
|
||||
this._clearParticipatedItems();
|
||||
}
|
||||
|
||||
private _resolveNodes(): void {
|
||||
@@ -87,12 +107,25 @@ export class PagePKData extends BaseView {
|
||||
?? this.createdListContent?.getChildByName('FriendsPKRankListItem')
|
||||
?? null;
|
||||
|
||||
const participatedList = this.node.getChildByName('MyPKList');
|
||||
const participatedView = participatedList?.getChildByName('view');
|
||||
this.participatedListContent = this.participatedListContent ?? participatedView?.getChildByName('content') ?? null;
|
||||
this.participatedListItemTemplate = this.participatedListItemTemplate
|
||||
?? this.participatedListContent?.getChildByName('MyPKListItem')
|
||||
?? null;
|
||||
|
||||
if (!this.createdListContent) {
|
||||
console.warn('[PagePKData] 未找到 FriendsPKRankList/content 节点');
|
||||
}
|
||||
if (!this.createdListItemTemplate) {
|
||||
console.warn('[PagePKData] 未找到 FriendsPKRankListItem 模板节点');
|
||||
}
|
||||
if (!this.participatedListContent) {
|
||||
console.warn('[PagePKData] 未找到 MyPKList/content 节点');
|
||||
}
|
||||
if (!this.participatedListItemTemplate) {
|
||||
console.warn('[PagePKData] 未找到 MyPKListItem 模板节点');
|
||||
}
|
||||
}
|
||||
|
||||
private _renderCreatedShares(): void {
|
||||
@@ -119,6 +152,29 @@ export class PagePKData extends BaseView {
|
||||
this._scrollCreatedListToTop();
|
||||
}
|
||||
|
||||
private _renderParticipatedShares(): void {
|
||||
this._clearParticipatedItems();
|
||||
|
||||
if (!this.participatedListContent || !this.participatedListItemTemplate) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._layoutParticipatedList(this._participatedShares.length);
|
||||
this._hideParticipatedItemTemplate();
|
||||
|
||||
this._participatedShares.forEach((share, index) => {
|
||||
const item = instantiate(this.participatedListItemTemplate!);
|
||||
item.name = `MyPKListItem_${index + 1}`;
|
||||
item.active = true;
|
||||
this.participatedListContent!.addChild(item);
|
||||
this._participatedItemNodes.push(item);
|
||||
this._positionParticipatedItem(item, index);
|
||||
this._applyParticipatedShare(item, share);
|
||||
});
|
||||
|
||||
this._scrollParticipatedListToTop();
|
||||
}
|
||||
|
||||
private _applyCreatedShare(item: Node, share: CreatedShareItem, version: number): void {
|
||||
this._setLabel(this._findLabelIn(item, 'Name'), share.title || '未命名挑战');
|
||||
this._setLabel(this._findLabelIn(item, 'ParticipateLabel'), `共${share.participantCount ?? 0}人参与`);
|
||||
@@ -146,6 +202,12 @@ export class PagePKData extends BaseView {
|
||||
}
|
||||
}
|
||||
|
||||
private _applyParticipatedShare(item: Node, share: ParticipatedShareItem): void {
|
||||
this._setLabel(this._findLabelIn(item, 'ChallangeName'), share.title || '未命名挑战');
|
||||
this._setLabel(this._findLabelIn(item, 'ParticipateLabel'), `共${share.participantCount ?? 0}人参与`);
|
||||
this._applyParticipatedRank(item, share.userRank);
|
||||
}
|
||||
|
||||
private _openShareDetail(share: CreatedShareItem): void {
|
||||
if (!share.shareCode) {
|
||||
ToastManager.instance.show('挑战数据异常,请稍后重试');
|
||||
@@ -200,6 +262,34 @@ export class PagePKData extends BaseView {
|
||||
);
|
||||
}
|
||||
|
||||
private _layoutParticipatedList(itemCount: number): void {
|
||||
if (!this.participatedListContent || !this.participatedListItemTemplate) {
|
||||
return;
|
||||
}
|
||||
|
||||
const contentTransform = this.participatedListContent.getComponent(UITransform);
|
||||
const viewTransform = this.participatedListContent.parent?.getComponent(UITransform) ?? null;
|
||||
const itemTransform = this.participatedListItemTemplate.getComponent(UITransform);
|
||||
if (!contentTransform || !viewTransform || !itemTransform) {
|
||||
return;
|
||||
}
|
||||
|
||||
const contentHeight = Math.max(
|
||||
viewTransform.height,
|
||||
PagePKData.PARTICIPATED_ITEM_TOP_PADDING
|
||||
+ PagePKData.PARTICIPATED_ITEM_BOTTOM_PADDING
|
||||
+ itemCount * itemTransform.height
|
||||
+ Math.max(0, itemCount - 1) * PagePKData.PARTICIPATED_ITEM_SPACING,
|
||||
);
|
||||
|
||||
contentTransform.setContentSize(contentTransform.width, contentHeight);
|
||||
this.participatedListContent.setPosition(
|
||||
this.participatedListContent.position.x,
|
||||
viewTransform.height / 2,
|
||||
this.participatedListContent.position.z,
|
||||
);
|
||||
}
|
||||
|
||||
private _positionCreatedItem(item: Node, index: number): void {
|
||||
const itemTransform = item.getComponent(UITransform);
|
||||
if (!itemTransform) {
|
||||
@@ -212,11 +302,55 @@ export class PagePKData extends BaseView {
|
||||
item.setPosition(0, y, item.position.z);
|
||||
}
|
||||
|
||||
private _positionParticipatedItem(item: Node, index: number): void {
|
||||
const itemTransform = item.getComponent(UITransform);
|
||||
if (!itemTransform) {
|
||||
return;
|
||||
}
|
||||
|
||||
const y = -PagePKData.PARTICIPATED_ITEM_TOP_PADDING
|
||||
- itemTransform.height / 2
|
||||
- index * (itemTransform.height + PagePKData.PARTICIPATED_ITEM_SPACING);
|
||||
item.setPosition(0, y, item.position.z);
|
||||
}
|
||||
|
||||
private _scrollCreatedListToTop(): void {
|
||||
const scrollView = this.node.getChildByName('FriendsPKRankList')?.getComponent(ScrollView);
|
||||
scrollView?.scrollToTop(0);
|
||||
}
|
||||
|
||||
private _scrollParticipatedListToTop(): void {
|
||||
const scrollView = this.node.getChildByName('MyPKList')?.getComponent(ScrollView);
|
||||
scrollView?.scrollToTop(0);
|
||||
}
|
||||
|
||||
private _applyParticipatedRank(item: Node, rank: number | null): void {
|
||||
const rankRoot = this._findChild(item, 'Rank');
|
||||
if (!rankRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rank1Badge = this._findChild(rankRoot, 'rank1badge');
|
||||
const rank2Badge = this._findChild(rankRoot, 'rank2badge');
|
||||
const rank3Badge = this._findChild(rankRoot, 'rank3badge');
|
||||
const rankNumberNode = this._findChild(rankRoot, 'RankNumber');
|
||||
const normalizedRank = rank && rank > 0 ? rank : null;
|
||||
|
||||
if (rank1Badge) {
|
||||
rank1Badge.active = normalizedRank === 1;
|
||||
}
|
||||
if (rank2Badge) {
|
||||
rank2Badge.active = normalizedRank === 2;
|
||||
}
|
||||
if (rank3Badge) {
|
||||
rank3Badge.active = normalizedRank === 3;
|
||||
}
|
||||
if (rankNumberNode) {
|
||||
rankNumberNode.active = normalizedRank !== 1 && normalizedRank !== 2 && normalizedRank !== 3;
|
||||
this._setLabel(rankNumberNode.getComponent(Label), normalizedRank ? `${normalizedRank}` : '-');
|
||||
}
|
||||
}
|
||||
|
||||
private _findAvatarSprite(item: Node): Sprite | null {
|
||||
const headNode = this._findChild(item, 'Head');
|
||||
return headNode?.children[0]?.getComponent(Sprite) ?? headNode?.getComponent(Sprite) ?? null;
|
||||
@@ -256,6 +390,18 @@ export class PagePKData extends BaseView {
|
||||
this._hideCreatedItemTemplate();
|
||||
}
|
||||
|
||||
private _clearParticipatedItems(): void {
|
||||
for (const item of this._participatedItemNodes) {
|
||||
if (item.isValid) {
|
||||
item.removeFromParent();
|
||||
item.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
this._participatedItemNodes = [];
|
||||
this._hideParticipatedItemTemplate();
|
||||
}
|
||||
|
||||
private _unbindCreatedButtons(): void {
|
||||
for (const binding of this._createdButtonBindings) {
|
||||
if (binding.node.isValid) {
|
||||
@@ -271,6 +417,12 @@ export class PagePKData extends BaseView {
|
||||
}
|
||||
}
|
||||
|
||||
private _hideParticipatedItemTemplate(): void {
|
||||
if (this.participatedListItemTemplate?.isValid) {
|
||||
this.participatedListItemTemplate.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
private _setLabel(label: Label | null, text: string): void {
|
||||
if (label) {
|
||||
label.string = text;
|
||||
|
||||
Reference in New Issue
Block a user