Skip to content

Commit fdb2b1f

Browse files
committed
Handle first layer footer links
This commit introduces handling of footer links clicked in the first layer. They will be opened in a separate webview in a popup.
1 parent 5699995 commit fdb2b1f

3 files changed

Lines changed: 87 additions & 7 deletions

File tree

packages/react-native-contentpass-ui/src/components/ContentpassConsentGate.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export default function ContentpassConsentGate({
165165
<ContentpassLayer
166166
eventHandler={layerEvents}
167167
baseUrl={contentpassConfig.apiUrl}
168+
instanceId={sdk.instanceId}
168169
planId={contentpassConfig.planId}
169170
propertyId={contentpassConfig.propertyId}
170171
purposesList={purposesList}

packages/react-native-contentpass-ui/src/components/ContentpassLayer.tsx

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1-
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native';
1+
import {
2+
ActivityIndicator,
3+
Modal,
4+
Pressable,
5+
StyleSheet,
6+
Text,
7+
View,
8+
} from 'react-native';
29
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
310
import type { ContentpassLayerEvents } from './ContentpassLayerEvents';
411
import buildFirstLayerUrl from './buildFirstLayerUrl';
5-
import { useMemo, useState } from 'react';
12+
import { useCallback, useMemo, useState } from 'react';
613

714
const MESSAGE_PROTOCOL = 'contentpass-first-layer';
815

@@ -52,18 +59,44 @@ const styles = StyleSheet.create({
5259
alignItems: 'center',
5360
justifyContent: 'center',
5461
},
62+
popupContainer: {
63+
flex: 1,
64+
backgroundColor: '#fff',
65+
},
66+
popupHeader: {
67+
flexDirection: 'row',
68+
justifyContent: 'flex-end',
69+
paddingHorizontal: 12,
70+
paddingVertical: 8,
71+
borderBottomWidth: StyleSheet.hairlineWidth,
72+
borderBottomColor: '#ccc',
73+
},
74+
popupClose: {
75+
paddingHorizontal: 12,
76+
paddingVertical: 6,
77+
},
78+
popupCloseText: {
79+
fontSize: 16,
80+
fontWeight: '600',
81+
color: '#007AFF',
82+
},
83+
popupWebview: {
84+
flex: 1,
85+
},
5586
});
5687

5788
export default function ContentpassLayer({
5889
baseUrl,
5990
eventHandler,
91+
instanceId,
6092
planId,
6193
propertyId,
6294
purposesList,
6395
vendorCount,
6496
}: {
6597
baseUrl: string;
6698
eventHandler: ContentpassLayerEvents;
99+
instanceId: string;
67100
planId: string;
68101
propertyId: string;
69102
purposesList: string[];
@@ -80,6 +113,13 @@ export default function ContentpassLayer({
80113
}, [baseUrl, planId, propertyId, purposesList, vendorCount]);
81114

82115
const [ready, setReady] = useState(false);
116+
const [popupUrl, setPopupUrl] = useState<string | null>(null);
117+
118+
const closePopup = useCallback(() => setPopupUrl(null), []);
119+
120+
function buildFaqUrl(): string {
121+
return `${baseUrl}/auth/login?instanceId=${encodeURIComponent(instanceId)}&propertyId=${encodeURIComponent(propertyId)}&planId=${encodeURIComponent(planId)}&route=faq`;
122+
}
83123

84124
function handleMessage(event: WebViewMessageEvent) {
85125
let msg: any;
@@ -118,6 +158,19 @@ export default function ContentpassLayer({
118158
msg.payload?.options?.page as 'login' | 'signup'
119159
);
120160
break;
161+
case 'faq':
162+
setPopupUrl(buildFaqUrl());
163+
break;
164+
case 'url':
165+
if (msg.payload?.options?.url) {
166+
setPopupUrl(msg.payload?.options?.url);
167+
} else {
168+
console.warn(
169+
'WebView message with unknown URL',
170+
msg.payload?.options?.url
171+
);
172+
}
173+
break;
121174
default:
122175
console.warn(
123176
'WebView message with unknown page',
@@ -198,6 +251,28 @@ export default function ContentpassLayer({
198251
<ActivityIndicator size="large" />
199252
</View>
200253
)}
254+
<Modal
255+
visible={popupUrl !== null}
256+
animationType="slide"
257+
presentationStyle="pageSheet"
258+
onRequestClose={closePopup}
259+
>
260+
<View style={styles.popupContainer}>
261+
<View style={styles.popupHeader}>
262+
<Pressable onPress={closePopup} style={styles.popupClose}>
263+
<Text style={styles.popupCloseText}>Close</Text>
264+
</Pressable>
265+
</View>
266+
{popupUrl && (
267+
<WebView
268+
source={{ uri: popupUrl }}
269+
style={styles.popupWebview}
270+
javaScriptEnabled
271+
domStorageEnabled
272+
/>
273+
)}
274+
</View>
275+
</Modal>
201276
</View>
202277
);
203278
}

packages/react-native-contentpass/src/Contentpass.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ export default class Contentpass implements ContentpassInterface {
4444
private authStateStorage: OidcAuthStateStorage;
4545
private readonly config: ContentpassConfig;
4646
private readonly samplingRate: number;
47-
private instanceId: string;
47+
private _instanceId: string;
48+
49+
get instanceId(): string {
50+
return this._instanceId;
51+
}
4852

4953
private contentpassState: ContentpassState = {
5054
state: ContentpassStateType.INITIALISING,
@@ -59,7 +63,7 @@ export default class Contentpass implements ContentpassInterface {
5963
}
6064

6165
this.config = config;
62-
this.instanceId = uuid.v4();
66+
this._instanceId = uuid.v4();
6367
logger.debug('Contentpass initialised with config', config);
6468
if (
6569
config.samplingRate &&
@@ -130,7 +134,7 @@ export default class Contentpass implements ContentpassInterface {
130134
ea: eventAction,
131135
ec: eventCategory,
132136
el: eventLabel,
133-
cpabid: this.instanceId,
137+
cpabid: this._instanceId,
134138
cppid: publicId,
135139
cpsr: activeSamplingRate,
136140
};
@@ -180,7 +184,7 @@ export default class Contentpass implements ContentpassInterface {
180184
public countImpression = async () => {
181185
// Generate a new impression id to be used per impression
182186
// This mimics the behaviour of the web SDK when in SPA mode
183-
this.instanceId = uuid.v4();
187+
this._instanceId = uuid.v4();
184188
await Promise.all([
185189
this.countPaidImpressionWhenUserHasValidSub(),
186190
this.countSampledImpression(),
@@ -197,7 +201,7 @@ export default class Contentpass implements ContentpassInterface {
197201
try {
198202
await sendPageViewEvent(this.config.apiUrl, {
199203
propertyId: this.config.propertyId,
200-
impressionId: this.instanceId,
204+
impressionId: this._instanceId,
201205
accessToken: this.oidcAuthState!.accessToken,
202206
});
203207
} catch (err: any) {

0 commit comments

Comments
 (0)