'f'
mh-two-thousand-and-two
2024-04-12 26f2711ef9461961fb953e2b497bd314ef95e345
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import {
  isFn,
  isPlainObject
} from 'uni-shared'
import {
  getApiCallbacks
} from 'uni-helpers/utils'
 
let cid
let cidErrMsg
let enabled
let offline
 
function normalizePushMessage (message) {
  try {
    return JSON.parse(message)
  } catch (e) {}
  return message
}
 
export function invokePushCallback (
  args
) {
  if (args.type === 'enabled') {
    enabled = true
    if (__PLATFORM__ === 'app-plus') {
      offline = args.offline
    }
  } else if (args.type === 'clientId') {
    cid = args.cid
    cidErrMsg = args.errMsg
    invokeGetPushCidCallbacks(cid, args.errMsg)
  } else if (args.type === 'pushMsg') {
    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
      }
    }
  } else if (args.type === 'click') {
    onPushMessageCallbacks.forEach((callback) => {
      callback({
        type: 'click',
        data: normalizePushMessage(args.message)
      })
    })
  }
}
 
const getPushCidCallbacks = []
 
function invokeGetPushCidCallbacks (cid, errMsg) {
  getPushCidCallbacks.forEach((callback) => {
    callback(cid, errMsg)
  })
  getPushCidCallbacks.length = 0
}
 
export function getPushClientId (args) {
  if (!isPlainObject(args)) {
    args = {}
  }
  const {
    success,
    fail,
    complete
  } = getApiCallbacks(args)
  const hasSuccess = isFn(success)
  const hasFail = isFn(fail)
  const hasComplete = isFn(complete)
 
  // App 端且启用离线时,使用 getClientInfoAsync 来调用
  if (__PLATFORM__ === 'app-plus' && offline) {
    plus.push.getClientInfoAsync(
      (info) => {
        const res = {
          errMsg: 'getPushClientId:ok',
          cid: info.clientid
        }
        hasSuccess && success(res)
        hasComplete && complete(res)
      },
      (res) => {
        res = {
          errMsg: 'getPushClientId:fail ' + (res.code + ': ' + res.message)
        }
        hasFail && fail(res)
        hasComplete && complete(res)
      }
    )
    return
  }
 
  Promise.resolve().then(() => {
    if (typeof enabled === 'undefined') {
      enabled = false
      cid = ''
      cidErrMsg = 'uniPush is not enabled'
    }
    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)
      }
      hasComplete && complete(res)
    })
    if (typeof cid !== 'undefined') {
      invokeGetPushCidCallbacks(cid, cidErrMsg)
    }
  })
}
 
const onPushMessageCallbacks = []
let listening = false
// 不使用 defineOnApi 实现,是因为 defineOnApi 依赖 UniServiceJSBridge ,该对象目前在小程序上未提供,故简单实现
export const onPushMessage = (fn) => {
  if (onPushMessageCallbacks.indexOf(fn) === -1) {
    onPushMessageCallbacks.push(fn)
  }
  // 不能程序启动时就监听,因为离线事件,仅触发一次,框架监听后,无法转发给还没开始监听的开发者
  if (__PLATFORM__ === 'app-plus' && !listening) {
    listening = true
    plus.push.addEventListener('click', (result) => {
      invokePushCallback({
        type: 'click',
        message: result
      })
    })
    plus.push.addEventListener('receive', (result) => {
      invokePushCallback({
        type: 'pushMsg',
        message: result
      })
    })
  }
}
 
export const offPushMessage = (fn) => {
  if (!fn) {
    onPushMessageCallbacks.length = 0
  } else {
    const index = onPushMessageCallbacks.indexOf(fn)
    if (index > -1) {
      onPushMessageCallbacks.splice(index, 1)
    }
  }
}