[RN] Add conference navigation bar
This commit is contained in:
parent
46713cab3b
commit
9f3ef43daa
|
@ -43,6 +43,8 @@ target 'JitsiMeet' do
|
|||
:path => '../node_modules/react-native-fast-image'
|
||||
pod 'react-native-keep-awake',
|
||||
:path => '../node_modules/react-native-keep-awake'
|
||||
pod 'BVLinearGradient',
|
||||
:path => '../node_modules/react-native-linear-gradient'
|
||||
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
||||
pod 'RNGoogleSignin',
|
||||
:path => '../node_modules/react-native-google-signin'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BVLinearGradient (2.5.3):
|
||||
- React
|
||||
- Crashlytics (3.12.0):
|
||||
- Fabric (~> 1.9.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
|
@ -152,6 +154,7 @@ PODS:
|
|||
- yoga (0.57.8.React)
|
||||
|
||||
DEPENDENCIES:
|
||||
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
|
||||
- Crashlytics
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- Fabric
|
||||
|
@ -202,6 +205,8 @@ SPEC REPOS:
|
|||
- SDWebImage
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
BVLinearGradient:
|
||||
:path: "../node_modules/react-native-linear-gradient"
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
Folly:
|
||||
|
@ -231,6 +236,7 @@ EXTERNAL SOURCES:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: b0b70acf63ee888829b7c2ebbf6b50e227396e55
|
||||
Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933
|
||||
DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd
|
||||
Fabric: f988e33c97f08930a413e08123064d2e5f68d655
|
||||
|
@ -262,6 +268,6 @@ SPEC CHECKSUMS:
|
|||
SDWebImage: c5594f1a19c48d526d321e548902b56b479cd508
|
||||
yoga: b1ce48b6cf950b98deae82838f5173ea7cf89e85
|
||||
|
||||
PODFILE CHECKSUM: b5218184626a027e8b1ca12361d46100e2fa2f1f
|
||||
PODFILE CHECKSUM: 7d1909450626f31f9ea2de80122a66a50af2e1ea
|
||||
|
||||
COCOAPODS: 1.5.3
|
||||
|
|
|
@ -145,6 +145,22 @@ export function forEachConference(
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display name of the conference.
|
||||
*
|
||||
* @param {Function | Object} stateful - Reference that can be resolved to Redux
|
||||
* state with the {@code toState} function.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getConferenceName(stateful: Function | Object): string {
|
||||
const state = toState(stateful);
|
||||
const { callee } = state['features/base/jwt'];
|
||||
|
||||
return state['features/base/config'].callDisplayName
|
||||
|| (callee && callee.name)
|
||||
|| state['features/base/conference'].room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current {@code JitsiConference} which is joining or joined and is
|
||||
* not leaving. Please note the contrast with merely reading the
|
||||
|
|
|
@ -29,6 +29,7 @@ import { shouldDisplayTileView } from '../../../video-layout';
|
|||
|
||||
import DisplayNameLabel from './DisplayNameLabel';
|
||||
import Labels from './Labels';
|
||||
import NavigationBar from './NavigationBar';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
|
@ -306,6 +307,8 @@ class Conference extends Component<Props> {
|
|||
}
|
||||
</View>
|
||||
|
||||
<NavigationBar />
|
||||
|
||||
<TestConnectionInfo />
|
||||
|
||||
{
|
||||
|
|
|
@ -12,7 +12,9 @@ import {
|
|||
import {
|
||||
RecordingExpandedLabel
|
||||
} from '../../../recording';
|
||||
import { isToolboxVisible } from '../../../toolbox';
|
||||
import { TranscribingExpandedLabel } from '../../../transcribing';
|
||||
import { shouldDisplayTileView } from '../../../video-layout';
|
||||
import { VideoQualityExpandedLabel } from '../../../video-quality';
|
||||
|
||||
import AbstractLabels, {
|
||||
|
@ -37,7 +39,12 @@ type Props = AbstractLabelsProps & {
|
|||
*
|
||||
* @private
|
||||
*/
|
||||
_reducedUI: boolean
|
||||
_reducedUI: boolean,
|
||||
|
||||
/**
|
||||
* True if the labels should be visible, false otherwise.
|
||||
*/
|
||||
_visible: boolean
|
||||
};
|
||||
|
||||
type State = {
|
||||
|
@ -148,6 +155,10 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
if (!this.props._visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const wide = !isNarrowAspectRatio(this);
|
||||
const { _filmstripVisible, _reducedUI } = this.props;
|
||||
|
||||
|
@ -344,13 +355,15 @@ class Labels extends AbstractLabels<Props, State> {
|
|||
* @private
|
||||
* @returns {{
|
||||
* _filmstripVisible: boolean,
|
||||
* _reducedUI: boolean
|
||||
* _reducedUI: boolean,
|
||||
* _visible: boolean
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_reducedUI: state['features/base/responsive-ui'].reducedUI
|
||||
_reducedUI: state['features/base/responsive-ui'].reducedUI,
|
||||
_visible: !isToolboxVisible(state) && !shouldDisplayTileView(state)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
// @flow
|
||||
|
||||
import _ from 'lodash';
|
||||
import React, { Component } from 'react';
|
||||
import { SafeAreaView, Text, View } from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getConferenceName } from '../../../base/conference';
|
||||
import { PictureInPictureButton } from '../../../mobile/picture-in-picture';
|
||||
import { isToolboxVisible } from '../../../toolbox';
|
||||
|
||||
import styles, { NAVBAR_GRADIENT_COLORS } from './styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Name of the meeting we're currently in.
|
||||
*/
|
||||
_meetingName: string,
|
||||
|
||||
/**
|
||||
* True if the navigation bar should be visible.
|
||||
*/
|
||||
_visible: boolean
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a navigation bar component that is rendered on top of the
|
||||
* conference screen.
|
||||
*/
|
||||
class NavigationBar extends Component<Props> {
|
||||
/**
|
||||
* Implements {@Component#render}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
if (!this.props._visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.navBarContainer }>
|
||||
<LinearGradient
|
||||
colors = { NAVBAR_GRADIENT_COLORS }
|
||||
pointerEvents = 'none'
|
||||
style = { styles.gradient }>
|
||||
<SafeAreaView>
|
||||
<View style = { styles.gradientStretch } />
|
||||
</SafeAreaView>
|
||||
</LinearGradient>
|
||||
<SafeAreaView
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.navBarSafeView }>
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.navBarWrapper }>
|
||||
<PictureInPictureButton
|
||||
styles = { styles.navBarButton } />
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.roomNameWrapper }>
|
||||
<Text
|
||||
numberOfLines = { 1 }
|
||||
style = { styles.roomName }>
|
||||
{ this.props._meetingName }
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux store to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _meetingName: string,
|
||||
* _visible: boolean
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_meetingName: _.startCase(getConferenceName(state)),
|
||||
_visible: isToolboxVisible(state)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(NavigationBar);
|
|
@ -7,6 +7,8 @@ import {
|
|||
|
||||
import { FILMSTRIP_SIZE } from '../../../filmstrip';
|
||||
|
||||
export const NAVBAR_GRADIENT_COLORS = [ 'black', '#00000000' ];
|
||||
|
||||
/**
|
||||
* The styles of the feature conference.
|
||||
*/
|
||||
|
@ -34,6 +36,14 @@ export default createStyleSheet({
|
|||
fontSize: 14
|
||||
},
|
||||
|
||||
gradient: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
gradientStretch: {
|
||||
height: 116
|
||||
},
|
||||
|
||||
/**
|
||||
* View that contains the indicators.
|
||||
*/
|
||||
|
@ -58,6 +68,54 @@ export default createStyleSheet({
|
|||
top: 0
|
||||
},
|
||||
|
||||
navBarButton: {
|
||||
iconStyle: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
underlayColor: 'transparent'
|
||||
},
|
||||
|
||||
navBarContainer: {
|
||||
flexDirection: 'column',
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0
|
||||
},
|
||||
|
||||
navBarSafeView: {
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0
|
||||
},
|
||||
|
||||
navBarWrapper: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: 44,
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 14
|
||||
},
|
||||
|
||||
roomName: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 17,
|
||||
fontWeight: '400'
|
||||
},
|
||||
|
||||
roomNameWrapper: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
left: 0,
|
||||
paddingHorizontal: 48,
|
||||
position: 'absolute',
|
||||
right: 0
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of the {@link View} which expands over the whole
|
||||
* {@link Conference} area and splits it between the {@link Filmstrip} and
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
CONFERENCE_WILL_JOIN,
|
||||
CONFERENCE_JOINED,
|
||||
SET_AUDIO_ONLY,
|
||||
getConferenceName,
|
||||
getCurrentConference
|
||||
} from '../../base/conference';
|
||||
import { getInviteURL } from '../../base/connection';
|
||||
|
@ -226,12 +227,7 @@ function _conferenceWillJoin({ dispatch, getState }, next, action) {
|
|||
|
||||
CallIntegration.startCall(conference.callUUID, handle, hasVideo)
|
||||
.then(() => {
|
||||
const { callee } = state['features/base/jwt'];
|
||||
const displayName
|
||||
= state['features/base/config'].callDisplayName
|
||||
|| (callee && callee.name)
|
||||
|| state['features/base/conference'].room;
|
||||
|
||||
const displayName = getConferenceName(state);
|
||||
const muted
|
||||
= isLocalTrackMuted(
|
||||
state['features/base/tracks'],
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
} from '../../../base/dialog';
|
||||
import { InviteButton } from '../../../invite';
|
||||
import { AudioRouteButton } from '../../../mobile/audio-mode';
|
||||
import { PictureInPictureButton } from '../../../mobile/picture-in-picture';
|
||||
import { LiveStreamButton, RecordButton } from '../../../recording';
|
||||
import { RoomLockButton } from '../../../room-lock';
|
||||
import { ClosedCaptionButton } from '../../../subtitles';
|
||||
|
@ -90,7 +89,6 @@ class OverflowMenu extends Component<Props> {
|
|||
<LiveStreamButton { ...buttonProps } />
|
||||
<TileViewButton { ...buttonProps } />
|
||||
<InviteButton { ...buttonProps } />
|
||||
<PictureInPictureButton { ...buttonProps } />
|
||||
</BottomSheet>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue