[RN] Room lock button
This commit is contained in:
parent
8c3fb54d3d
commit
9a49a01713
|
@ -45,6 +45,18 @@ export const CONFERENCE_LEFT = Symbol('CONFERENCE_LEFT');
|
||||||
*/
|
*/
|
||||||
export const CONFERENCE_WILL_LEAVE = Symbol('CONFERENCE_WILL_LEAVE');
|
export const CONFERENCE_WILL_LEAVE = Symbol('CONFERENCE_WILL_LEAVE');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the Redux action which signals that the lock state of a specific
|
||||||
|
* <tt>JitsiConference</tt> changed.
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* type: LOCK_STATE_CHANGED,
|
||||||
|
* conference: JitsiConference,
|
||||||
|
* locked: boolean
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
export const LOCK_STATE_CHANGED = Symbol('LOCK_STATE_CHANGED');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the Redux action which sets the password to join or lock a
|
* The type of the Redux action which sets the password to join or lock a
|
||||||
* specific JitsiConference.
|
* specific JitsiConference.
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
CONFERENCE_JOINED,
|
CONFERENCE_JOINED,
|
||||||
CONFERENCE_LEFT,
|
CONFERENCE_LEFT,
|
||||||
CONFERENCE_WILL_LEAVE,
|
CONFERENCE_WILL_LEAVE,
|
||||||
|
LOCK_STATE_CHANGED,
|
||||||
SET_PASSWORD,
|
SET_PASSWORD,
|
||||||
SET_ROOM
|
SET_ROOM
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
|
@ -46,6 +47,10 @@ function _addConferenceListeners(conference, dispatch) {
|
||||||
JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
|
JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
|
||||||
(...args) => dispatch(dominantSpeakerChanged(...args)));
|
(...args) => dispatch(dominantSpeakerChanged(...args)));
|
||||||
|
|
||||||
|
conference.on(
|
||||||
|
JitsiConferenceEvents.LOCK_STATE_CHANGED,
|
||||||
|
(...args) => dispatch(_lockStateChanged(conference, ...args)));
|
||||||
|
|
||||||
conference.on(
|
conference.on(
|
||||||
JitsiConferenceEvents.TRACK_ADDED,
|
JitsiConferenceEvents.TRACK_ADDED,
|
||||||
t => t && !t.isLocal() && dispatch(trackAdded(t)));
|
t => t && !t.isLocal() && dispatch(trackAdded(t)));
|
||||||
|
@ -185,6 +190,27 @@ export function createConference() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that the lock state of a specific JitsiConference changed.
|
||||||
|
*
|
||||||
|
* @param {JitsiConference} conference - The JitsiConference which had its lock
|
||||||
|
* state changed.
|
||||||
|
* @param {boolean} locked - If the specified conference became locked, true;
|
||||||
|
* otherwise, false.
|
||||||
|
* @returns {{
|
||||||
|
* type: LOCK_STATE_CHANGED,
|
||||||
|
* conference: JitsiConference,
|
||||||
|
* locked: boolean
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
function _lockStateChanged(conference, locked) {
|
||||||
|
return {
|
||||||
|
type: LOCK_STATE_CHANGED,
|
||||||
|
conference,
|
||||||
|
locked
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the password to join or lock a specific JitsiConference.
|
* Sets the password to join or lock a specific JitsiConference.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
CONFERENCE_JOINED,
|
CONFERENCE_JOINED,
|
||||||
CONFERENCE_LEFT,
|
CONFERENCE_LEFT,
|
||||||
CONFERENCE_WILL_LEAVE,
|
CONFERENCE_WILL_LEAVE,
|
||||||
|
LOCK_STATE_CHANGED,
|
||||||
SET_PASSWORD,
|
SET_PASSWORD,
|
||||||
SET_ROOM
|
SET_ROOM
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
|
@ -33,6 +34,9 @@ ReducerRegistry.register('features/base/conference', (state = {}, action) => {
|
||||||
case CONFERENCE_WILL_LEAVE:
|
case CONFERENCE_WILL_LEAVE:
|
||||||
return _conferenceWillLeave(state, action);
|
return _conferenceWillLeave(state, action);
|
||||||
|
|
||||||
|
case LOCK_STATE_CHANGED:
|
||||||
|
return _lockStateChanged(state, action);
|
||||||
|
|
||||||
case SET_PASSWORD:
|
case SET_PASSWORD:
|
||||||
return _setPassword(state, action);
|
return _setPassword(state, action);
|
||||||
|
|
||||||
|
@ -70,6 +74,7 @@ function _conferenceFailed(state, action) {
|
||||||
setStateProperties(state, {
|
setStateProperties(state, {
|
||||||
conference: undefined,
|
conference: undefined,
|
||||||
leaving: undefined,
|
leaving: undefined,
|
||||||
|
locked: undefined,
|
||||||
password: undefined,
|
password: undefined,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,6 +97,14 @@ function _conferenceFailed(state, action) {
|
||||||
* reduction of the specified action.
|
* reduction of the specified action.
|
||||||
*/
|
*/
|
||||||
function _conferenceJoined(state, action) {
|
function _conferenceJoined(state, action) {
|
||||||
|
const conference = action.conference;
|
||||||
|
|
||||||
|
// FIXME The indicator which determines whether a JitsiConference is locked
|
||||||
|
// i.e. password-protected is private to lib-jitsi-meet. However, the
|
||||||
|
// library does not fire LOCK_STATE_CHANGED upon joining a JitsiConference
|
||||||
|
// with a password.
|
||||||
|
const locked = conference.room.locked || undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
setStateProperties(state, {
|
setStateProperties(state, {
|
||||||
/**
|
/**
|
||||||
|
@ -100,8 +113,15 @@ function _conferenceJoined(state, action) {
|
||||||
*
|
*
|
||||||
* @type {JitsiConference}
|
* @type {JitsiConference}
|
||||||
*/
|
*/
|
||||||
conference: action.conference,
|
conference,
|
||||||
leaving: undefined,
|
leaving: undefined,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The indicator which determines whether the conference is locked.
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
locked,
|
||||||
passwordRequired: undefined
|
passwordRequired: undefined
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -127,6 +147,7 @@ function _conferenceLeft(state, action) {
|
||||||
setStateProperties(state, {
|
setStateProperties(state, {
|
||||||
conference: undefined,
|
conference: undefined,
|
||||||
leaving: undefined,
|
leaving: undefined,
|
||||||
|
locked: undefined,
|
||||||
password: undefined,
|
password: undefined,
|
||||||
passwordRequired: undefined
|
passwordRequired: undefined
|
||||||
}));
|
}));
|
||||||
|
@ -162,6 +183,24 @@ function _conferenceWillLeave(state, action) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces a specific Redux action LOCK_STATE_CHANGED of the feature
|
||||||
|
* base/conference.
|
||||||
|
*
|
||||||
|
* @param {Object} state - The Redux state of the feature base/conference.
|
||||||
|
* @param {Action} action - The Redux action LOCK_STATE_CHANGED to reduce.
|
||||||
|
* @private
|
||||||
|
* @returns {Object} The new state of the feature base/conference after the
|
||||||
|
* reduction of the specified action.
|
||||||
|
*/
|
||||||
|
function _lockStateChanged(state, action) {
|
||||||
|
if (state.conference !== action.conference) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
return setStateProperty(state, 'locked', action.locked || undefined);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces a specific Redux action SET_PASSWORD of the feature base/conference.
|
* Reduces a specific Redux action SET_PASSWORD of the feature base/conference.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
// FIXME React Native does not polyfill Symbol at versions 0.39.2 or earlier.
|
// FIXME React Native does not polyfill Symbol at versions 0.39.2 or earlier.
|
||||||
export default (global => {
|
export default (global => {
|
||||||
let s = global.Symbol;
|
let clazz = global.Symbol;
|
||||||
|
|
||||||
if (typeof s === 'undefined') {
|
if (typeof clazz === 'undefined') {
|
||||||
// XXX At the time of this writing we use Symbol only as a way to
|
// XXX At the time of this writing we use Symbol only as a way to
|
||||||
// prevent collisions in Redux action types. Consequently, the Symbol
|
// prevent collisions in Redux action types. Consequently, the Symbol
|
||||||
// implementation provided bellow is minimal and specific to our
|
// implementation provided bellow is minimal and specific to our
|
||||||
// purpose.
|
// purpose.
|
||||||
s = description => (description || '').split('');
|
const toString = function() {
|
||||||
|
return this.join(''); // eslint-disable-line no-invalid-this
|
||||||
|
};
|
||||||
|
|
||||||
|
clazz = description => {
|
||||||
|
const thiz = (description || '').split('');
|
||||||
|
|
||||||
|
thiz.toString = toString;
|
||||||
|
|
||||||
|
return thiz;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return clazz;
|
||||||
})(global || window || this); // eslint-disable-line no-invalid-this
|
})(global || window || this); // eslint-disable-line no-invalid-this
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { appNavigate } from '../../app';
|
import { appNavigate } from '../../app';
|
||||||
import {
|
import { toggleAudioMuted, toggleVideoMuted } from '../../base/media';
|
||||||
toggleAudioMuted,
|
|
||||||
toggleVideoMuted
|
|
||||||
} from '../../base/media';
|
|
||||||
import { ColorPalette } from '../../base/styles';
|
import { ColorPalette } from '../../base/styles';
|
||||||
|
|
||||||
import { styles } from './styles';
|
import { styles } from './styles';
|
||||||
|
@ -23,6 +20,12 @@ export class AbstractToolbar extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
audioMuted: React.PropTypes.bool,
|
audioMuted: React.PropTypes.bool,
|
||||||
dispatch: React.PropTypes.func,
|
dispatch: React.PropTypes.func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The indicator which determines whether the conference is
|
||||||
|
* locked/password-protected.
|
||||||
|
*/
|
||||||
|
locked: React.PropTypes.bool,
|
||||||
videoMuted: React.PropTypes.bool,
|
videoMuted: React.PropTypes.bool,
|
||||||
visible: React.PropTypes.bool.isRequired
|
visible: React.PropTypes.bool.isRequired
|
||||||
}
|
}
|
||||||
|
@ -39,6 +42,7 @@ export class AbstractToolbar extends Component {
|
||||||
// Bind event handlers so they are only bound once for every instance.
|
// Bind event handlers so they are only bound once for every instance.
|
||||||
this._onHangup = this._onHangup.bind(this);
|
this._onHangup = this._onHangup.bind(this);
|
||||||
this._toggleAudio = this._toggleAudio.bind(this);
|
this._toggleAudio = this._toggleAudio.bind(this);
|
||||||
|
this._toggleLock = this._toggleLock.bind(this);
|
||||||
this._toggleVideo = this._toggleVideo.bind(this);
|
this._toggleVideo = this._toggleVideo.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,33 +54,32 @@ export class AbstractToolbar extends Component {
|
||||||
* button to get styles for.
|
* button to get styles for.
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* buttonStyle: Object,
|
|
||||||
* iconName: string,
|
* iconName: string,
|
||||||
* iconStyle: Object
|
* iconStyle: Object,
|
||||||
|
* style: Object
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
_getMuteButtonStyles(mediaType) {
|
_getMuteButtonStyles(mediaType) {
|
||||||
let buttonStyle;
|
|
||||||
let iconName;
|
let iconName;
|
||||||
let iconStyle;
|
let iconStyle;
|
||||||
|
let style = styles.primaryToolbarButton;
|
||||||
|
|
||||||
if (this.props[`${mediaType}Muted`]) {
|
if (this.props[`${mediaType}Muted`]) {
|
||||||
buttonStyle = {
|
|
||||||
...styles.toolbarButton,
|
|
||||||
backgroundColor: ColorPalette.buttonUnderlay
|
|
||||||
};
|
|
||||||
iconName = this[`${mediaType}MutedIcon`];
|
iconName = this[`${mediaType}MutedIcon`];
|
||||||
iconStyle = styles.whiteIcon;
|
iconStyle = styles.whiteIcon;
|
||||||
|
style = {
|
||||||
|
...style,
|
||||||
|
backgroundColor: ColorPalette.buttonUnderlay
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
buttonStyle = styles.toolbarButton;
|
|
||||||
iconName = this[`${mediaType}Icon`];
|
iconName = this[`${mediaType}Icon`];
|
||||||
iconStyle = styles.icon;
|
iconStyle = styles.icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
buttonStyle,
|
|
||||||
iconName,
|
iconName,
|
||||||
iconStyle
|
iconStyle,
|
||||||
|
style
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +99,7 @@ export class AbstractToolbar extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches action to toggle the mute state of the audio/microphone.
|
* Dispatches an action to toggle the mute state of the audio/microphone.
|
||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -106,7 +109,18 @@ export class AbstractToolbar extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches action to toggle the mute state of the video/camera.
|
* Dispatches an action to toggle the lock i.e. password protection of the
|
||||||
|
* conference.
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_toggleLock() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches an action to toggle the mute state of the video/camera.
|
||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -123,10 +137,19 @@ export class AbstractToolbar extends Component {
|
||||||
* @returns {{ audioMuted: boolean, videoMuted: boolean }}
|
* @returns {{ audioMuted: boolean, videoMuted: boolean }}
|
||||||
*/
|
*/
|
||||||
export function mapStateToProps(state) {
|
export function mapStateToProps(state) {
|
||||||
|
const conference = state['features/base/conference'];
|
||||||
const media = state['features/base/media'];
|
const media = state['features/base/media'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
audioMuted: media.audio.muted,
|
audioMuted: media.audio.muted,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The indicator which determines whether the conference is
|
||||||
|
* locked/password-protected.
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
locked: conference.locked,
|
||||||
videoMuted: media.video.muted
|
videoMuted: media.video.muted
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,13 +77,13 @@ class Toolbar extends AbstractToolbar {
|
||||||
iconName = { audioButtonStyles.iconName }
|
iconName = { audioButtonStyles.iconName }
|
||||||
iconStyle = { audioButtonStyles.iconStyle }
|
iconStyle = { audioButtonStyles.iconStyle }
|
||||||
onClick = { this._toggleAudio }
|
onClick = { this._toggleAudio }
|
||||||
style = { audioButtonStyles.buttonStyle } />
|
style = { audioButtonStyles.style } />
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
iconName = 'hangup'
|
iconName = 'hangup'
|
||||||
iconStyle = { styles.whiteIcon }
|
iconStyle = { styles.whiteIcon }
|
||||||
onClick = { this._onHangup }
|
onClick = { this._onHangup }
|
||||||
style = {{
|
style = {{
|
||||||
...styles.toolbarButton,
|
...styles.primaryToolbarButton,
|
||||||
backgroundColor: ColorPalette.red
|
backgroundColor: ColorPalette.red
|
||||||
}}
|
}}
|
||||||
underlayColor = { ColorPalette.buttonUnderlay } />
|
underlayColor = { ColorPalette.buttonUnderlay } />
|
||||||
|
@ -91,7 +91,7 @@ class Toolbar extends AbstractToolbar {
|
||||||
iconName = { videoButtonStyles.iconName }
|
iconName = { videoButtonStyles.iconName }
|
||||||
iconStyle = { videoButtonStyles.iconStyle }
|
iconStyle = { videoButtonStyles.iconStyle }
|
||||||
onClick = { this._toggleVideo }
|
onClick = { this._toggleVideo }
|
||||||
style = { videoButtonStyles.buttonStyle } />
|
style = { videoButtonStyles.style } />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -106,21 +106,33 @@ class Toolbar extends AbstractToolbar {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
_renderSecondaryToolbar() {
|
_renderSecondaryToolbar() {
|
||||||
/* eslint-disable react/jsx-handler-names */
|
const iconStyle = styles.whiteIcon;
|
||||||
|
const style = styles.secondaryToolbarButton;
|
||||||
|
const underlayColor = 'transparent';
|
||||||
|
|
||||||
|
/* eslint-disable react/jsx-curly-spacing,react/jsx-handler-names */
|
||||||
|
|
||||||
// TODO Use an appropriate icon for toggle camera facing mode.
|
// TODO Use an appropriate icon for toggle camera facing mode.
|
||||||
return (
|
return (
|
||||||
<View style = { styles.secondaryToolbar }>
|
<View style = { styles.secondaryToolbar }>
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
iconName = 'reload'
|
iconName = 'reload'
|
||||||
iconStyle = { styles.whiteIcon }
|
iconStyle = { iconStyle }
|
||||||
onClick = { this._toggleCameraFacingMode }
|
onClick = { this._toggleCameraFacingMode }
|
||||||
style = { styles.toggleCameraFacingModeButton }
|
style = { style }
|
||||||
underlayColor = 'transparent' />
|
underlayColor = { underlayColor } />
|
||||||
|
<ToolbarButton
|
||||||
|
iconName = {
|
||||||
|
this.props.locked ? 'security-locked' : 'security'
|
||||||
|
}
|
||||||
|
iconStyle = { iconStyle }
|
||||||
|
onClick = { this._toggleLock }
|
||||||
|
style = { style }
|
||||||
|
underlayColor = { underlayColor } />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
/* eslint-enable react/jsx-handler-names */
|
/* eslint-enable react/jsx-curly-spacing,react/jsx-handler-names */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,35 +1,23 @@
|
||||||
import { ColorPalette, createStyleSheet } from '../../base/styles';
|
import { BoxModel, ColorPalette, createStyleSheet } from '../../base/styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic styles for a button.
|
* The base style for (toolbar) buttons.
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
const button = {
|
const button = {
|
||||||
alignSelf: 'center',
|
|
||||||
borderRadius: 35,
|
borderRadius: 35,
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
|
flex: 0,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
height: 60,
|
height: 60,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
margin: BoxModel.margin,
|
||||||
width: 60
|
width: 60
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic container for buttons.
|
* The base style for icons.
|
||||||
*
|
|
||||||
* @type {Object}
|
|
||||||
*/
|
|
||||||
const container = {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: 'row',
|
|
||||||
left: 0,
|
|
||||||
position: 'absolute',
|
|
||||||
right: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic styles for an icon.
|
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
|
@ -39,28 +27,45 @@ const icon = {
|
||||||
fontSize: 24
|
fontSize: 24
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base style for toolbars.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
const toolbar = {
|
||||||
|
flex: 1,
|
||||||
|
position: 'absolute'
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The (conference) toolbar related styles.
|
* The (conference) toolbar related styles.
|
||||||
* TODO Make styles more generic and reusable. Use ColorPalette for all colors.
|
|
||||||
*/
|
*/
|
||||||
export const styles = createStyleSheet({
|
export const styles = createStyleSheet({
|
||||||
/**
|
/**
|
||||||
* The toolbar button icon style.
|
* The toolbar button icon style.
|
||||||
*/
|
*/
|
||||||
icon: {
|
icon,
|
||||||
...icon,
|
|
||||||
color: ColorPalette.darkGrey
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The style of the toolbar which contains the primary buttons such as
|
* The style of the toolbar which contains the primary buttons such as
|
||||||
* hangup, audio and video mute.
|
* hangup, audio and video mute.
|
||||||
*/
|
*/
|
||||||
primaryToolbar: {
|
primaryToolbar: {
|
||||||
...container,
|
...toolbar,
|
||||||
bottom: 30,
|
bottom: 3 * BoxModel.margin,
|
||||||
height: 60,
|
flexDirection: 'row',
|
||||||
justifyContent: 'center'
|
justifyContent: 'center',
|
||||||
|
left: 0,
|
||||||
|
right: 0
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The style of button in primaryToolbar.
|
||||||
|
*/
|
||||||
|
primaryToolbarButton: {
|
||||||
|
...button,
|
||||||
|
backgroundColor: ColorPalette.white,
|
||||||
|
opacity: 0.8
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,36 +73,29 @@ export const styles = createStyleSheet({
|
||||||
* toggle camera facing mode.
|
* toggle camera facing mode.
|
||||||
*/
|
*/
|
||||||
secondaryToolbar: {
|
secondaryToolbar: {
|
||||||
...container,
|
...toolbar,
|
||||||
height: 60,
|
bottom: 0,
|
||||||
justifyContent: 'flex-end'
|
flexDirection: 'column',
|
||||||
|
right: 0,
|
||||||
|
top: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The toggle camera facing mode button style.
|
* The style of button in secondaryToolbar.
|
||||||
*/
|
*/
|
||||||
toggleCameraFacingModeButton: {
|
secondaryToolbarButton: {
|
||||||
...button,
|
...button,
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent'
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The toolbar button style.
|
* The style of the root/top-level Container of Toolbar.
|
||||||
*/
|
|
||||||
toolbarButton: {
|
|
||||||
...button,
|
|
||||||
backgroundColor: ColorPalette.white,
|
|
||||||
marginLeft: 20,
|
|
||||||
marginRight: 20,
|
|
||||||
opacity: 0.8
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The toolbar container style.
|
|
||||||
*/
|
*/
|
||||||
toolbarContainer: {
|
toolbarContainer: {
|
||||||
...container,
|
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
position: 'absolute',
|
||||||
|
right: 0,
|
||||||
top: 0
|
top: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue