| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- import { type H5BridgeMessage, type H5ExperienceRequest } from '../../game/experience/h5Experience'
- type ExperienceWebViewPageData = {
- webViewSrc: string
- webViewReady: boolean
- loadErrorText: string
- }
- let currentRequest: H5ExperienceRequest | null = null
- let currentEventChannel: WechatMiniprogram.EventChannel | null = null
- let pageResolved = false
- function appendQueryParam(url: string, key: string, value: string): string {
- const separator = url.indexOf('?') >= 0 ? '&' : '?'
- return `${url}${separator}${key}=${encodeURIComponent(value)}`
- }
- function buildWebViewSrc(request: H5ExperienceRequest): string {
- let nextUrl = request.url
- nextUrl = appendQueryParam(nextUrl, 'cmrBridge', request.bridgeVersion)
- nextUrl = appendQueryParam(nextUrl, 'cmrKind', request.kind)
- return nextUrl
- }
- function emitFallbackAndClose() {
- if (!currentRequest || !currentEventChannel) {
- return
- }
- if (!pageResolved) {
- pageResolved = true
- currentEventChannel.emit('fallback', currentRequest.fallback)
- }
- wx.navigateBack({
- fail: () => {},
- })
- }
- function emitCloseAndBack(payload?: Record<string, unknown>) {
- if (currentEventChannel && !pageResolved) {
- pageResolved = true
- currentEventChannel.emit('close', payload || {})
- }
- wx.navigateBack({
- fail: () => {},
- })
- }
- Page<ExperienceWebViewPageData, WechatMiniprogram.IAnyObject>({
- data: {
- webViewSrc: '',
- webViewReady: false,
- loadErrorText: '',
- },
- onLoad() {
- pageResolved = false
- currentRequest = null
- currentEventChannel = null
- this.setData({
- webViewSrc: '',
- webViewReady: false,
- loadErrorText: '',
- })
- try {
- currentEventChannel = this.getOpenerEventChannel()
- } catch {
- currentEventChannel = null
- }
- if (!currentEventChannel) {
- return
- }
- currentEventChannel.on('init', (request: H5ExperienceRequest) => {
- currentRequest = request
- wx.setNavigationBarTitle({
- title: request.title || '内容体验',
- fail: () => {},
- })
- this.setData({
- webViewSrc: buildWebViewSrc(request),
- webViewReady: true,
- loadErrorText: '',
- })
- })
- },
- onUnload() {
- if (currentEventChannel && !pageResolved) {
- currentEventChannel.emit('close', {})
- }
- pageResolved = false
- currentRequest = null
- currentEventChannel = null
- },
- handleWebViewMessage(event: WechatMiniprogram.CustomEvent) {
- const dataList = event.detail && Array.isArray(event.detail.data)
- ? event.detail.data
- : []
- const rawMessage = dataList.length ? dataList[dataList.length - 1] : null
- if (!rawMessage || typeof rawMessage !== 'object') {
- return
- }
- const message = rawMessage as H5BridgeMessage
- const action = message.action || message.type || ''
- if (!action) {
- return
- }
- if (action === 'close') {
- emitCloseAndBack(message.payload)
- return
- }
- if (action === 'submitResult') {
- if (currentEventChannel) {
- currentEventChannel.emit('submitResult', message.payload || {})
- }
- return
- }
- if (action === 'fallback') {
- emitFallbackAndClose()
- }
- },
- handleWebViewError() {
- this.setData({
- loadErrorText: '页面打开失败,已回退原生内容',
- })
- emitFallbackAndClose()
- },
- })
|