103 lines
3.4 KiB
TypeScript
103 lines
3.4 KiB
TypeScript
|
import React from 'react';
|
||
|
import { BackHandler, NativeEventSubscription } from 'react-native';
|
||
|
import BackgroundTimer from 'react-native-background-timer';
|
||
|
import { isAppInstalled, openAppWithUri } from 'react-native-send-intent';
|
||
|
import WebView from 'react-native-webview';
|
||
|
import { WebViewMessage, WebViewNavigation } from 'react-native-webview/lib/WebViewTypes';
|
||
|
|
||
|
import { IBaseScreen } from '../definitions';
|
||
|
import { events, logEvent } from '../lib/methods/helpers/log';
|
||
|
import { Services } from '../lib/services';
|
||
|
import { ChatsStackParamList } from '../stacks/types';
|
||
|
import { withTheme } from '../theme';
|
||
|
|
||
|
const JITSI_INTENT = 'org.jitsi.meet';
|
||
|
|
||
|
type TJitsiMeetViewProps = IBaseScreen<ChatsStackParamList, 'JitsiMeetView'>;
|
||
|
|
||
|
class JitsiMeetView extends React.Component<TJitsiMeetViewProps> {
|
||
|
private rid: string;
|
||
|
private url: string;
|
||
|
private videoConf: boolean;
|
||
|
private jitsiTimeout: number | null;
|
||
|
private backHandler!: NativeEventSubscription;
|
||
|
|
||
|
constructor(props: TJitsiMeetViewProps) {
|
||
|
super(props);
|
||
|
this.rid = props.route.params?.rid;
|
||
|
this.url = props.route.params?.url;
|
||
|
this.videoConf = !!props.route.params?.videoConf;
|
||
|
this.jitsiTimeout = null;
|
||
|
}
|
||
|
|
||
|
componentDidMount() {
|
||
|
const { route, navigation } = this.props;
|
||
|
isAppInstalled(JITSI_INTENT)
|
||
|
.then(function (isInstalled) {
|
||
|
if (isInstalled) {
|
||
|
const callUrl = route.params.url.replace(/^https?:\/\//, '').split('#')[0];
|
||
|
openAppWithUri(`intent://${callUrl}#Intent;scheme=${JITSI_INTENT};package=${JITSI_INTENT};end`)
|
||
|
.then(() => navigation.pop())
|
||
|
.catch(() => {});
|
||
|
}
|
||
|
})
|
||
|
.catch(() => {});
|
||
|
this.onConferenceJoined();
|
||
|
this.backHandler = BackHandler.addEventListener('hardwareBackPress', () => true);
|
||
|
}
|
||
|
|
||
|
componentWillUnmount() {
|
||
|
logEvent(this.videoConf ? events.LIVECHAT_VIDEOCONF_TERMINATE : events.JM_CONFERENCE_TERMINATE);
|
||
|
if (this.jitsiTimeout && !this.videoConf) {
|
||
|
BackgroundTimer.clearInterval(this.jitsiTimeout);
|
||
|
this.jitsiTimeout = null;
|
||
|
BackgroundTimer.stopBackgroundTimer();
|
||
|
}
|
||
|
this.backHandler.remove();
|
||
|
}
|
||
|
|
||
|
// Jitsi Update Timeout needs to be called every 10 seconds to make sure
|
||
|
// call is not ended and is available to web users.
|
||
|
onConferenceJoined = () => {
|
||
|
logEvent(this.videoConf ? events.LIVECHAT_VIDEOCONF_JOIN : events.JM_CONFERENCE_JOIN);
|
||
|
if (this.rid && !this.videoConf) {
|
||
|
Services.updateJitsiTimeout(this.rid).catch((e: unknown) => console.log(e));
|
||
|
if (this.jitsiTimeout) {
|
||
|
BackgroundTimer.clearInterval(this.jitsiTimeout);
|
||
|
BackgroundTimer.stopBackgroundTimer();
|
||
|
this.jitsiTimeout = null;
|
||
|
}
|
||
|
this.jitsiTimeout = BackgroundTimer.setInterval(() => {
|
||
|
Services.updateJitsiTimeout(this.rid).catch((e: unknown) => console.log(e));
|
||
|
}, 10000);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
onNavigationStateChange = (webViewState: WebViewNavigation | WebViewMessage) => {
|
||
|
const { navigation, route } = this.props;
|
||
|
const jitsiRoomId = route.params.url
|
||
|
?.split(/^https?:\/\//)[1]
|
||
|
?.split('#')[0]
|
||
|
?.split('/')[1];
|
||
|
if ((jitsiRoomId && !webViewState.url.includes(jitsiRoomId)) || webViewState.url.includes('close')) {
|
||
|
navigation.pop();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
render() {
|
||
|
return (
|
||
|
<WebView
|
||
|
source={{ uri: `${this.url}&config.disableDeepLinking=true` }}
|
||
|
onMessage={({ nativeEvent }) => this.onNavigationStateChange(nativeEvent)}
|
||
|
onNavigationStateChange={this.onNavigationStateChange}
|
||
|
style={{ flex: 1 }}
|
||
|
javaScriptEnabled
|
||
|
domStorageEnabled
|
||
|
mediaPlaybackRequiresUserAction={false}
|
||
|
/>
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default withTheme(JitsiMeetView);
|