[RN] Add conference navigation bar

pull/3873/head jitsi-meet_3534
Bettenbuk Zoltan 6 years ago committed by Saúl Ibarra Corretgé
parent 46713cab3b
commit 9f3ef43daa
  1. 2
      ios/Podfile
  2. 8
      ios/Podfile.lock
  3. 16
      react/features/base/conference/functions.js
  4. 3
      react/features/conference/components/native/Conference.js
  5. 19
      react/features/conference/components/native/Labels.js
  6. 96
      react/features/conference/components/native/NavigationBar.js
  7. 58
      react/features/conference/components/native/styles.js
  8. 8
      react/features/mobile/call-integration/middleware.js
  9. 2
      react/features/toolbox/components/native/OverflowMenu.js

@ -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…
Cancel
Save