feat)rn,sdk) introduce a "ready to close" event
This event is the event host applications need to listen to for knowing when to dispose the SDK from now on. Since the introduction of breakout rooms it's possible that we navigate from one meeting to another, so there will be several conference join / terminations. In addition, local track destruction is now moved to SET_ROOM when there is no room, aka, we are going back to the welcome page or to the black page.
This commit is contained in:
parent
763d975445
commit
d7b581e338
|
@ -182,11 +182,6 @@ public class MainActivity extends JitsiMeetActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onConferenceTerminated(HashMap<String, Object> extraData) {
|
|
||||||
Log.d(TAG, "Conference terminated: " + extraData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activity lifecycle method overrides
|
// Activity lifecycle method overrides
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class BroadcastEvent {
|
||||||
CHAT_MESSAGE_RECEIVED("org.jitsi.meet.CHAT_MESSAGE_RECEIVED"),
|
CHAT_MESSAGE_RECEIVED("org.jitsi.meet.CHAT_MESSAGE_RECEIVED"),
|
||||||
CHAT_TOGGLED("org.jitsi.meet.CHAT_TOGGLED"),
|
CHAT_TOGGLED("org.jitsi.meet.CHAT_TOGGLED"),
|
||||||
VIDEO_MUTED_CHANGED("org.jitsi.meet.VIDEO_MUTED_CHANGED");
|
VIDEO_MUTED_CHANGED("org.jitsi.meet.VIDEO_MUTED_CHANGED");
|
||||||
|
READY_TO_CLOSE("org.jitsi.meet.READY_TO_CLOSE");
|
||||||
|
|
||||||
private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
|
private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
|
||||||
private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
|
private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
|
||||||
|
@ -101,6 +101,7 @@ public class BroadcastEvent {
|
||||||
private static final String CHAT_MESSAGE_RECEIVED_NAME = "CHAT_MESSAGE_RECEIVED";
|
private static final String CHAT_MESSAGE_RECEIVED_NAME = "CHAT_MESSAGE_RECEIVED";
|
||||||
private static final String CHAT_TOGGLED_NAME = "CHAT_TOGGLED";
|
private static final String CHAT_TOGGLED_NAME = "CHAT_TOGGLED";
|
||||||
private static final String VIDEO_MUTED_CHANGED_NAME = "VIDEO_MUTED_CHANGED";
|
private static final String VIDEO_MUTED_CHANGED_NAME = "VIDEO_MUTED_CHANGED";
|
||||||
|
private static final String READY_TO_CLOSE_NAME = "READY_TO_CLOSE";
|
||||||
|
|
||||||
private final String action;
|
private final String action;
|
||||||
|
|
||||||
|
@ -147,6 +148,8 @@ public class BroadcastEvent {
|
||||||
return CHAT_TOGGLED;
|
return CHAT_TOGGLED;
|
||||||
case VIDEO_MUTED_CHANGED_NAME:
|
case VIDEO_MUTED_CHANGED_NAME:
|
||||||
return VIDEO_MUTED_CHANGED;
|
return VIDEO_MUTED_CHANGED;
|
||||||
|
case READY_TO_CLOSE_NAME:
|
||||||
|
return READY_TO_CLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -194,7 +194,6 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||||
|
|
||||||
protected void onConferenceTerminated(HashMap<String, Object> extraData) {
|
protected void onConferenceTerminated(HashMap<String, Object> extraData) {
|
||||||
JitsiMeetLogger.i("Conference terminated: " + extraData);
|
JitsiMeetLogger.i("Conference terminated: " + extraData);
|
||||||
finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onConferenceWillJoin(HashMap<String, Object> extraData) {
|
protected void onConferenceWillJoin(HashMap<String, Object> extraData) {
|
||||||
|
@ -217,6 +216,11 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onReadyToClose() {
|
||||||
|
JitsiMeetLogger.i("SDK is ready to close");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
// Activity lifecycle methods
|
// Activity lifecycle methods
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -298,6 +302,9 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||||
case PARTICIPANT_LEFT:
|
case PARTICIPANT_LEFT:
|
||||||
onParticipantLeft(event.getData());
|
onParticipantLeft(event.getData());
|
||||||
break;
|
break;
|
||||||
|
case READY_TO_CLOSE:
|
||||||
|
onReadyToClose();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,10 +91,13 @@
|
||||||
#if 0
|
#if 0
|
||||||
- (void)enterPictureInPicture:(NSDictionary *)data {
|
- (void)enterPictureInPicture:(NSDictionary *)data {
|
||||||
[self _onJitsiMeetViewDelegateEvent:@"ENTER_PICTURE_IN_PICTURE" withData:data];
|
[self _onJitsiMeetViewDelegateEvent:@"ENTER_PICTURE_IN_PICTURE" withData:data];
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
- (void)readyToClose:(NSDictionary *)data {
|
||||||
|
[self _onJitsiMeetViewDelegateEvent:@"READY_TO_CLOSE" withData:data];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)participantJoined:(NSDictionary *)data {
|
- (void)participantJoined:(NSDictionary *)data {
|
||||||
NSLog(@"%@%@", @"Participant joined: ", data[@"participantId"]);
|
NSLog(@"%@%@", @"Participant joined: ", data[@"participantId"]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,4 +111,9 @@
|
||||||
*/
|
*/
|
||||||
- (void)videoMutedChanged:(NSDictionary *)data;
|
- (void)videoMutedChanged:(NSDictionary *)data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the SDK is ready to be closed. No meeting is happening at this point.
|
||||||
|
*/
|
||||||
|
- (void)readyToClose:(NSDictionary *)data;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -39,6 +39,9 @@
|
||||||
"audioOnly": {
|
"audioOnly": {
|
||||||
"audioOnly": "Low bandwidth"
|
"audioOnly": "Low bandwidth"
|
||||||
},
|
},
|
||||||
|
"blankPage": {
|
||||||
|
"meetingEnded": "Meeting ended."
|
||||||
|
},
|
||||||
"breakoutRooms": {
|
"breakoutRooms": {
|
||||||
"defaultName": "Breakout room #{{index}}",
|
"defaultName": "Breakout room #{{index}}",
|
||||||
"mainRoom": "Main room",
|
"mainRoom": "Main room",
|
||||||
|
|
|
@ -43,9 +43,6 @@ export default {
|
||||||
'LargeVideo': {
|
'LargeVideo': {
|
||||||
background: '#040404'
|
background: '#040404'
|
||||||
},
|
},
|
||||||
'LoadConfigOverlay': {
|
|
||||||
background: 'rgb(249, 249, 249)'
|
|
||||||
},
|
|
||||||
'Thumbnail': {
|
'Thumbnail': {
|
||||||
activeParticipantHighlight: 'rgb(81, 214, 170)',
|
activeParticipantHighlight: 'rgb(81, 214, 170)',
|
||||||
activeParticipantTint: 'rgba(49, 183, 106, 0.3)',
|
activeParticipantTint: 'rgba(49, 183, 106, 0.3)',
|
||||||
|
|
|
@ -14,7 +14,12 @@ import { isRoomValid, SET_ROOM } from '../conference';
|
||||||
import { getLocalParticipant } from '../participants';
|
import { getLocalParticipant } from '../participants';
|
||||||
import { MiddlewareRegistry } from '../redux';
|
import { MiddlewareRegistry } from '../redux';
|
||||||
import { getPropertyValue } from '../settings';
|
import { getPropertyValue } from '../settings';
|
||||||
import { isLocalVideoTrackDesktop, setTrackMuted, TRACK_ADDED } from '../tracks';
|
import {
|
||||||
|
destroyLocalTracks,
|
||||||
|
isLocalVideoTrackDesktop,
|
||||||
|
setTrackMuted,
|
||||||
|
TRACK_ADDED
|
||||||
|
} from '../tracks';
|
||||||
|
|
||||||
import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from './actionTypes';
|
import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from './actionTypes';
|
||||||
import { setAudioMuted, setCameraFacingMode, setVideoMuted } from './actions';
|
import { setAudioMuted, setCameraFacingMode, setVideoMuted } from './actions';
|
||||||
|
@ -217,6 +222,10 @@ function _setRoom({ dispatch, getState }, next, action) {
|
||||||
|
|
||||||
dispatch(setAudioOnly(audioOnly, false));
|
dispatch(setAudioOnly(audioOnly, false));
|
||||||
|
|
||||||
|
if (!roomIsValid) {
|
||||||
|
dispatch(destroyLocalTracks());
|
||||||
|
}
|
||||||
|
|
||||||
return next(action);
|
return next(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
/**
|
||||||
|
* The type of the action which indicates the SDK is ready to be closed.
|
||||||
|
*
|
||||||
|
* @returns {{
|
||||||
|
* type: READY_TO_CLOSE
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
export const READY_TO_CLOSE = 'READY_TO_CLOSE';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the action which sets the list of known participant IDs which
|
* The type of the action which sets the list of known participant IDs which
|
||||||
* have an active screen share.
|
* have an active screen share.
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { SCREEN_SHARE_PARTICIPANTS_UPDATED } from './actionTypes';
|
import {
|
||||||
|
READY_TO_CLOSE,
|
||||||
|
SCREEN_SHARE_PARTICIPANTS_UPDATED
|
||||||
|
} from './actionTypes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a (redux) action which signals that the SDK is ready to be closed.
|
||||||
|
*
|
||||||
|
* @returns {{
|
||||||
|
* type: READY_TO_CLOSE
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
export function readyToClose() {
|
||||||
|
return {
|
||||||
|
type: READY_TO_CLOSE
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a (redux) action which signals that the list of known participants
|
* Creates a (redux) action which signals that the list of known participants
|
||||||
|
@ -9,10 +25,10 @@ import { SCREEN_SHARE_PARTICIPANTS_UPDATED } from './actionTypes';
|
||||||
* @param {string} participantIds - The participants which currently have active
|
* @param {string} participantIds - The participants which currently have active
|
||||||
* screen share streams.
|
* screen share streams.
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
|
* type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
|
||||||
* participantId: string
|
* participantId: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function setParticipantsWithScreenShare(participantIds: Array<string>) {
|
export function setParticipantsWithScreenShare(participantIds: Array<string>) {
|
||||||
return {
|
return {
|
||||||
type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
|
type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
|
||||||
|
|
|
@ -24,8 +24,6 @@ import {
|
||||||
getURLWithoutParams
|
getURLWithoutParams
|
||||||
} from '../../base/connection';
|
} from '../../base/connection';
|
||||||
import {
|
import {
|
||||||
isFatalJitsiConferenceError,
|
|
||||||
isFatalJitsiConnectionError,
|
|
||||||
JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
|
JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
|
||||||
import { MEDIA_TYPE } from '../../base/media';
|
import { MEDIA_TYPE } from '../../base/media';
|
||||||
import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../../base/media/actionTypes';
|
import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../../base/media/actionTypes';
|
||||||
|
@ -45,6 +43,7 @@ import { SET_PAGE_RELOAD_OVERLAY_CANCELED } from '../../overlay/actionTypes';
|
||||||
import { muteLocal } from '../../video-menu/actions';
|
import { muteLocal } from '../../video-menu/actions';
|
||||||
import { ENTER_PICTURE_IN_PICTURE } from '../picture-in-picture';
|
import { ENTER_PICTURE_IN_PICTURE } from '../picture-in-picture';
|
||||||
|
|
||||||
|
import { READY_TO_CLOSE } from './actionTypes';
|
||||||
import { setParticipantsWithScreenShare } from './actions';
|
import { setParticipantsWithScreenShare } from './actions';
|
||||||
import { sendEvent } from './functions';
|
import { sendEvent } from './functions';
|
||||||
import logger from './logger';
|
import logger from './logger';
|
||||||
|
@ -116,7 +115,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
// counterpart of the External API (or at least not in the
|
// counterpart of the External API (or at least not in the
|
||||||
// fatality/finality semantics attributed to
|
// fatality/finality semantics attributed to
|
||||||
// conferenceFailed:/onConferenceFailed).
|
// conferenceFailed:/onConferenceFailed).
|
||||||
if (!error.recoverable && !isFatalJitsiConnectionError(error) && !isFatalJitsiConferenceError(error)) {
|
if (!error.recoverable) {
|
||||||
_sendConferenceEvent(store, /* action */ {
|
_sendConferenceEvent(store, /* action */ {
|
||||||
error: _toErrorString(error),
|
error: _toErrorString(error),
|
||||||
...data
|
...data
|
||||||
|
@ -190,6 +189,10 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case READY_TO_CLOSE:
|
||||||
|
sendEvent(store, type, /* data */ {});
|
||||||
|
break;
|
||||||
|
|
||||||
case SET_ROOM:
|
case SET_ROOM:
|
||||||
_maybeTriggerEarlyConferenceWillJoin(store, action);
|
_maybeTriggerEarlyConferenceWillJoin(store, action);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { SafeAreaView, Text, View } from 'react-native';
|
import { SafeAreaView, Text, View } from 'react-native';
|
||||||
|
|
||||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
import { LoadingIndicator } from '../../../base/react';
|
import { LoadingIndicator } from '../../../base/react';
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
import { StyleType } from '../../../base/styles';
|
import { StyleType } from '../../../base/styles';
|
||||||
|
|
||||||
import OverlayFrame from './OverlayFrame';
|
import OverlayFrame from './OverlayFrame';
|
||||||
import styles from './styles';
|
import styles, { TEXT_COLOR } from './styles';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
|
@ -29,7 +27,7 @@ type Props = {
|
||||||
* Implements an overlay to tell the user that there is an operation in progress in the background during connect
|
* Implements an overlay to tell the user that there is an operation in progress in the background during connect
|
||||||
* so then the app doesn't seem hung.
|
* so then the app doesn't seem hung.
|
||||||
*/
|
*/
|
||||||
class LoadConfigOverlay extends Component<Props> {
|
class LoadConfigOverlay extends PureComponent<Props> {
|
||||||
/**
|
/**
|
||||||
* Determines whether this overlay needs to be rendered (according to a
|
* Determines whether this overlay needs to be rendered (according to a
|
||||||
* specific redux state). Called by {@link OverlayContainer}.
|
* specific redux state). Called by {@link OverlayContainer}.
|
||||||
|
@ -49,25 +47,15 @@ class LoadConfigOverlay extends Component<Props> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { _styles } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OverlayFrame>
|
<OverlayFrame>
|
||||||
<View
|
<View style = { styles.loadingOverlayWrapper }>
|
||||||
style = { [
|
|
||||||
styles.loadingOverlayWrapper,
|
|
||||||
_styles.loadingOverlayWrapper
|
|
||||||
] }>
|
|
||||||
<SafeAreaView>
|
<SafeAreaView>
|
||||||
<LoadingIndicator
|
<LoadingIndicator
|
||||||
color = { _styles.indicatorColor }
|
color = { TEXT_COLOR }
|
||||||
size = 'large'
|
size = 'large'
|
||||||
style = { styles.connectIndicator } />
|
style = { styles.connectIndicator } />
|
||||||
<Text
|
<Text style = { styles.loadingOverlayText }>
|
||||||
style = { [
|
|
||||||
styles.loadingOverlayText,
|
|
||||||
_styles.loadingOverlayText
|
|
||||||
] }>
|
|
||||||
{ this.props.t('connectingOverlay.joiningRoom') }
|
{ this.props.t('connectingOverlay.joiningRoom') }
|
||||||
</Text>
|
</Text>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
|
@ -77,18 +65,5 @@ class LoadConfigOverlay extends Component<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps part of the Redux state to the props of this component.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The Redux state.
|
|
||||||
* @returns {{
|
|
||||||
* _styles: StyleType
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _mapStateToProps(state) {
|
|
||||||
return {
|
|
||||||
_styles: ColorSchemeRegistry.get(state, 'LoadConfigOverlay')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(LoadConfigOverlay));
|
export default translate(LoadConfigOverlay);
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
|
|
||||||
import { BoxModel, ColorPalette } from '../../../base/styles';
|
import { BoxModel, ColorPalette } from '../../../base/styles';
|
||||||
|
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
|
|
||||||
|
export const TEXT_COLOR = BaseTheme.palette.text01;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The React {@code Component} styles of the overlay feature.
|
* The React {@code Component} styles of the overlay feature.
|
||||||
|
@ -23,12 +25,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
loadingOverlayText: {
|
loadingOverlayText: {
|
||||||
color: ColorPalette.white
|
color: TEXT_COLOR
|
||||||
},
|
},
|
||||||
|
|
||||||
loadingOverlayWrapper: {
|
loadingOverlayWrapper: {
|
||||||
...StyleSheet.absoluteFillObject,
|
...StyleSheet.absoluteFillObject,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
backgroundColor: BaseTheme.palette.uiBackground,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
|
@ -38,18 +41,3 @@ export default {
|
||||||
flex: 1
|
flex: 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Color schemed styles for all the component based on the abstract dialog.
|
|
||||||
*/
|
|
||||||
ColorSchemeRegistry.register('LoadConfigOverlay', {
|
|
||||||
indicatorColor: schemeColor('text'),
|
|
||||||
|
|
||||||
loadingOverlayText: {
|
|
||||||
color: schemeColor('text')
|
|
||||||
},
|
|
||||||
|
|
||||||
loadingOverlayWrapper: {
|
|
||||||
backgroundColor: schemeColor('background')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,80 +1,34 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { View } from 'react-native';
|
import { useTranslation } from 'react-i18next';
|
||||||
import type { Dispatch } from 'redux';
|
import { Text, View } from 'react-native';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import { ColorSchemeRegistry } from '../../base/color-scheme';
|
import { readyToClose } from '../../mobile/external-api/actions';
|
||||||
import { LoadingIndicator } from '../../base/react';
|
|
||||||
import { connect } from '../../base/redux';
|
|
||||||
import { StyleType } from '../../base/styles';
|
|
||||||
import { destroyLocalTracks } from '../../base/tracks';
|
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of React {@code Component} props of {@link BlankPage}.
|
|
||||||
*/
|
|
||||||
type Props = {
|
|
||||||
|
|
||||||
/**
|
const BlankPage = () => {
|
||||||
* The color schemed style of the component.
|
const dispatch = useDispatch();
|
||||||
*/
|
const { t } = useTranslation();
|
||||||
_styles: StyleType,
|
|
||||||
|
|
||||||
dispatch: Dispatch<any>
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The React {@code Component} displayed by {@code AbstractApp} when it has no
|
|
||||||
* {@code Route} to render. Renders a progress indicator when there are ongoing
|
|
||||||
* network requests.
|
|
||||||
*/
|
|
||||||
class BlankPage extends Component<Props> {
|
|
||||||
/**
|
/**
|
||||||
* Destroys the local tracks (if any) since no media is desired when this
|
* Destroys the local tracks (if any) since no media is desired when this
|
||||||
* component is rendered.
|
* component is rendered.
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
*/
|
||||||
componentDidMount() {
|
useEffect(() => {
|
||||||
this.props.dispatch(destroyLocalTracks());
|
dispatch(readyToClose());
|
||||||
}
|
}, []);
|
||||||
|
|
||||||
/**
|
return (
|
||||||
* Implements React's {@link Component#render()}.
|
<View style = { styles.blankPageWrapper }>
|
||||||
*
|
<Text style = { styles.blankPageText }>
|
||||||
* @inheritdoc
|
{ t('blankPage.meetingEnded') }
|
||||||
* @returns {ReactElement}
|
</Text>
|
||||||
*/
|
</View>
|
||||||
render() {
|
);
|
||||||
const { _styles } = this.props;
|
};
|
||||||
|
|
||||||
return (
|
export default BlankPage;
|
||||||
<View
|
|
||||||
style = { [
|
|
||||||
styles.blankPageWrapper,
|
|
||||||
_styles.loadingOverlayWrapper
|
|
||||||
] }>
|
|
||||||
<LoadingIndicator
|
|
||||||
color = { _styles.indicatorColor }
|
|
||||||
size = 'large' />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps part of the Redux state to the props of this component.
|
|
||||||
*
|
|
||||||
* @param {Object} state - The Redux state.
|
|
||||||
* @returns {Props}
|
|
||||||
*/
|
|
||||||
function _mapStateToProps(state) {
|
|
||||||
return {
|
|
||||||
_styles: ColorSchemeRegistry.get(state, 'LoadConfigOverlay')
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(_mapStateToProps)(BlankPage);
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { Icon, IconMenu, IconWarning } from '../../base/icons';
|
||||||
import JitsiStatusBar from '../../base/modal/components/JitsiStatusBar';
|
import JitsiStatusBar from '../../base/modal/components/JitsiStatusBar';
|
||||||
import { LoadingIndicator, Text } from '../../base/react';
|
import { LoadingIndicator, Text } from '../../base/react';
|
||||||
import { connect } from '../../base/redux';
|
import { connect } from '../../base/redux';
|
||||||
import { destroyLocalTracks } from '../../base/tracks';
|
|
||||||
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -108,7 +107,6 @@ class WelcomePage extends AbstractWelcomePage<*> {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
_headerStyles,
|
_headerStyles,
|
||||||
dispatch,
|
|
||||||
navigation
|
navigation
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -129,8 +127,6 @@ class WelcomePage extends AbstractWelcomePage<*> {
|
||||||
headerRight: () =>
|
headerRight: () =>
|
||||||
<VideoSwitch />
|
<VideoSwitch />
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatch(destroyLocalTracks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,12 +42,18 @@ export default {
|
||||||
marginRight: BaseTheme.spacing[2]
|
marginRight: BaseTheme.spacing[2]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
blankPageText: {
|
||||||
|
color: TEXT_COLOR,
|
||||||
|
fontSize: 18
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View that is rendered when there is no welcome page.
|
* View that is rendered when there is no welcome page.
|
||||||
*/
|
*/
|
||||||
blankPageWrapper: {
|
blankPageWrapper: {
|
||||||
...StyleSheet.absoluteFillObject,
|
...StyleSheet.absoluteFillObject,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
backgroundColor: BaseTheme.palette.uiBackground,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
|
|
Loading…
Reference in New Issue