push.ts 3.7 KB
Newer Older
1
import { defineAsyncApi } from '../../helpers/api'
fxy060608's avatar
fxy060608 已提交
2

fxy060608's avatar
fxy060608 已提交
3 4
interface OnPushEnabledCallback {
  type: 'enabled'
fxy060608's avatar
fxy060608 已提交
5
  offline: boolean
fxy060608's avatar
fxy060608 已提交
6 7 8
}

interface OnPushClientIdCallback {
fxy060608's avatar
fxy060608 已提交
9 10
  type: 'clientId'
  cid: string
fxy060608's avatar
fxy060608 已提交
11
  errMsg?: string
fxy060608's avatar
fxy060608 已提交
12 13 14 15 16 17 18 19 20 21 22 23
}

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

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

fxy060608's avatar
fxy060608 已提交
24 25 26 27 28 29 30
interface OnPushClickCallback {
  type: 'click'
  message: unknown
}

let cid: string | undefined
let cidErrMsg: string | undefined
fxy060608's avatar
fxy060608 已提交
31
let enabled: boolean | undefined
fxy060608's avatar
fxy060608 已提交
32
let offline: boolean | undefined
fxy060608's avatar
fxy060608 已提交
33

fxy060608's avatar
fxy060608 已提交
34
function normalizePushMessage(message: unknown) {
fxy060608's avatar
fxy060608 已提交
35
  try {
fxy060608's avatar
fxy060608 已提交
36
    return JSON.parse(message as string) as Record<string, any>
fxy060608's avatar
fxy060608 已提交
37 38 39
  } catch (e: any) {}
  return message
}
fxy060608's avatar
fxy060608 已提交
40 41 42 43 44
/**
 * @private
 * @param args
 */
export function invokePushCallback(
fxy060608's avatar
fxy060608 已提交
45
  args:
fxy060608's avatar
fxy060608 已提交
46 47
    | OnPushEnabledCallback
    | OnPushClientIdCallback
fxy060608's avatar
fxy060608 已提交
48 49 50
    | OnPushLineStateCallback
    | OnPushMsgCallback
    | OnPushClickCallback
fxy060608's avatar
fxy060608 已提交
51
) {
fxy060608's avatar
fxy060608 已提交
52 53
  if (args.type === 'enabled') {
    enabled = true
fxy060608's avatar
fxy060608 已提交
54 55 56
    if (__PLATFORM__ === 'app') {
      offline = args.offline
    }
fxy060608's avatar
fxy060608 已提交
57
  } else if (args.type === 'clientId') {
fxy060608's avatar
fxy060608 已提交
58
    cid = args.cid
fxy060608's avatar
fxy060608 已提交
59 60
    cidErrMsg = args.errMsg
    invokeGetPushCidCallbacks(cid, args.errMsg)
fxy060608's avatar
fxy060608 已提交
61
  } else if (args.type === 'pushMsg') {
fxy060608's avatar
fxy060608 已提交
62 63 64 65 66 67 68 69 70 71 72 73
    const message: OnPushMessageSuccess = {
      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 已提交
74 75
  } else if (args.type === 'click') {
    onPushMessageCallbacks.forEach((callback) => {
fxy060608's avatar
fxy060608 已提交
76 77
      callback({
        type: 'click',
fxy060608's avatar
fxy060608 已提交
78
        data: normalizePushMessage(args.message),
fxy060608's avatar
fxy060608 已提交
79
      })
fxy060608's avatar
fxy060608 已提交
80 81 82 83
    })
  }
}

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

fxy060608's avatar
fxy060608 已提交
86
function invokeGetPushCidCallbacks(cid?: string, errMsg?: string) {
fxy060608's avatar
fxy060608 已提交
87
  getPushCidCallbacks.forEach((callback) => {
fxy060608's avatar
fxy060608 已提交
88
    callback(cid, errMsg)
fxy060608's avatar
fxy060608 已提交
89 90 91 92
  })
  getPushCidCallbacks.length = 0
}

93 94 95 96
const API_GET_PUSH_CLIENT_ID = 'getPushClientId'
export const getPushClientId = defineAsyncApi(
  API_GET_PUSH_CLIENT_ID,
  (_, { resolve, reject }) => {
fxy060608's avatar
fxy060608 已提交
97 98 99 100 101 102 103 104 105 106 107 108
    // App 端且启用离线时,使用 getClientInfoAsync 来调用
    if (__PLATFORM__ === 'app' && offline) {
      plus.push.getClientInfoAsync(
        (info) => {
          resolve({ cid: info.clientid })
        },
        (res) => {
          reject(res.code + ': ' + res.message)
        }
      )
      return
    }
fxy060608's avatar
fxy060608 已提交
109 110 111 112
    Promise.resolve().then(() => {
      if (typeof enabled === 'undefined') {
        enabled = false
        cid = ''
fxy060608's avatar
fxy060608 已提交
113
        cidErrMsg = 'uniPush is not enabled'
fxy060608's avatar
fxy060608 已提交
114 115 116 117 118 119 120 121 122 123
      }
      getPushCidCallbacks.push((cid?: string, errMsg?: string) => {
        if (cid) {
          resolve({ cid })
        } else {
          reject(errMsg)
        }
      })
      if (typeof cid !== 'undefined') {
        invokeGetPushCidCallbacks(cid, cidErrMsg)
124 125
      }
    })
fxy060608's avatar
fxy060608 已提交
126
  }
127
)
fxy060608's avatar
fxy060608 已提交
128 129

interface OnPushMessageSuccess {
fxy060608's avatar
fxy060608 已提交
130
  type: 'click' | 'receive'
fxy060608's avatar
fxy060608 已提交
131
  data: unknown
fxy060608's avatar
fxy060608 已提交
132
  stopped?: boolean
fxy060608's avatar
fxy060608 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
}

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)
    }
  }
}