push.js 4.0 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6 7 8 9 10
import {
  isFn,
  isPlainObject
} from 'uni-shared'
import {
  getApiCallbacks
} from 'uni-helpers/utils'

let cid
let cidErrMsg
fxy060608's avatar
fxy060608 已提交
11
let enabled
fxy060608's avatar
fxy060608 已提交
12
let offline
fxy060608's avatar
fxy060608 已提交
13

14
function normalizePushMessage (message) {
fxy060608's avatar
fxy060608 已提交
15
  try {
16
    return JSON.parse(message)
fxy060608's avatar
fxy060608 已提交
17 18 19 20 21 22 23
  } catch (e) {}
  return message
}

export function invokePushCallback (
  args
) {
fxy060608's avatar
fxy060608 已提交
24 25
  if (args.type === 'enabled') {
    enabled = true
fxy060608's avatar
fxy060608 已提交
26
    if (__PLATFORM__ === 'app-plus') {
fxy060608's avatar
fxy060608 已提交
27 28
      offline = args.offline
    }
fxy060608's avatar
fxy060608 已提交
29
  } else if (args.type === 'clientId') {
fxy060608's avatar
fxy060608 已提交
30 31 32 33
    cid = args.cid
    cidErrMsg = args.errMsg
    invokeGetPushCidCallbacks(cid, args.errMsg)
  } else if (args.type === 'pushMsg') {
fxy060608's avatar
fxy060608 已提交
34 35 36 37 38 39 40 41 42 43 44 45
    const message = {
      type: 'receive',
      data: normalizePushMessage(args.message)
    }
    for (let i = 0; i < onPushMessageCallbacks.length; i++) {
      const callback = onPushMessageCallbacks[i]
      callback(message)
      // 该消息已被阻止
      if (message.stopped) {
        break
      }
    }
fxy060608's avatar
fxy060608 已提交
46 47 48 49
  } else if (args.type === 'click') {
    onPushMessageCallbacks.forEach((callback) => {
      callback({
        type: 'click',
50
        data: normalizePushMessage(args.message)
fxy060608's avatar
fxy060608 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64
      })
    })
  }
}

const getPushCidCallbacks = []

function invokeGetPushCidCallbacks (cid, errMsg) {
  getPushCidCallbacks.forEach((callback) => {
    callback(cid, errMsg)
  })
  getPushCidCallbacks.length = 0
}

65
export function getPushClientId (args) {
fxy060608's avatar
fxy060608 已提交
66 67 68 69 70 71 72 73 74 75 76
  if (!isPlainObject(args)) {
    args = {}
  }
  const {
    success,
    fail,
    complete
  } = getApiCallbacks(args)
  const hasSuccess = isFn(success)
  const hasFail = isFn(fail)
  const hasComplete = isFn(complete)
fxy060608's avatar
fxy060608 已提交
77 78

  // App 端且启用离线时,使用 getClientInfoAsync 来调用
fxy060608's avatar
fxy060608 已提交
79
  if (__PLATFORM__ === 'app-plus' && offline) {
fxy060608's avatar
fxy060608 已提交
80 81 82 83
    plus.push.getClientInfoAsync(
      (info) => {
        const res = {
          errMsg: 'getPushClientId:ok',
fxy060608's avatar
fxy060608 已提交
84
          cid: info.clientid
fxy060608's avatar
fxy060608 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        }
        hasSuccess && success(res)
        hasComplete && complete(res)
      },
      (res) => {
        res = {
          errMsg: 'getPushClientId:fail ' + (res.code + ': ' + res.message)
        }
        hasFail && fail(res)
        hasComplete && complete(res)
      }
    )
    return
  }

fxy060608's avatar
fxy060608 已提交
100 101 102 103
  Promise.resolve().then(() => {
    if (typeof enabled === 'undefined') {
      enabled = false
      cid = ''
fxy060608's avatar
fxy060608 已提交
104
      cidErrMsg = 'uniPush is not enabled'
fxy060608's avatar
fxy060608 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118
    }
    getPushCidCallbacks.push((cid, errMsg) => {
      let res
      if (cid) {
        res = {
          errMsg: 'getPushClientId:ok',
          cid
        }
        hasSuccess && success(res)
      } else {
        res = {
          errMsg: 'getPushClientId:fail' + (errMsg ? ' ' + errMsg : '')
        }
        hasFail && fail(res)
fxy060608's avatar
fxy060608 已提交
119
      }
fxy060608's avatar
fxy060608 已提交
120 121 122 123
      hasComplete && complete(res)
    })
    if (typeof cid !== 'undefined') {
      invokeGetPushCidCallbacks(cid, cidErrMsg)
fxy060608's avatar
fxy060608 已提交
124 125 126 127 128
    }
  })
}

const onPushMessageCallbacks = []
fxy060608's avatar
fxy060608 已提交
129
let listening = false
fxy060608's avatar
fxy060608 已提交
130 131 132 133
// 不使用 defineOnApi 实现,是因为 defineOnApi 依赖 UniServiceJSBridge ,该对象目前在小程序上未提供,故简单实现
export const onPushMessage = (fn) => {
  if (onPushMessageCallbacks.indexOf(fn) === -1) {
    onPushMessageCallbacks.push(fn)
fxy060608's avatar
fxy060608 已提交
134 135
  }
  // 不能程序启动时就监听,因为离线事件,仅触发一次,框架监听后,无法转发给还没开始监听的开发者
fxy060608's avatar
fxy060608 已提交
136
  if (__PLATFORM__ === 'app-plus' && !listening) {
fxy060608's avatar
fxy060608 已提交
137 138 139 140 141 142 143 144 145 146 147 148 149
    listening = true
    plus.push.addEventListener('click', (result) => {
      invokePushCallback({
        type: 'click',
        message: result
      })
    })
    plus.push.addEventListener('receive', (result) => {
      invokePushCallback({
        type: 'pushMsg',
        message: result
      })
    })
fxy060608's avatar
fxy060608 已提交
150 151 152 153 154 155 156 157 158 159 160 161
  }
}

export const offPushMessage = (fn) => {
  if (!fn) {
    onPushMessageCallbacks.length = 0
  } else {
    const index = onPushMessageCallbacks.indexOf(fn)
    if (index > -1) {
      onPushMessageCallbacks.splice(index, 1)
    }
  }
fxy060608's avatar
fxy060608 已提交
162
}