| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- import { type H5BridgeMessage, type H5ExperienceRequest } from '../../game/experience/h5Experience'
- type ExperienceWebViewPageData = {
- pageTitle: string
- pageSubtitle: string
- presentation: 'sheet' | 'dialog' | 'fullscreen'
- webViewSrc: string
- webViewReady: boolean
- loadErrorText: string
- panelBodyHeightPx: number
- }
- 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: {
- pageTitle: '内容体验',
- pageSubtitle: '',
- presentation: 'sheet',
- webViewSrc: '',
- webViewReady: false,
- loadErrorText: '',
- panelBodyHeightPx: 420,
- },
- onLoad() {
- const systemInfo = wx.getSystemInfoSync()
- const windowHeight = typeof systemInfo.windowHeight === 'number' ? systemInfo.windowHeight : 700
- pageResolved = false
- currentRequest = null
- currentEventChannel = null
- this.setData({
- pageTitle: '内容体验',
- pageSubtitle: '',
- presentation: 'sheet',
- webViewSrc: '',
- webViewReady: false,
- loadErrorText: '',
- panelBodyHeightPx: Math.max(420, Math.floor(windowHeight * 0.62)),
- })
- try {
- currentEventChannel = this.getOpenerEventChannel()
- } catch {
- currentEventChannel = null
- }
- if (!currentEventChannel) {
- return
- }
- currentEventChannel.on('init', (request: H5ExperienceRequest) => {
- currentRequest = request
- const presentation = request.presentation || 'sheet'
- const panelHeightPx = presentation === 'dialog'
- ? Math.max(420, Math.floor(windowHeight * 0.7))
- : presentation === 'fullscreen'
- ? Math.max(520, windowHeight - 24)
- : Math.max(420, Math.floor(windowHeight * 0.72))
- const headerHeightPx = presentation === 'fullscreen' ? 84 : 76
- this.setData({
- pageTitle: request.title || '内容体验',
- pageSubtitle: request.subtitle || '',
- presentation,
- webViewSrc: buildWebViewSrc(request),
- webViewReady: true,
- loadErrorText: '',
- panelBodyHeightPx: Math.max(240, panelHeightPx - headerHeightPx),
- })
- })
- },
- 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()
- },
- handleCloseTap() {
- emitCloseAndBack({})
- },
- })
|