PhoneCallViewImpl.ts 7.73 KB
import { CCPureView, CCView } from "../../../../common/classbase/CCViewBase";
import { PhoneCallViewType, PhoneCallViewProps, PhoneCallView, PhoneCallItemProps, PhoneCallListAutoNextPlot } from "../type/PhoneCallView";
import { RegView } from "../../PresenterCCViewFactory";
import { DummyScrollView, DummyLayout, DummyNode, DummyLabel, DummySprite } from "../../../../common/CCDummyObjects";
import { SentenceType, SentenceContent } from "../../../../avg/model/PlotModel";
import { richNodesToCocosString } from "../../../../avg/utils/RichTextUtils";
import { ResUtils } from "../../../../common/utils/ResUtils";
import { AudioManager } from "../../../../common/gameplay/managers/AudioManager";

const { ccclass, property } = cc._decorator;



@ccclass
@RegView(PhoneCallViewType, "prefab/ui/PhoneCallView")
export class PhoneCallViewImpl extends CCPureView<PhoneCallViewProps> implements PhoneCallView {
    //#region editor bindings
    @property(cc.ScrollView)
    private scrollView = DummyScrollView;
    @property(cc.Layout)
    private contentLayout = DummyLayout;
    @property(cc.Node)
    private callingNode = DummyNode;
    @property(cc.Node)
    private messageNode = DummyNode;
    @property(cc.Label)
    private nameLabel1 = DummyLabel;
    @property(cc.Label)
    private nameLabel2 = DummyLabel;
    @property(cc.Sprite)
    private headIcon1 = DummySprite;
    @property(cc.Sprite)
    private headIcon2 = DummySprite;

    @property(cc.Node)
    private rejectTipNode = DummyNode;
    @property(cc.Node)
    private nextPlotNode = DummyNode;

    onRejectCall() {
        this.node.children[1].active = true;
        this.rejectTipNode.runAction(cc.sequence(cc.fadeIn(0.3), cc.delayTime(0.3), cc.callFunc(() => {
            this.rejectTipNode.opacity = 0;
            this.node.children[0].opacity = 0;
            this.stopPhoneMusic();
            this.scheduleOnce(() => {
                this.node.children[0].opacity = 255;
                this.node.children[1].active = false;
                this.playPhoneMusic();
            }, 0.8);
        })));
    }

    playPhoneMusic = () => {
        const PhoneBgmCallSound = "/audio/bgm/iPhoneXSCallSound";
        AudioManager.playMusic(PhoneBgmCallSound)
    }

    stopPhoneMusic = () => {
        AudioManager.stopMusic();
    }

    onAcceptCall() {
        this.callingNode.active = false;
        this.messageNode.active = true;
        this.stopPhoneMusic();
        if (PhoneCallListAutoNextPlot) {
            this.scheduleOnce(() => {
                this._props.onCompletePlot();
            }, 0.6);
        }
    }

    onNextPlotBtnClick() {
        if (!PhoneCallListAutoNextPlot) {
            this._props.onCompletePlot(this._selectIndex);
            this._selectIndex = undefined;
        }
    }
    //#endregion

    private _newCall = true;
    private _selectIndex?: number;

    onLoad() {
        this.bindProp("name", this.nameLabel1, "string");
        this.bindProp("name", this.nameLabel2, "string");
        this.bindProp("icon", async (v) => {
            if (v) {
                let sf = await ResUtils.loadRes(v, cc.SpriteFrame, 2);
                // if (v === this._props.icon) { // 理论上这里没必要
                this.headIcon1.spriteFrame = sf;
                this.headIcon2.spriteFrame = sf;
                // }
            }
        });

        // this.bindProp("select", (value) => {
        //     if (value >= 0) {
        //         let item = this._props.items[this._props.items.length - 1];
        //         item.select = value;
        //         this.processItem(item);
        //     }
        // });

    }

    select(value: number) {
        if (value >= 0) {
            let item = this._props.items[this._props.items.length - 1];
            item.select = value;
            this.processItem(item);
        }
    }

    scrollToTop(): void {
        this.scrollView.scrollToTop();
    }

    scrollToBottom(animate = true): void {
        if (this.contentLayout.node.height > this.scrollView.node.height) {
            this.scrollView.scrollToBottom(animate ? 0.3 : undefined);
        }
    }

    open(parent: CCView) {
        super.open(parent);

        this.callingNode.active = true;
        this.messageNode.active = false;
        this.node.children[0].opacity = 0;
        this.node.children[1].active = true;
        this.stopPhoneMusic();
        this.node.children[0].runAction(cc.sequence(cc.delayTime(0.2), cc.fadeIn(0.1), cc.callFunc(() => {
            this.node.children[0].opacity = 255;
            this.node.children[1].active = false;
            this.playPhoneMusic();
        })));
    }

    close(clean?: boolean) {
        super.close(clean);
        // 清除内容,防止下次打开的时候先显示上次的内容
        this.contentLayout.node.removeAllChildren();
        this.headIcon1.spriteFrame = undefined as any;
        this.nameLabel1.string = "";
        this.stopPhoneMusic();
        delete this._props;
    }

    onPropsLoad(props: PhoneCallViewProps) {
        super.onPropsLoad(props);
        for (let item of this._props.items) { // 应该只有一条
            this.processItem(item);
        }
    }

    onPropChange(propName: keyof PhoneCallViewProps) {
        super.onPropChange(propName);
        if (propName === "items") {
            for (let i = this.contentLayout.node.children.length; i < this._props.items.length; i++) {
                this.processItem(this._props.items[i]);
            }
        }
    }

    processItem(item: PhoneCallItemProps) {
        let content = item.sentence.content!;
        if (item.isSelf && content.type === SentenceType.SELECT && item.select === undefined) { // show selector
            this._props.onSetContent(content);
            this.nextPlotNode.active = false;
        } else {
            this.nextPlotNode.active = true;
            if (content.type === SentenceType.SELECT && item.select === undefined) {
                console.error("Something went wrong. ", item.sentence);
                return;
            }
            let node = new cc.Node;
            let richLabel = node.addComponent(cc.RichText);
            richLabel.fontSize = 32;
            richLabel.maxWidth = 585;
            if (item.isSelf) {
                node.anchorX = 1;
                node.x = 300;
                node.color = cc.color(62, 46, 198);
                richLabel.horizontalAlign = cc.macro.TextAlignment.RIGHT;
            } else {
                node.anchorX = 0;
                node.x = -300;
                richLabel.horizontalAlign = cc.macro.TextAlignment.LEFT;
            }

            if (content.type === SentenceType.SELECT) {
                let option = content.value[item.select!];
                if (option.content) {
                    if (option.content.type === SentenceType.TEXT) {
                        richLabel.string = richNodesToCocosString(option.content.value);
                    } else {
                        richLabel.string = `SentenceType(${option.content.type}) not supported in phone call.`;
                    }
                } else {
                    richLabel.string = option.summary;
                }
            } else if (content.type === SentenceType.TEXT) {
                richLabel.string = richNodesToCocosString(content.value);
            } else {
                richLabel.string = `SentenceType(${content.type}) not supported in phone call.`;
            }
            node.parent = this.contentLayout.node;
        }

        if (PhoneCallListAutoNextPlot && this.messageNode.active && !this._props.isSentenceSelectVisible()) {
            this.scheduleOnce(() => {
                this._props.onCompletePlot(item.select);
            }, 1);
        } else {
            this._selectIndex = item.select;
        }
        this.contentLayout.updateLayout();
        this.scrollToBottom();
    }
}