98 lines
2.5 KiB
JavaScript
98 lines
2.5 KiB
JavaScript
import { getStorageFun, TOKEN_NAME, USER_DATA } from '@/utils/auth.js'
|
|||
|
|
import { getCurrentMember } from './api.js'
|
||
|
|
import { KefuSocket } from './kefu-socket.js'
|
||
|
|
|
||
|
|
export const KEFU_REALTIME_EVENT = 'kefu-realtime-event'
|
||
|
|
export const KEFU_REALTIME_STATUS = 'kefu-realtime-status'
|
||
|
|
|
||
|
|
let socket = null
|
||
|
|
let connectionParams = null
|
||
|
|
let startingPromise = null
|
||
|
|
|
||
|
|
function storedMember() {
|
||
|
|
const value = getStorageFun(USER_DATA)
|
||
|
|
if (!value) return null
|
||
|
|
if (typeof value === 'object') return value
|
||
|
|
try {
|
||
|
|
return JSON.parse(value)
|
||
|
|
} catch (error) {
|
||
|
|
return null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function resolveMemberId(explicitUserId) {
|
||
|
|
if (explicitUserId) return explicitUserId
|
||
|
|
const cached = storedMember()
|
||
|
|
if (cached && (cached.id || cached.userId)) return cached.id || cached.userId
|
||
|
|
const member = await getCurrentMember()
|
||
|
|
return member && (member.id || member.userId)
|
||
|
|
}
|
||
|
|
|
||
|
|
function createSocket() {
|
||
|
|
const instance = new KefuSocket({
|
||
|
|
onStatus(status) {
|
||
|
|
uni.$emit(KEFU_REALTIME_STATUS, status)
|
||
|
|
},
|
||
|
|
onEvent(event) {
|
||
|
|
uni.$emit(KEFU_REALTIME_EVENT, event)
|
||
|
|
},
|
||
|
|
})
|
||
|
|
socket = instance
|
||
|
|
instance.connect(connectionParams)
|
||
|
|
return instance
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Start the foreground customer-service connection. Calls are idempotent so
|
||
|
|
* several pages can consume the same stream without opening duplicate sockets.
|
||
|
|
*/
|
||
|
|
export function startKefuRealtime(options = {}) {
|
||
|
|
if (!getStorageFun(TOKEN_NAME)) {
|
||
|
|
resetKefuRealtime()
|
||
|
|
return Promise.resolve(null)
|
||
|
|
}
|
||
|
|
if (startingPromise) return startingPromise
|
||
|
|
|
||
|
|
startingPromise = resolveMemberId(options.userId)
|
||
|
|
.then((userId) => {
|
||
|
|
if (!userId) return null
|
||
|
|
const nextParams = {
|
||
|
|
userId,
|
||
|
|
mchId: options.mchId || (connectionParams && connectionParams.mchId) || 1002,
|
||
|
|
}
|
||
|
|
const sameMember = connectionParams && String(connectionParams.userId) === String(userId)
|
||
|
|
connectionParams = nextParams
|
||
|
|
if (socket && sameMember) {
|
||
|
|
socket.reconnectNow()
|
||
|
|
return socket
|
||
|
|
}
|
||
|
|
if (socket) socket.close()
|
||
|
|
socket = null
|
||
|
|
return createSocket()
|
||
|
|
})
|
||
|
|
.catch(() => null)
|
||
|
|
.finally(() => {
|
||
|
|
startingPromise = null
|
||
|
|
})
|
||
|
|
return startingPromise
|
||
|
|
}
|
||
|
|
|
||
|
|
export function suspendKefuRealtime() {
|
||
|
|
if (socket) socket.close()
|
||
|
|
socket = null
|
||
|
|
uni.$emit(KEFU_REALTIME_STATUS, 'closed')
|
||
|
|
}
|
||
|
|
|
||
|
|
export function resumeKefuRealtime() {
|
||
|
|
if (!getStorageFun(TOKEN_NAME)) {
|
||
|
|
resetKefuRealtime()
|
||
|
|
return Promise.resolve(null)
|
||
|
|
}
|
||
|
|
return startKefuRealtime(connectionParams || {})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function resetKefuRealtime() {
|
||
|
|
suspendKefuRealtime()
|
||
|
|
connectionParams = null
|
||
|
|
}
|