native-message.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { browser, getRandomKey } from '/src/helpers/utils'
  2. export type EnumApiType =
  3. | 'cloudDetail'
  4. | 'cloudDestroy'
  5. | 'cloudVolume'
  6. | 'cloudMetronome'
  7. | 'cloudGetMediaStatus'
  8. | 'cloudPlay'
  9. | 'cloudSuspend'
  10. | 'cloudTimeUpdae'
  11. | 'cloudplayed'
  12. | 'cloudSetCurrentTime'
  13. | 'cloudChangeSpeed'
  14. | 'savePicture'
  15. | 'openWebView'
  16. | 'openCamera'
  17. | 'closeCamera'
  18. | 'back'
  19. | 'openAccompanyWebView'
  20. | 'startCapture'
  21. | 'endCapture'
  22. | 'setCaptureMode'
  23. | 'proxyServiceMessage'
  24. | 'startEvaluating'
  25. | 'endEvaluating'
  26. | 'videoUpdate'
  27. | 'shareAchievements'
  28. | 'resumeRecording'
  29. | 'startRecording'
  30. | 'stopRecording'
  31. export interface IPostMessage {
  32. api: string | EnumApiType
  33. content?: any
  34. }
  35. /**
  36. * 劫持postMessage
  37. */
  38. // const originalPostMessage = window.postMessage
  39. // window.postMessage = (message: IPostMessage) => {
  40. // // console.log('通过劫持', message)
  41. // originalPostMessage(message, '*')
  42. // }
  43. /**
  44. *
  45. * 目前已支持API
  46. *
  47. * openWebView
  48. *
  49. */
  50. export type CallBack = (evt?: IPostMessage) => void
  51. // eslint-disable-next-line @typescript-eslint/no-empty-function
  52. const loop = () => {}
  53. const calls: { [key: string]: CallBack | CallBack[] } = {}
  54. const browserInfo = browser()
  55. if (browserInfo.isApp) {
  56. window.addEventListener('message', (evt) => {
  57. console.log('app回调', evt?.data)
  58. try {
  59. const data = evt.data ? (typeof evt.data === 'object' ? evt.data : JSON.parse(evt.data)) : {}
  60. const uuid = data.content?.uuid || data.uuid
  61. try {
  62. if (data.content) {
  63. data.content = typeof data.content === 'object' ? data.content : JSON.parse(data.content)
  64. }
  65. } catch (error) {}
  66. if (!uuid) {
  67. const keys = Object.keys(calls).filter((key) => key.indexOf(data.api) === 0)
  68. for (const key of keys) {
  69. const callback = calls[key] || loop
  70. typeof callback === 'function' && callback(data)
  71. if (Array.isArray(callback)) {
  72. callback.forEach((cb) => {
  73. typeof cb === 'function' && cb(data)
  74. })
  75. }
  76. }
  77. return
  78. }
  79. const callid = data.content?.uuid || data.uuid || data.api + data.uuid
  80. const callback = calls[callid] || loop
  81. typeof callback === 'function' && callback(data)
  82. } catch (error) {
  83. console.error('通信消息解析错误', error)
  84. }
  85. })
  86. }
  87. const instance: any = (window as any).ORCHESTRA || (window as any).webkit?.messageHandlers?.ORCHESTRA
  88. export const postMessage = (data: IPostMessage, callback?: CallBack) => {
  89. if (browserInfo.isApp) {
  90. const uuid = getRandomKey()
  91. calls[uuid] = callback || loop
  92. data.content = data.content ? { ...data.content, uuid } : { uuid }
  93. console.log('h5发送:', JSON.stringify(data))
  94. instance.postMessage(JSON.stringify(data))
  95. }
  96. }
  97. export const listenerMessage = (api: string, callback: CallBack) => {
  98. if (browserInfo.isApp) {
  99. const uuid = api
  100. if (!calls[uuid]) {
  101. calls[uuid] = []
  102. }
  103. ;(calls[uuid] as CallBack[]).push(callback || loop)
  104. }
  105. }
  106. export const removeListenerMessage = (api: string, callback: CallBack) => {
  107. if (browserInfo.isApp) {
  108. const uuid = api
  109. if (Array.isArray(calls[uuid])) {
  110. const indexOf = (calls[uuid] as CallBack[]).indexOf(callback)
  111. ;(calls[uuid] as CallBack[]).splice(indexOf, 1)
  112. }
  113. }
  114. }
  115. export const promisefiyPostMessage = (data: IPostMessage): Promise<IPostMessage | undefined> => {
  116. return new Promise((resolve) => {
  117. postMessage(data, (res) => resolve(res))
  118. })
  119. }