yoho-app.js 7.89 KB
/**
 * YOHO-SDK
 *
 * 与原生 APP 交互的代码
 * 所有函数要做降级处理
 * 假如不是 YOHO App,在浏览器实现对应的功能
 * 浏览器不支持的功能,给出提示,控制台不能报错,不影响后续代码执行
 *
 * 希望能与 微信 JS-SDK 一样方便
 * http://git.yoho.cn/mobile/AppJSBridge/blob/master/AppH5Bridge.md
 * http://git.yoho.cn/mobile/appbridge    old、sick、ugly
 */
let $ = require('yoho-jquery');
let tip = require('./plugin/tip');
let cookie = require('yoho-cookie');

require('js/common');

/* 空方法 */
let emptyFn = function() {};

/* 提示信息 */
let tipInfo = '暂不支持,请在YOHO!BUY应用中打开';
let unknownInfo = '未知异常,请刷新页面后重试';

let qs = window.queryString;

let yoho, $appLink;

$appLink = $('#yoho-app-link');

if (!$appLink.length) {
    $('body').append('<a id="yoho-app-link" href="javascript:;" style="display:none !important;"></a>');
    $appLink = $('#yoho-app-link');
}
const isiPhoneXSeries = () => {
    console.log(navigator.userAgent);
    let isiOS = /\(i[^;]+;( U;)? CPU.+Mac OS X/i.test(navigator.userAgent || '');

    if (!window || !isiOS) {
        return false;
    }
    const xSeriesConfig = [{ // iPhone Xs(Max,Pro Max)
            devicePixelRatio: 3,
            width: 414,
            height: 896,
        },
        { // iPhone XR(11)
            devicePixelRatio: 2,
            width: 414,
            height: 896,
        },
        { // iPhone X(Xs,Pro)
            devicePixelRatio: 3,
            width: 375,
            height: 812,
        },
    ];
    const {
        devicePixelRatio,
        screen: {
            width,
            height
        }
    } = window;

    // eslint-disable-next-line max-len
    return xSeriesConfig.some(item => item.devicePixelRatio === devicePixelRatio && item.width === width && item.height === height);
    };

yoho = {
    /**
     * 判断是否是 APP
     */
    isNowApp: /yohonow/i.test(navigator.userAgent || ''),
    isMarsApp: /YohoMars/i.test(navigator.userAgent || ''),
    isYohoApp: /YohoBuy/i.test(navigator.userAgent || ''),
    isMiniApp: /miniProgram/i.test(navigator.userAgent || '') || qs && qs.client_type === 'miniapp',
    isApp: /YohoMars/i.test(navigator.userAgent || '') ||
        /YohoBuy/i.test(navigator.userAgent || '') ||
        /yohonow/i.test(navigator.userAgent || '') ||
        qs && qs.app_version,
    isiOS: /\(i[^;]+;( U;)? CPU.+Mac OS X/i.test(navigator.userAgent || ''),
    isAndroid: /Android/i.test(navigator.userAgent || ''),
    isWechat: /micromessenger/i.test(navigator.userAgent || ''),
    isiPhoneXSeries: isiPhoneXSeries() || false,

    /**
     * JS 与 APP 共享的对象
     */
    data: window.yohoInterfaceData,

    ready: function(callback) {
        // App 未注入 yohoInterface 的时候,延迟执行
        if (this.isApp && !window.yohoInterface) {
            document.addEventListener('deviceready', callback);
        } else {
            return callback();
        }
    },

    /**
     * 调用APP原生方法
     * @param method 方法名称
     * @param args 传递给 APP 的参数 {"index":tab_index}
     * @param success 调用成功的回调方法
     * @param fail 调用失败的回调方法
     */
    invokeMethod: function(method, args, success, fail) {
        let appInterface = window.yohoInterface;

        if (this.isApp) {
            if (appInterface) {
                appInterface.triggerEvent(success || emptyFn, fail || emptyFn, {
                    method: method,
                    arguments: args
                });
            } else {
                tip.show(unknownInfo);
            }
        } else {
            tip.show(tipInfo);
        }
    },

    /**
     * 原生调用 JS 方法
     * @param name 方法名
     * @param callback 回调
     */
    addNativeMethod: function(name, callback) {
        let appInterface = window.yohoInterface;

        // 延迟 500ms 注入
        setTimeout(function() {
            if (appInterface) {
                appInterface[name] = callback;
            }
        }, 500);
    },

    parseUrl: function(url) {
        let query = {},
            hashs,
            hash,
            i;

        url = (url || '').split('?');
        hashs = (url[1] || '').split('&');

        if (hashs && hashs.length) {
            for (i = 0; i < hashs.length; i++) {
                hash = hashs[i].split('=');
                query[hash[0]] = hash[1];
            }
        }

        return {
            path: url[0],
            query: query
        };
    },

    getClientUserInfo: function() {
        return new Promise((resolve, reject) => {
            let userInfo = {};
            let successFn = function(info) {
                $.extend(userInfo, info);

                if (userInfo.hasOwnProperty('uid') && userInfo.hasOwnProperty('session_key')) {
                    return resolve(userInfo);
                }
            };

            this.invokeMethod('get.uid', {}, uid => {
                successFn({uid: uid});
            }, () => {
                return reject();
            });

            this.invokeMethod('get.sessionId', {}, sessionId => {
                successFn({session_key: sessionId});
            }, () => {
                return reject();
            });
        });
    },

    getUid: function() {
        if (yoho.isApp) {
            return qs.uid || cookie.get('_YOHOUID') || cookie.get('app_uid');
        }

        return window.getUid();
    },

    /**
     * 判断是否是 登录
     */
    isLogin: function() {
        return this.getUid();
    },

    goLogin: function(refer, data) {
        if (this.isMiniApp) {
            return false;
        }
        let url;

        if (refer.indexOf('//') === 0) {
            refer = location.protocol + refer;
        }

        url = 'http://m.yohobuy.com/signin.html?refer=' + encodeURIComponent(refer);
        refer = yoho.parseUrl(refer || location.href);

        if (this.isApp) {
            url = location.href;
            if (this.isAndroid) {
                if (url.indexOf('?') < 0) {
                    url += '?appLogin=1';
                }
                if (location.href.indexOf('&openby') >= 0) {
                    url = url.substring(0, url.indexOf('&openby'));
                }
                url += '&';
            } else {
                if (location.href.indexOf('#openby') >= 0) {
                    url = url.substring(0, url.indexOf('#openby'));
                }
                url += '#';
            }

            url += 'openby:yohobuy=' + (data || JSON.stringify({
                action: 'go.weblogin',
                params: {
                    priority: 'N',
                    jumpurl: {
                        url: refer.path,
                        param: refer.query
                    },
                    needlogout: 'Y'
                }
            }));
        }
        $appLink.attr('href', url);
        $appLink[0].click();
        return false;
    },

    goH5: function(link, data) {
        let url = link;

        if (!link) {
            return;
        }
        link = yoho.parseUrl(link || location.href);

        if (yoho.isApp) {
            url = url + '&openby:yohobuy=' + (data || JSON.stringify({
                action: 'go.h5',
                params: {
                    islogin: 'N',
                    type: 0,
                    updateflag: Date.now() + '',
                    url: link.path,
                    param: link.query
                }
            }));
        }

        $appLink.attr('href', url);
        $appLink[0].click();
        return false;
    },

    goHome: function() {
        var url = '//m.yohobuy.com/';

        if (yoho.isApp) {
            url = url + '?openby:yohobuy=' + JSON.stringify({
                action: 'go.home'
            });
        }
        $appLink.attr('href', url);
        $appLink[0].click();
        return false;
    }
};

module.exports = yoho;