import cookies from 'js-cookie'; import semver from 'semver'; import { COOKIE_ROOT_DOMAIN, COOKIE_APP_KEY, COOKIE_APP_EXTRA_KEY, COOKIE_ACCESS_TOKEN_KEY, MSG_REQUIRE_LOGIN, APP_INJECT_COOKIE_KEYS, DEF_SYNCED_COOKIE_EXP } from './constant'; const setupWebViewJavascriptBridge = (callback) => { if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'https://__bridge_loaded__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function () { document.documentElement.removeChild(WVJBIframe); }, 0); }; const parseJWT = (token) => { const payloadStr = token.split('.')[1]; if (!payloadStr) { return null; } try { return JSON.parse(atob(payloadStr)); } catch (e) { // tslint:disable-next-line console.error('[parseJWT]', e); } return null; }; const getAppInfo = () => { const val = cookies.get(COOKIE_APP_KEY); const matched = val && /^(ios|android)\ ((?:\d\.?)+)$/.exec(val); if (!matched) { return null; } return { os: matched[1], version: matched[2] }; }; const getAppExtra = () => { const val = cookies.get(COOKIE_APP_EXTRA_KEY); const segments = val && val.split(/\s+/); if (!segments || !segments.length) { return {}; } return segments.reduce((map, item) => { const matched = /^([0-9a-zA-Z_-]+)\/(.+)$/.exec(item); if (matched) { map[matched[1]] = matched[2]; } return map; }, {}); }; let cachedAppInfo; let cachedappExtra; class ProginnBridge { constructor(opts) { this.root = window.app_event || window.appBridge; const { notifier } = opts || {}; this.notifier = notifier; } get appInfo() { cachedAppInfo = cachedAppInfo || getAppInfo(); return cachedAppInfo; } get appExtra() { cachedappExtra = cachedappExtra || getAppExtra(); return cachedappExtra; } get appVersion() { var _a; return (_a = this.appInfo) === null || _a === void 0 ? void 0 : _a.version; } get os() { var _a; return (_a = this.appInfo) === null || _a === void 0 ? void 0 : _a.os; } get isInApp() { return !!(this.appInfo || this.root); } get isAndroid() { return /Android/.test(window.navigator.userAgent) || this.os === 'android' || false; } get isIos() { return /iP(hone|ad|od)/.test(window.navigator.userAgent) || this.os === 'ios' || false; } get cookie() { return cookies.get(); } get isLogined() { return !!cookies.get(COOKIE_ACCESS_TOKEN_KEY); } get uid() { const token = cookies.get(COOKIE_ACCESS_TOKEN_KEY); const payload = token && parseJWT(token); return payload === null || payload === void 0 ? void 0 : payload.uid; } inject(name, cb, root = 'Proginn') { window[root] = window[root] || {}; window[root][name] = cb; } invoke(fn, data = null, cb = () => { }) { if (this.isIos && this.compareAppVersion('gte', '4.22.0')) { setupWebViewJavascriptBridge((bridge) => { bridge.callHandler(fn, data, cb); }); return; } if (!this.root) { // tslint:disable-next-line console.warn(`Bridge invoke ${fn} skipped.`); return null; } if (this.isAndroid) { if (typeof this.root[fn] === 'function') { return data ? this.root[fn](data) : this.root[fn](); } else { return null; } } else { return this.root(fn, data); } } back() { if (!this.isInApp) { window.history.back(); } else { if (this.isIos && this.compareAppVersion('gte', '4.22.0')) { this.invoke('back'); } else { this.invoke('back_page'); } } } close() { if (this.isAndroid || this.compareAppVersion('lt', '4.22.0')) { this.invoke('finishActivity'); } else { this.invoke('close'); } } load(url) { window.location.href = url; } open(url, title) { if (this.isInApp && (!this.isAndroid || this.compareAppVersion('gte', '4.20.0'))) { url = `proginn://webview?url=${encodeURIComponent(url)}${title ? '&title=' + encodeURIComponent(title) : ''}`; } this.load(url); } login() { if (!this.isInApp) { return; } this.load('proginn://login?backToPage=true'); } checkLogin(force = false) { if (force || !this.isLogined) { this.notifier && this.notifier(MSG_REQUIRE_LOGIN, -99); this.login(); return false; } return true; } compareAppVersion(operator, version) { return this.appVersion ? semver[operator](this.appVersion, version) : false; } syncCookies(opts) { opts = opts || {}; opts.domain = opts.domain || COOKIE_ROOT_DOMAIN; opts.expires = opts.expires || DEF_SYNCED_COOKIE_EXP; for (const key of APP_INJECT_COOKIE_KEYS) { const val = cookies.get(key); if (val) { cookies.set(key, val, opts); } } } // generally to fix android webview cookies non-inject bug cacheCookiesInStorage() { for (const key of APP_INJECT_COOKIE_KEYS) { const val = cookies.get(key); if (val) { window.localStorage.setItem(key, val); } else { window.localStorage.removeItem(key); } } } loadCookiesInStorage(opts) { opts = opts || {}; opts.domain = opts.domain || COOKIE_ROOT_DOMAIN; opts.expires = opts.expires || DEF_SYNCED_COOKIE_EXP; for (const key of APP_INJECT_COOKIE_KEYS) { // pass if already exists if (cookies.get(key)) { continue; } const val = window.localStorage.getItem(key); if (val) { cookies.set(key, val, opts); } } } // load data loadUserData(data) { if (this.isAndroid) { this.invoke('user_load', data); } else if (this.compareAppVersion('lt', '4.22.0')) { this.invoke('user_load', { userInfo: data, }); } else { this.invoke('loadUserData', data); } } loadShareData(data) { if (this.isAndroid) { this.invoke('load_share_data', JSON.stringify(data)); } else if (this.compareAppVersion('lt', '4.22.0')) { this.invoke('load_share_data', data); } else { this.invoke('loadShareData', data); } } loadTopicData(data) { if (this.isAndroid) { this.invoke('topic_load', data.topic_id); } else if (this.compareAppVersion('lt', '4.22.0')) { this.invoke('topic_load', data); } else { this.invoke('loadTopicData', data); } } // ui setNavigationBarColor(hex) { if (this.isAndroid || this.compareAppVersion('lt', '4.22.0')) { this.invoke('setTitleBarColor', hex); } else { this.invoke('setNavigationBarColor', hex); } } setNavigationBarTitle(text) { this.invoke('setNavigationBarTitle', text); } } export default ProginnBridge;