push.ts 3.2 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6
import { isFunction, isPlainObject } from '@vue/shared'
import { getApiCallbacks } from '../../helpers/api/callback'

interface OnPushCidCallback {
  type: 'clientId'
  cid: string
fxy060608's avatar
fxy060608 已提交
7
  errMsg?: string
fxy060608's avatar
fxy060608 已提交
8 9 10 11 12 13 14 15 16 17 18 19
}

interface OnPushLineStateCallback {
  type: 'lineState'
  online: boolean
}

interface OnPushMsgCallback {
  type: 'pushMsg'
  message: unknown
}

fxy060608's avatar
fxy060608 已提交
20 21 22 23 24 25 26
interface OnPushClickCallback {
  type: 'click'
  message: unknown
}

let cid: string | undefined
let cidErrMsg: string | undefined
fxy060608's avatar
fxy060608 已提交
27
function normalizePushMessage(message: unknown) {
fxy060608's avatar
fxy060608 已提交
28
  try {
fxy060608's avatar
fxy060608 已提交
29
    return JSON.parse(message as string) as Record<string, any>
fxy060608's avatar
fxy060608 已提交
30 31 32
  } catch (e: any) {}
  return message
}
fxy060608's avatar
fxy060608 已提交
33 34 35 36 37
/**
 * @private
 * @param args
 */
export function invokePushCallback(
fxy060608's avatar
fxy060608 已提交
38 39 40 41 42
  args:
    | OnPushCidCallback
    | OnPushLineStateCallback
    | OnPushMsgCallback
    | OnPushClickCallback
fxy060608's avatar
fxy060608 已提交
43 44 45
) {
  if (args.type === 'clientId') {
    cid = args.cid
fxy060608's avatar
fxy060608 已提交
46 47
    cidErrMsg = args.errMsg
    invokeGetPushCidCallbacks(cid, args.errMsg)
fxy060608's avatar
fxy060608 已提交
48 49
  } else if (args.type === 'pushMsg') {
    onPushMessageCallbacks.forEach((callback) => {
fxy060608's avatar
fxy060608 已提交
50 51
      callback({
        type: 'receive',
fxy060608's avatar
fxy060608 已提交
52
        data: normalizePushMessage(args.message),
fxy060608's avatar
fxy060608 已提交
53
      })
fxy060608's avatar
fxy060608 已提交
54 55 56
    })
  } else if (args.type === 'click') {
    onPushMessageCallbacks.forEach((callback) => {
fxy060608's avatar
fxy060608 已提交
57 58
      callback({
        type: 'click',
fxy060608's avatar
fxy060608 已提交
59
        data: normalizePushMessage(args.message),
fxy060608's avatar
fxy060608 已提交
60
      })
fxy060608's avatar
fxy060608 已提交
61 62 63 64 65 66 67 68
    })
  }
}

interface GetPushCidOptions {
  success?: OnPushMessageSuccess
}

fxy060608's avatar
fxy060608 已提交
69
const getPushCidCallbacks: ((cid?: string, errMsg?: string) => void)[] = []
fxy060608's avatar
fxy060608 已提交
70

fxy060608's avatar
fxy060608 已提交
71
function invokeGetPushCidCallbacks(cid?: string, errMsg?: string) {
fxy060608's avatar
fxy060608 已提交
72
  getPushCidCallbacks.forEach((callback) => {
fxy060608's avatar
fxy060608 已提交
73
    callback(cid, errMsg)
fxy060608's avatar
fxy060608 已提交
74 75 76 77
  })
  getPushCidCallbacks.length = 0
}

78
export function getPushClientid(args: GetPushCidOptions) {
fxy060608's avatar
fxy060608 已提交
79 80 81 82 83 84 85
  if (!isPlainObject(args)) {
    args = {}
  }
  const { success, fail, complete } = getApiCallbacks(args)
  const hasSuccess = isFunction(success)
  const hasFail = isFunction(fail)
  const hasComplete = isFunction(complete)
fxy060608's avatar
fxy060608 已提交
86
  getPushCidCallbacks.push((cid?: string, errMsg?: string) => {
fxy060608's avatar
fxy060608 已提交
87 88
    let res: Record<string, unknown>
    if (cid) {
89
      res = { errMsg: 'getPushClientid:ok', cid }
fxy060608's avatar
fxy060608 已提交
90 91
      hasSuccess && success(res)
    } else {
92
      res = { errMsg: 'getPushClientid:fail' + (errMsg ? ' ' + errMsg : '') }
fxy060608's avatar
fxy060608 已提交
93 94 95 96
      hasFail && fail(res)
    }
    hasComplete && complete(res)
  })
fxy060608's avatar
fxy060608 已提交
97 98
  if (typeof cid !== 'undefined') {
    Promise.resolve().then(() => invokeGetPushCidCallbacks(cid, cidErrMsg))
fxy060608's avatar
fxy060608 已提交
99 100 101 102
  }
}

interface OnPushMessageSuccess {
fxy060608's avatar
fxy060608 已提交
103
  type: 'click' | 'receive'
fxy060608's avatar
fxy060608 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
  data: unknown
}

type OnPushMessageCallback = (result: OnPushMessageSuccess) => void
const onPushMessageCallbacks: OnPushMessageCallback[] = []
// 不使用 defineOnApi 实现,是因为 defineOnApi 依赖 UniServiceJSBridge ,该对象目前在小程序上未提供,故简单实现
export const onPushMessage: (fn: OnPushMessageCallback) => void = (fn) => {
  if (onPushMessageCallbacks.indexOf(fn) === -1) {
    onPushMessageCallbacks.push(fn)
  }
}

export const offPushMessage: (fn?: OnPushMessageCallback) => void = (fn) => {
  if (!fn) {
    onPushMessageCallbacks.length = 0
  } else {
    const index = onPushMessageCallbacks.indexOf(fn)
    if (index > -1) {
      onPushMessageCallbacks.splice(index, 1)
    }
  }
}