Skip to content

Commit

Permalink
Merge pull request #1716 from didi/feat-rn-button-share
Browse files Browse the repository at this point in the history
Feat rn button share
  • Loading branch information
hiyuki authored Nov 26, 2024
2 parents 6fa9bc7 + 7cbf46e commit 1b9a008
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/convertor/wxToReact.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
import { implemented } from '../core/implement'

// 暂不支持的wx选项,后期需要各种花式支持
const unsupported = ['relations', 'moved', 'definitionFilter', 'onShareAppMessage']
const unsupported = ['relations', 'moved', 'definitionFilter']

function convertErrorDesc (key) {
error(`Options.${key} is not supported in runtime conversion from wx to react native.`, global.currentResource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ import {
NativeSyntheticEvent
} from 'react-native'
import { warn } from '@mpxjs/utils'
import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren } from './utils'
import { getCurrentPage, splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren } from './utils'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef'
import { FormContext } from './context'
import { RouteContext, FormContext } from './context'

export type Type = 'default' | 'primary' | 'warn'

Expand Down Expand Up @@ -128,7 +128,8 @@ const styles = StyleSheet.create({
}
})

const getOpenTypeEvent = (openType: OpenType) => {
const getOpenTypeEvent = (openType?: OpenType) => {
if (!openType) return
if (!global.__mpx?.config?.rnConfig) {
warn('Environment not supported')
return
Expand All @@ -148,6 +149,12 @@ const getOpenTypeEvent = (openType: OpenType) => {
return event
}

const timer = (data: any, time = 3000) => new Promise((resolve) => {
setTimeout(() => {
resolve(data)
}, time)
})

const Loading = ({ alone = false }: { alone: boolean }): JSX.Element => {
const image = useRef(new Animated.Value(0)).current

Expand Down Expand Up @@ -211,6 +218,8 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
bindtouchend
} = props

const pageId = useContext(RouteContext)

const formContext = useContext(FormContext)

let submitFn: () => void | undefined
Expand Down Expand Up @@ -310,17 +319,41 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonPro
}

const handleOpenTypeEvent = (evt: NativeSyntheticEvent<TouchEvent>) => {
if (!openType) return
const handleEvent = getOpenTypeEvent(openType)
if (!handleEvent) return

if (openType === 'share') {
handleEvent && handleEvent({
const currentPage = getCurrentPage(pageId)
const event = {
from: 'button',
target: getCustomEvent('tap', evt, { layoutRef }, props).target
})
target: getCustomEvent('tap', evt, { layoutRef }, props).target,
webViewUrl: currentPage?.__webViewUrl
}
if (currentPage) {
const defaultMessage = {
title: global.__mpx.config.rnConfig.projectName || 'AwesomeProject',
path: currentPage.route || ''
}
if (currentPage.onShareAppMessage) {
const { promise, ...message } = currentPage.onShareAppMessage(event) || {}
if (promise) {
Promise.race([Promise.resolve(promise), timer(message)])
.then((msg) => {
handleEvent(Object.assign({}, defaultMessage, msg))
})
} else {
handleEvent(Object.assign({}, defaultMessage, message))
}
} else {
handleEvent(defaultMessage)
}
} else {
warn('Current page not found')
// Todo handleEvent(event)
}
}

if (openType === 'getUserInfo' && handleEvent && bindgetuserinfo) {
if (openType === 'getUserInfo' && bindgetuserinfo) {
Promise.resolve(handleEvent)
.then((userInfo) => {
if (typeof userInfo === 'object') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { forwardRef, JSX, useEffect, useRef } from 'react'
import { forwardRef, JSX, useEffect, useRef, useContext, useMemo } from 'react'
import { noop, warn } from '@mpxjs/utils'
import { Portal } from '@ant-design/react-native'
import { getCustomEvent } from './getInnerListeners'
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
import { WebView } from 'react-native-webview'
import useNodesRef, { HandlerRef } from './useNodesRef'
import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent } from 'react-native-webview/lib/WebViewTypes'
import { getCurrentPage } from './utils'
import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent, WebViewNavigation } from 'react-native-webview/lib/WebViewTypes'
import { RouteContext } from './context'

type OnMessageCallbackEvent = {
detail: {
Expand Down Expand Up @@ -51,6 +53,9 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
if (props.style) {
warn('The web-view component does not support the style prop.')
}
const pageId = useContext(RouteContext)
const currentPage = useMemo(() => getCurrentPage(pageId), [pageId])

const defaultWebViewStyle = {
position: 'absolute' as 'absolute' | 'relative' | 'static',
left: 0 as number,
Expand All @@ -64,17 +69,23 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
defaultStyle: defaultWebViewStyle
})

const _messageList: any[] = []
const _messageList = useRef<any[]>([])
const handleUnload = () => {
// 这里是 WebView 销毁前执行的逻辑
bindmessage(getCustomEvent('messsage', {}, {
detail: {
data: _messageList
data: _messageList.current
},
layoutRef: webViewRef
}))
}

useEffect(() => {
if (currentPage) {
currentPage.__webViewUrl = src
}
}, [src, currentPage])

useEffect(() => {
// 组件卸载时执行
return () => {
Expand All @@ -101,6 +112,11 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
}
binderror(result)
}
const _changeUrl = function (navState: WebViewNavigation) {
if (currentPage) {
currentPage.__webViewUrl = navState.url
}
}
const _message = function (res: WebViewMessageEvent) {
let data: MessageData = {}
let asyncCallback
Expand All @@ -116,7 +132,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
const postData: PayloadData = data.payload || {}
switch (data.type) {
case 'postMessage':
_messageList.push(postData.data)
_messageList.current.push(postData.data)
asyncCallback = Promise.resolve({
errMsg: 'invokeWebappApi:ok'
})
Expand Down Expand Up @@ -157,6 +173,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
onLoad={_load}
onError={_error}
onMessage={_message}
onNavigationStateChange={_changeUrl}
javaScriptEnabled={true}
></WebView>
</Portal>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ declare module 'react-native-svg/css' {

declare module '@mpxjs/utils' {
export function isEmptyObject (obj: Object): boolean
export function isFunction (fn: unknown): boolean
export function hasOwn (obj: Object, key: string): boolean
export function noop (...arg: any): void
export function diffAndCloneA<A, B> (a: A, b?: B): {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
import { isObject, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
import { isObject, isFunction, hasOwn, diffAndCloneA, error, warn, getFocusedNavigation } from '@mpxjs/utils'
import { VarContext } from './context'
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
import { initialWindowMetrics } from 'react-native-safe-area-context'
Expand Down Expand Up @@ -588,6 +588,12 @@ export function extendObject (...args: Record<string, any>[]) {
return Object.assign({}, ...args)
}

export function getCurrentPage (pageId: number | null) {
if (!global.getCurrentPages) return
const pages = global.getCurrentPages()
return pages.find((page: any) => isFunction(page.getPageId) && page.getPageId() === pageId)
}

export function renderImage (
imageProps: ImageProps | FastImageProps,
enableFastImage = false
Expand Down

0 comments on commit 1b9a008

Please sign in to comment.