WxGrid.ts 8.61 KB
import WxSystem from "./WxSystem";
import SDKUtils from "../utils/SDKUtils";
import { BannerError, __LOG__ } from "../base/SDKConst";
import LogService from "../service/LogService";
import { DOT_AD_STATUS, DOT_AD_TYPE } from "../base/SDKEnum";

/*
* banner
*/
export default class WxGrid {
    private static instance: WxGrid;
    static get I(): WxGrid {
        return this.instance || (this.instance = new WxGrid(750, 750));
    }
    private designWidth: number;
    private bannerWidth: number;
    private bannerHeight: number;
    private bannerScale: number;
    private bannerParams: any;
    private _isErrored: boolean;
    private adUnitId: string;
    private gridAd: any;
    private resolve: any;
    private reject: any;
    private AdList: object

    constructor(designWidth: number, bannerWidth: number) {
        designWidth = designWidth || 750;
        bannerWidth = bannerWidth || 750;

        this.AdList = {}
        this.adUnitId = '';
        this._isErrored = false;
        this.designWidth = designWidth;
        this.bannerScale = WxSystem.I.winWidth / this.designWidth;
        this.bannerWidth = Math.max(this.bannerScale * bannerWidth, 300);
        this.bannerHeight = WxSystem.I.winHeight / this.bannerScale;
    }

    get isErrored() {
        return this._isErrored;
    }

    create(key: string, adUnitId: string, opts?: { gridCount?: number; bannerWidth?: number, offsetY: number; adIntervals?: number }) {
        this.bannerParams = opts || {};
        this.AdList[key] = {
            ...opts,
            adUnitId,
            key,
            isEnd: false,
            queue: []
        }
        if (opts && opts.bannerWidth) {
            this.bannerWidth = opts.bannerWidth;
        }
        this.bannerParams.type = this.bannerParams.type || 1;
        this.bannerParams.gridCount = this.bannerParams.gridCount || 5;
        this.bannerParams.offsetY = -this.bannerParams.offsetY || 0;
        this.bannerParams.adIntervals = this.bannerParams.adIntervals || 60;
        return new Promise((resolve, reject) => {
            this.resolve = resolve;
            this.reject = reject;
            this._isErrored = false;
            this.adUnitId = adUnitId;

            if (SDKUtils.isEmpty(adUnitId))
                return this.reject({ ...BannerError.BannerInvalid, adUnitId: this.adUnitId });

            // 设置样式(hack:修复qq版本)
            this.bannerParams.type === 2 && (this.bannerWidth = WxSystem.I.winWidth);
            let style = { top: 0, left: (WxSystem.I.winWidth - this.bannerWidth) / 2, width: this.bannerWidth };
            style = {
                ...style,
                top: 0 + this.bannerParams.offsetY
            };
            if (this.AdList[key].gridAd) {
                if (this.AdList[key].isOff) {
                    this.show(key)
                }
                resolve()
                return
            }
            // 创建并判断是否存在
            this.gridAd = wx.createGridAd({ adUnitId, style: { left: style.left, top: this.bannerHeight }, gridCount: this.bannerParams.gridCount, });
            LogService.I.adStat('grid', adUnitId, DOT_AD_TYPE.grid, DOT_AD_STATUS.request)
            if (!this.gridAd)
                return this.reject({ ...BannerError.BannerNotOpen, adUnitId: this.adUnitId });
            this.AdList[key].gridAd = this.gridAd;
            this.gridAd.onLoad(this.onLoad);
            this.gridAd.onError(this.onError);
            this.gridAd.onResize(this.onResize);
            if (!this.AdList[key].isOff) {
                this.show(key);
            }
        });
    }

    show(key: string): boolean {
        if (this.AdList[key].gridAd) {
            if (this.AdList[key].isEnd) {
                let fun = (key) => {
                    WxGrid.I.show(key)
                }
                this.AdList[key].queue.push(fun);
                return
            }
            this.AdList[key].isEnd = true;

            if (this.AdList[key].gridAd.style.realHeight)
                this.AdList[key].gridAd.style.top = WxSystem.I.winHeight - this.AdList[key].gridAd.style.realHeight + this.AdList[key].offsetY;
            if (this.bannerParams.type === 2) {
                if (this.AdList[key].gridAd.style.width)
                    this.AdList[key].gridAd.style.left = (WxSystem.I.winWidth - this.AdList[key].gridAd.style.width) / 2;
                else
                    this.AdList[key].gridAd.style.left = (WxSystem.I.winWidth - this.bannerWidth) / 2;
            } else
                this.AdList[key].gridAd.style.left = (WxSystem.I.winWidth - this.bannerWidth) / 2;

            LogService.I.adStat('grid', this.AdList[key].adUnitId, DOT_AD_TYPE.grid, DOT_AD_STATUS.show)
            this.AdList[key].gridAd.show().catch((err: any) => this.handleShowError(err));
            this.onResize();
            __LOG__ && console.error('WxGrid - show: ' + this.adUnitId, this.AdList[key].gridAd.style);
            WxGrid.I.handleQueue(key)
            return true;
        }
        WxGrid.I.handleQueue(key)
        return false;
    }

    hide(key: string) {
        if (this.AdList[key].gridAd) {
            if (this.AdList[key].isEnd) {
                let fun = (key) => {
                    WxGrid.I.hide(key)
                }
                this.AdList[key].queue.push(fun);
                return
            }
            this.AdList[key].isEnd = true;
            this.AdList[key].gridAd.style.left = -9999;
            this.AdList[key].gridAd.hide();
            LogService.I.adStat('grid', this.AdList[key].adUnitId, DOT_AD_TYPE.grid, DOT_AD_STATUS.interrupt);
            __LOG__ && console.error('WxGrid - hide: ' + this.adUnitId);

            WxGrid.I.handleQueue(key)
        }
    }

    destory(key: string) {
        if (this.AdList[key] && this.AdList[key].gridAd) {
            this.AdList[key].gridAd.style.left = -9999;
            this.AdList[key].gridAd.destroy();
            this.AdList[key].gridAd = null;
            LogService.I.adStat('grid', this.AdList[key].adUnitId, DOT_AD_TYPE.grid, DOT_AD_STATUS.interrupt)
            __LOG__ && console.error('WxGrid - destory: ' + this.AdList[key].adUnitId);
        }
    }

    private onLoad() {
        let that = WxGrid.I;
        let gridAd = that.gridAd;
        if (!gridAd) return;
        // Platform.IsQQ && that.show();
        __LOG__ && console.error('WxGrid - onLoad: ' + that.adUnitId);
        if (gridAd.style.realHeight) {
            gridAd.style.top = WxSystem.I.winHeight - gridAd.style.realHeight + that.bannerParams.offsetY;
            gridAd.style.left = (WxSystem.I.winWidth - gridAd.style.realWidth) / 2;
        }

        that.unbind();
        that.resolve && that.resolve({
            adUnitId: that.adUnitId,
            scale: that.bannerScale,
            width: gridAd.style.realWidth / that.bannerScale,
            height: gridAd.style.realHeight / that.bannerScale
        });
    }

    private onError(err: any) {
        __LOG__ && console.error('WxGrid - onError', err);
        let that = WxGrid.I;
        !that._isErrored && that.handleError(err, { ...BannerError.BannerFail, adUnitId: that.adUnitId });
    }

    private onResize() {
        let that = WxGrid.I;
        let gridAd = that.gridAd;
        if (!gridAd) return;
        gridAd.style.top = WxSystem.I.winHeight - gridAd.style.realHeight + that.bannerParams.offsetY;
        gridAd.style.left = (WxSystem.I.winWidth - gridAd.style.realWidth) / 2;
    }

    private handleShowError(ret: { errCode: number; errMsg: string }) {
        __LOG__ && console.error('WxGrid - handleShowError', ret);
        let that = WxGrid.I;
        let { errCode, errMsg } = ret;
        !that.isErrored && that.handleError(ret, { code: errCode, msg: errMsg });
    }

    private handleError(ret: any, err: any) {
        let that = WxGrid.I;
        that.unbind();
        if (that.gridAd) {
            that.gridAd.destroy()
        }
        that.gridAd = null;
        that._isErrored = true;
        that.reject && that.reject({ ...err, adUnitId: that.adUnitId });
        LogService.I.adStat('grid', that.adUnitId, DOT_AD_TYPE.grid, DOT_AD_STATUS.fail)
        __LOG__ && console.error('WxGrid - onError: ' + that.adUnitId);
    }

    private unbind() {
        if (this.gridAd) {
            this.gridAd.offLoad(this.onLoad);
            this.gridAd.offError(this.onError);
            this.gridAd.offResize(this.onResize);
        }
    }
    /**
     * 处队列
     */
    handleQueue(key) {
        let that = WxGrid.I;
        if (that.AdList[key].queue.length > 0) {
            that.AdList[key].isEnd = false;
            let fn = that.AdList[key].queue.shift();
            fn();
        } else {
            that.AdList[key].isEnd = false;
        }
    }
}