import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
AdropBodyView,
AdropHeadLineView,
AdropMediaView,
AdropNativeAd,
AdropNativeAdView,
AdropProfileLogoView,
AdropProfileNameView,
} from 'adrop-ads-react-native'
import type { AdropNativeAdListener } from 'adrop-ads-react-native'
import { WebView } from 'react-native-webview'
import {
Button,
Dimensions,
ScrollView,
StyleSheet,
Text,
View,
Linking,
Platform,
} from 'react-native'
const NativeAdExample: React.FC = () => {
const [nativeAd, setNativeAd] = useState<AdropNativeAd>()
const [isLoaded, setIsLoaded] = useState(false)
const [errorCode, setErrorCode] = useState('')
// URL opening handler
const openUrl = useCallback((url: string) => {
Linking.openURL(url).catch((err) =>
console.error('Failed to open URL:', err)
)
}, [])
// Ad event listener
const listener = useMemo(
(): AdropNativeAdListener => ({
onAdReceived: (ad) => {
console.log('Ad received:', ad.unitId, ad.properties)
setIsLoaded(true)
setErrorCode('')
},
onAdFailedToReceive: (_, error) => {
console.log('Ad reception failed:', error)
setErrorCode(error)
},
onAdClicked: (ad) => {
console.log('Ad clicked:', ad.unitId)
},
onAdImpression: (ad) => {
console.log('Ad impression:', ad.unitId)
},
}),
[]
)
// Initialize ad
const initialize = useCallback(
(unitId: string) => {
const adropNativeAd = new AdropNativeAd(unitId)
adropNativeAd.listener = listener
setNativeAd((prev) => {
prev?.destroy()
return adropNativeAd
})
setIsLoaded(false)
setErrorCode('')
},
[listener]
)
// Initialize ad on component mount
useEffect(() => {
initialize('YOUR_UNIT_ID')
// Release ad on component unmount
return () => {
nativeAd?.destroy()
}
}, [])
// Load ad
const load = () => nativeAd?.load()
// Render ad view
const adView = useMemo(() => {
if (!isLoaded) return null
return (
<AdropNativeAdView
nativeAd={nativeAd}
style={{
...styles.adContainer,
width: Dimensions.get('window').width,
}}
>
{/* Profile area */}
<View style={styles.rowContainer}>
<AdropProfileLogoView style={styles.profileLogo} />
<AdropProfileNameView style={styles.profileName} />
</View>
{/* Ad title */}
<AdropHeadLineView style={styles.headline} />
{/* Ad body */}
<AdropBodyView style={styles.body} />
{/* Media area */}
{nativeAd?.isBackfilled ? (
// Backfill ad: Use AdropMediaView
<AdropMediaView style={styles.media} />
) : (
// Regular ad: Render with WebView
<WebView
source={{
html: nativeAd?.properties?.creative ?? '',
}}
style={styles.media}
javaScriptEnabled={true}
mediaPlaybackRequiresUserAction={false}
allowsInlineMediaPlayback={true}
scrollEnabled={false}
onNavigationStateChange={(event) => {
// Android WebView event
if (
event.url &&
event.url !== 'about:blank' &&
!event.url.startsWith('data:')
) {
openUrl(event.url)
}
}}
onOpenWindow={(event) => {
// iOS WebView event (window.open)
if (event.nativeEvent?.targetUrl) {
openUrl(event.nativeEvent.targetUrl)
}
}}
/>
)}
</AdropNativeAdView>
)
}, [isLoaded, nativeAd, openUrl])
return (
<ScrollView>
<View style={styles.container}>
{/* Ad load button */}
<View style={styles.button}>
<Button title="Load Ad" onPress={load} />
</View>
{/* Ad view */}
{adView}
{/* Error display */}
{errorCode && (
<Text style={styles.error}>
Error: {errorCode}
</Text>
)}
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
paddingVertical: 5,
paddingHorizontal: 16,
},
button: {
marginVertical: 8,
},
adContainer: {
paddingHorizontal: 16,
},
rowContainer: {
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
marginBottom: 8,
},
profileLogo: {
width: 32,
height: 32,
marginRight: 8,
borderRadius: 16,
},
profileName: {
fontSize: 14,
fontWeight: 'bold',
color: 'black',
},
headline: {
fontSize: 16,
fontWeight: 'bold',
color: 'black',
marginTop: 8,
},
body: {
fontSize: 14,
color: 'black',
marginVertical: 8,
},
media: {
width: '100%',
height: 360,
marginTop: 8,
},
error: {
color: 'red',
marginVertical: 8,
},
})
export default NativeAdExample