100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
import { router } from 'expo-router'
|
||
import * as WebBrowser from 'expo-web-browser'
|
||
import { Alert, Platform } from 'react-native'
|
||
|
||
interface WebViewOptions {
|
||
url: string
|
||
title?: string
|
||
embedded?: boolean // 是否使用内嵌WebView
|
||
}
|
||
|
||
export const openWebView = async ({ url, title, embedded = false }: WebViewOptions) => {
|
||
if (!url) {
|
||
console.warn('WebView: URL is required')
|
||
return
|
||
}
|
||
|
||
// 确保 URL 格式正确
|
||
const validUrl = url.startsWith('http') ? url : `https://${url}`
|
||
|
||
// 如果需要内嵌 WebView,跳转到 WebView 页面
|
||
if (embedded) {
|
||
router.push({
|
||
pathname: '/webview',
|
||
params: {
|
||
url: validUrl,
|
||
title: title || '网页',
|
||
},
|
||
})
|
||
return { type: 'embedded' }
|
||
}
|
||
|
||
try {
|
||
console.log(`Opening web browser: ${title || 'Web Page'} - ${validUrl}`)
|
||
console.log(`Platform: ${Platform.OS} - ${Platform.OS === 'ios' ? 'Safari View Controller' : 'Chrome Custom Tabs'}`)
|
||
|
||
const result = await WebBrowser.openBrowserAsync(validUrl, {
|
||
// iOS: Safari View Controller 配置
|
||
// Android: Chrome Custom Tabs 配置
|
||
presentationStyle:
|
||
Platform.OS === 'ios'
|
||
? WebBrowser.WebBrowserPresentationStyle.FORM_SHEET // iOS: 表单样式弹出
|
||
: WebBrowser.WebBrowserPresentationStyle.FULL_SCREEN, // Android: 全屏
|
||
|
||
controlsColor: '#FFE500', // 使用应用主题色 (iOS/Android都支持)
|
||
toolbarColor: '#1C1E22', // 深色工具栏 (iOS/Android都支持)
|
||
secondaryToolbarColor: '#2A2D35', // Android特有
|
||
|
||
// iOS特有配置
|
||
...(Platform.OS === 'ios' && {
|
||
modalEnabled: true,
|
||
modalPresentationStyle: 'pageSheet',
|
||
}),
|
||
|
||
// Android特有配置
|
||
...(Platform.OS === 'android' && {
|
||
showTitle: true,
|
||
enableBarCollapsing: true,
|
||
}),
|
||
|
||
browserPackage: undefined, // 使用默认浏览器
|
||
})
|
||
|
||
console.log('Web browser result:', result)
|
||
return result
|
||
} catch (error) {
|
||
console.error('Failed to open web browser:', error)
|
||
Alert.alert('打开失败', '无法打开网页,请检查网络连接')
|
||
}
|
||
}
|
||
|
||
// 简化的打开方式
|
||
export const openUrl = (url: string, title?: string, embedded?: boolean) => {
|
||
return openWebView({ url, title, embedded })
|
||
}
|
||
|
||
// 专门打开内嵌 WebView
|
||
export const openEmbeddedWebView = (url: string, title?: string) => {
|
||
return openWebView({ url, title, embedded: true })
|
||
}
|
||
|
||
// 配置WebBrowser的全局设置
|
||
export const configureWebBrowser = async () => {
|
||
try {
|
||
// 预热浏览器以提升性能 (仅在支持的平台和环境下执行)
|
||
if (Platform.OS !== 'web') {
|
||
await WebBrowser.warmUpAsync()
|
||
}
|
||
} catch (error) {
|
||
console.warn('WebBrowser warmUp failed (this is often normal in development):', error)
|
||
// 这个错误在开发环境中很常见,不影响实际功能
|
||
}
|
||
|
||
try {
|
||
// 设置默认配置
|
||
WebBrowser.maybeCompleteAuthSession()
|
||
} catch (error) {
|
||
console.warn('WebBrowser maybeCompleteAuthSession failed:', error)
|
||
}
|
||
}
|