Skip to content

Commit bd99047

Browse files
Merge pull request #3 from Crowdhandler/feature/match-on-url
Allow WR matches on URL
2 parents 091667d + e40e8c4 commit bd99047

2 files changed

Lines changed: 110 additions & 49 deletions

File tree

CHReactNativeGatekeeper.tsx

Lines changed: 91 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type CHEvents = {
1111
onRequestEnd: any,
1212
navigation: any,
1313
}
14-
const API_REDIRECT_ENDPOINT = "http://api.crowdhandler.com/v1/redirect/requests/";
14+
const API_REDIRECT_ENDPOINT = "https://api.crowdhandler.com/v1/redirect/requests/";
1515

1616
export default class CHReactNativeGatekeeper {
1717

@@ -27,6 +27,7 @@ export default class CHReactNativeGatekeeper {
2727
};
2828
screen_config: any;
2929
timeout: number;
30+
requestType: string;
3031

3132
constructor(config: { CH_KEY: string }, events: CHEvents, timeout: number, debug: boolean) {
3233
this.CH_KEY = config.CH_KEY;
@@ -45,8 +46,8 @@ export default class CHReactNativeGatekeeper {
4546
* @param config
4647
* @returns Promise
4748
*/
48-
redirectOrWait(config: { slug: string }) {
49-
if (!config.slug) {
49+
redirectOrWait(config: { slug: string, url: string }) {
50+
if (!config.slug && !config.url) {
5051

5152
this.on({
5253
type: 'onRedirect',
@@ -60,6 +61,11 @@ export default class CHReactNativeGatekeeper {
6061

6162
} else {
6263

64+
this.requestType = 'slug';
65+
if (config.url) {
66+
this.requestType = 'url';
67+
}
68+
6369
this.screen_config = config;
6470
this.makeCrowdHandlerRequest();
6571

@@ -77,26 +83,23 @@ export default class CHReactNativeGatekeeper {
7783
this.events.navigation = navigation;
7884
}
7985

80-
async fetchWithTimeout (resource: string, options: RequestInit) {
81-
86+
async fetchWithTimeout(resource: string, options: RequestInit) {
87+
8288
try {
8389
const controller = new AbortController();
8490
const id = setTimeout(() => controller.abort(), this.timeout);
85-
8691
const response = await fetch(resource, {
8792
...options,
88-
signal: controller.signal
89-
});
90-
91-
93+
signal: controller.signal
94+
});
9295
clearTimeout(id);
93-
96+
9497
return response;
9598
} catch (error) {
9699
return error;
97100
}
98101

99-
}
102+
}
100103

101104
/**
102105
*
@@ -116,9 +119,8 @@ export default class CHReactNativeGatekeeper {
116119
// a URL and config given:
117120

118121
return this.fetchWithTimeout(url, config)
119-
.then(async (response) => {
120-
121-
if(response.headers) {
122+
.then(async (response) => {
123+
if (response.headers) {
122124
return {
123125
headers: response.headers,
124126
status: response.status,
@@ -135,31 +137,57 @@ export default class CHReactNativeGatekeeper {
135137
})
136138
}
137139

140+
buildRequestURL() : string {
141+
let URL: string;
142+
let saved_token :undefined;
143+
144+
let params: any = [ { name: 'ch-public-key', value: this.CH_KEY } ];
145+
146+
if (this.requestType === 'slug') {
147+
params.push({ name: 'slug', value: this.screen_config.slug });
148+
if (this.tokens[this.screen_config.slug]) {
149+
saved_token = this.tokens[this.screen_config.slug];
150+
}
151+
} else {
152+
params.push({ name: 'url', value: encodeURI(this.screen_config.url) });
153+
if (this.tokens[encodeURI(this.screen_config.url)]) {
154+
saved_token = this.tokens[encodeURI(this.screen_config.url)]
155+
}
156+
}
157+
158+
if (!saved_token){
159+
URL = API_REDIRECT_ENDPOINT;
160+
} else {
161+
URL = `${API_REDIRECT_ENDPOINT}${saved_token}`;
162+
}
163+
164+
URL = `${URL}?${params.map((param) => {
165+
return `${param.name}=${param.value}`
166+
}).join('&')}`
167+
168+
return URL;
169+
}
170+
138171
/**
139172
*
140173
*/
141174
async makeCrowdHandlerRequest() {
142175
this.on({ type: 'onRequestStart' })
143-
let URL = `${API_REDIRECT_ENDPOINT}?ch-public-key=${this.CH_KEY}&slug=${this.screen_config.slug}`;
144-
if (this.tokens[this.screen_config.slug]) {
145-
URL = `${API_REDIRECT_ENDPOINT}${this.tokens[this.screen_config.slug]}?ch-public-key=${this.CH_KEY}&slug=${this.screen_config.slug}`;
146-
}
147-
176+
const URL : string = this.buildRequestURL();
177+
148178
try {
149179
const response = await this.request<CHResponse>(URL, {
150180
method: 'GET'
151-
});
181+
});
152182

153-
let token: string;
154-
if(response && response.url) {
183+
let token: any;
184+
if (response && response.url) {
155185
token = this.getToken(response.url);
156-
157-
if (token) {
158-
this.saveToken(this.screen_config.slug, token);
159-
}
160-
161186
}
162187

188+
if (token) {
189+
this.saveToken((this.requestType === 'slug') ? this.screen_config.slug : encodeURI(this.screen_config.url), token);
190+
}
163191

164192
if (response && response.status === 200) {
165193

@@ -191,7 +219,7 @@ export default class CHReactNativeGatekeeper {
191219

192220
this.on({ type: 'onRequestEnd' })
193221

194-
} catch (error) {
222+
} catch (error) {
195223

196224
this.on({
197225
type: 'onRedirect',
@@ -245,7 +273,7 @@ export default class CHReactNativeGatekeeper {
245273

246274
} catch (error) {
247275
console.log(error);
248-
276+
249277
}
250278

251279
return token;
@@ -257,28 +285,43 @@ export default class CHReactNativeGatekeeper {
257285

258286
}
259287

260-
handlePostMessage(message: string) {
288+
handlePostMessage(message: string) {
261289
let parts = message.split('=');
262-
let payload = JSON.parse(parts[1]);
263290

264-
switch (parts[0]) {
265-
case 'saveToken':
266-
this.saveToken(payload.slug, payload.token)
267-
break;
268-
case 'promoted':
269-
this.on({
270-
type: 'onRedirect',
271-
payload: {
272-
screen_config: this.screen_config,
273-
navigation: this.events.navigation,
274-
referer: 'waiting_room',
275-
status: 200
291+
try {
292+
let payload = JSON.parse(parts[1]);
293+
294+
switch (parts[0]) {
295+
case 'saveToken':
296+
297+
if (this.requestType === 'slug') {
298+
this.saveToken(payload.slug, payload.token)
276299
}
277-
});
278-
break;
279300

280-
default:
281-
break;
301+
if (this.requestType === 'url') {
302+
this.saveToken(encodeURI(payload.requestURL), payload.token)
303+
}
304+
305+
break;
306+
case 'promoted':
307+
this.on({
308+
type: 'onRedirect',
309+
payload: {
310+
screen_config: this.screen_config,
311+
navigation: this.events.navigation,
312+
referer: 'waiting_room',
313+
status: 200
314+
}
315+
});
316+
break;
317+
318+
default:
319+
break;
320+
}
321+
322+
} catch (error) {
323+
console.log(error);
324+
282325
}
283326
}
284327
}

CHWebView.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,25 @@ export const CHWebView = ({ navigation, route }) => {
1111

1212
const appState = useRef(AppState.currentState);
1313
const [appStateVisible, setAppStateVisible] = useState(appState.current);
14+
const isMounted = useRef(true);
1415
const uri = route.params.uri;
1516
const crowdhandler_gatekeeper = useCrowdHandler();
17+
const ref = useRef();
18+
/**
19+
* Only load the webview when this screen is mounted
20+
*/
21+
useEffect(() => {
22+
const webViewMounted = () => {
23+
isMounted.current = true;
24+
};
25+
webViewMounted();
26+
27+
return () => {
28+
isMounted.current = false;
29+
};
30+
31+
}, []);
32+
1633

1734
useEffect(() => {
1835
const subscription = AppState.addEventListener('change', nextAppState => {
@@ -25,8 +42,9 @@ export const CHWebView = ({ navigation, route }) => {
2542
}, []);
2643

2744
return (
28-
(appStateVisible == 'active') ?
45+
(appStateVisible == 'active' && isMounted.current) ?
2946
<WebView style={styles.container}
47+
ref={(instance) => (ref.current = instance)}
3048
onMessage={(event) => {
3149
crowdhandler_gatekeeper.handlePostMessage(event.nativeEvent.data);
3250
}}

0 commit comments

Comments
 (0)