146 lines
4.3 KiB
TypeScript
146 lines
4.3 KiB
TypeScript
import CookieManager from '@react-native-cookies/cookies';
|
|
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
|
|
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
|
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
import { ActivityIndicator, BackHandler, Linking, SafeAreaView, StyleSheet, View } from 'react-native';
|
|
import WebView from 'react-native-webview';
|
|
|
|
import { userAgent } from '../../lib/constants';
|
|
import { useAppSelector } from '../../lib/hooks';
|
|
import { isIOS } from '../../lib/methods/helpers';
|
|
import { getRoomIdFromJitsiCallUrl } from '../../lib/methods/helpers/getRoomIdFromJitsiCall';
|
|
import { events, logEvent } from '../../lib/methods/helpers/log';
|
|
import { endVideoConfTimer, initVideoConfTimer } from '../../lib/methods/videoConfTimer';
|
|
import { getUserSelector } from '../../selectors/login';
|
|
import { ChatsStackParamList } from '../../stacks/types';
|
|
import JitsiAuthModal from './JitsiAuthModal';
|
|
|
|
const JitsiMeetView = (): React.ReactElement => {
|
|
const {
|
|
params: { rid, url, videoConf }
|
|
} = useRoute<RouteProp<ChatsStackParamList, 'JitsiMeetView'>>();
|
|
const { goBack } = useNavigation();
|
|
const user = useAppSelector(state => getUserSelector(state));
|
|
const serverUrl = useAppSelector(state => state.server.server);
|
|
|
|
const [authModal, setAuthModal] = useState(false);
|
|
const [cookiesSet, setCookiesSet] = useState(false);
|
|
|
|
const setCookies = async () => {
|
|
const date = new Date();
|
|
date.setDate(date.getDate() + 1);
|
|
const expires = date.toISOString();
|
|
const domain = serverUrl.replace(/^https?:\/\//, '');
|
|
const ck = { domain, version: '1', expires };
|
|
|
|
await CookieManager.set(serverUrl, {
|
|
name: 'rc_uid',
|
|
value: user.id,
|
|
...ck
|
|
});
|
|
await CookieManager.set(serverUrl, {
|
|
name: 'rc_token',
|
|
value: user.token,
|
|
...ck
|
|
});
|
|
setCookiesSet(true);
|
|
};
|
|
|
|
const handleJitsiApp = useCallback(async () => {
|
|
const callUrl = url.replace(/^https?:\/\//, '');
|
|
try {
|
|
await Linking.openURL(`org.jitsi.meet://${callUrl}`);
|
|
goBack();
|
|
} catch (error) {
|
|
// As the jitsi app was not opened, disable the backhandler on android
|
|
BackHandler.addEventListener('hardwareBackPress', () => true);
|
|
}
|
|
}, [goBack, url]);
|
|
|
|
const onConferenceJoined = useCallback(() => {
|
|
logEvent(videoConf ? events.LIVECHAT_VIDEOCONF_JOIN : events.JM_CONFERENCE_JOIN);
|
|
if (rid && !videoConf) {
|
|
initVideoConfTimer(rid);
|
|
}
|
|
}, [rid, videoConf]);
|
|
|
|
const onNavigationStateChange = useCallback(
|
|
webViewState => {
|
|
const roomId = getRoomIdFromJitsiCallUrl(url);
|
|
if (webViewState.url.includes('auth-static')) {
|
|
setAuthModal(true);
|
|
return false;
|
|
}
|
|
if ((roomId && !webViewState.url.includes(roomId)) || webViewState.url.includes('close')) {
|
|
if (isIOS) {
|
|
if (webViewState.navigationType) {
|
|
goBack();
|
|
}
|
|
} else {
|
|
goBack();
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
[goBack, url]
|
|
);
|
|
|
|
useEffect(() => {
|
|
handleJitsiApp();
|
|
onConferenceJoined();
|
|
activateKeepAwake();
|
|
|
|
return () => {
|
|
logEvent(videoConf ? events.LIVECHAT_VIDEOCONF_TERMINATE : events.JM_CONFERENCE_TERMINATE);
|
|
if (!videoConf) endVideoConfTimer();
|
|
deactivateKeepAwake();
|
|
};
|
|
}, [handleJitsiApp, onConferenceJoined, videoConf]);
|
|
|
|
useEffect(() => {
|
|
setCookies();
|
|
}, []);
|
|
|
|
const callUrl = `${url}${url.includes('#config') ? '&' : '#'}config.disableDeepLinking=true`;
|
|
|
|
return (
|
|
<SafeAreaView style={styles.container}>
|
|
{authModal && <JitsiAuthModal setAuthModal={setAuthModal} callUrl={callUrl} />}
|
|
{cookiesSet ? (
|
|
<WebView
|
|
source={{
|
|
uri: callUrl.replace(/"/g, "'"),
|
|
headers: {
|
|
Cookie: `rc_uid=${user.id}; rc_token=${user.token}`
|
|
}
|
|
}}
|
|
onNavigationStateChange={onNavigationStateChange}
|
|
onShouldStartLoadWithRequest={onNavigationStateChange}
|
|
style={styles.webviewContainer}
|
|
userAgent={userAgent}
|
|
javaScriptEnabled
|
|
domStorageEnabled
|
|
allowsInlineMediaPlayback
|
|
mediaCapturePermissionGrantType={'grant'}
|
|
mediaPlaybackRequiresUserAction={isIOS}
|
|
sharedCookiesEnabled
|
|
/>
|
|
) : (
|
|
<View style={[styles.webviewContainer, styles.loading]}>
|
|
<ActivityIndicator />
|
|
</View>
|
|
)}
|
|
</SafeAreaView>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1
|
|
},
|
|
webviewContainer: { flex: 1, backgroundColor: 'rgb(62,62,62)' },
|
|
loading: { alignItems: 'center', justifyContent: 'center' }
|
|
});
|
|
|
|
export default JitsiMeetView;
|