mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-08 15:50:21 +00:00
Compare commits
15 Commits
3988
...
android-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e51819d7f | ||
|
|
ddf69160e5 | ||
|
|
34d8cd8c15 | ||
|
|
c46a646da3 | ||
|
|
8f87240ad2 | ||
|
|
fe0ab4eb0f | ||
|
|
715c7b3826 | ||
|
|
de8c679e83 | ||
|
|
d8da56d85d | ||
|
|
b706972acb | ||
|
|
5574221044 | ||
|
|
0f4369a9a9 | ||
|
|
0c2e13a453 | ||
|
|
2f817b6633 | ||
|
|
678ed605d7 |
@@ -20,5 +20,5 @@
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
appVersion=20.2.0
|
||||
appVersion=20.2.3
|
||||
sdkVersion=2.8.0
|
||||
|
||||
@@ -586,4 +586,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: f615794fb9184757b00cd16e534824ba6ee2fc98
|
||||
|
||||
COCOAPODS: 1.8.4
|
||||
COCOAPODS: 1.9.1
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>20.2.0</string>
|
||||
<string>20.2.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>20.2.0</string>
|
||||
<string>20.2.3</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>20.2.0</string>
|
||||
<string>20.2.3</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@@ -10883,8 +10883,8 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "github:jitsi/lib-jitsi-meet#960eea3c5087ce07e9135fad70268c7d338e0de5",
|
||||
"from": "github:jitsi/lib-jitsi-meet#960eea3c5087ce07e9135fad70268c7d338e0de5",
|
||||
"version": "github:jitsi/lib-jitsi-meet#d2155878aae350f82b83c491bffd69f94711e1ae",
|
||||
"from": "github:jitsi/lib-jitsi-meet#d2155878aae350f82b83c491bffd69f94711e1ae",
|
||||
"requires": {
|
||||
"@jitsi/sdp-interop": "0.1.14",
|
||||
"@jitsi/sdp-simulcast": "0.2.2",
|
||||
@@ -10896,7 +10896,7 @@
|
||||
"sdp-transform": "2.3.0",
|
||||
"strophe.js": "1.3.4",
|
||||
"strophejs-plugin-disco": "0.0.2",
|
||||
"strophejs-plugin-stream-management": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009",
|
||||
"strophejs-plugin-stream-management": "github:jitsi/strophejs-plugin-stream-management#e719a02b4f83856c1530882084a4b048ee622d45",
|
||||
"webrtc-adapter": "7.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -16879,8 +16879,8 @@
|
||||
"integrity": "sha512-T9pJFzn1ZUqZ/we9+OvI5pFdrjeb4IBMbEjK+ZWEZV036wEl8l8GOtF8AJ3sIqOMtdIiFLdFu99JiGWd7yapAQ=="
|
||||
},
|
||||
"strophejs-plugin-stream-management": {
|
||||
"version": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009",
|
||||
"from": "github:jitsi/strophejs-plugin-stream-management#cec7608601c1bc098543823fc658e3ddf758c009"
|
||||
"version": "github:jitsi/strophejs-plugin-stream-management#e719a02b4f83856c1530882084a4b048ee622d45",
|
||||
"from": "github:jitsi/strophejs-plugin-stream-management#e719a02b4f83856c1530882084a4b048ee622d45"
|
||||
},
|
||||
"style-loader": {
|
||||
"version": "0.19.0",
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"js-utils": "github:jitsi/js-utils#0b2cef90613a74777fefd98d4ee3eda3879809ab",
|
||||
"jsrsasign": "8.0.12",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#960eea3c5087ce07e9135fad70268c7d338e0de5",
|
||||
"lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#d2155878aae350f82b83c491bffd69f94711e1ae",
|
||||
"libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lodash": "4.17.13",
|
||||
"moment": "2.19.4",
|
||||
|
||||
@@ -89,22 +89,10 @@ export class AbstractApp extends BaseApp<Props, *> {
|
||||
return (
|
||||
<Fragment>
|
||||
<OverlayContainer />
|
||||
{ this._createExtraPlatformSpecificElement() }
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders platform specific extra elements to be added alongside with the main element, if need be.
|
||||
*
|
||||
* NOTE: Overridden by child components.
|
||||
*
|
||||
* @returns {React$Element}
|
||||
*/
|
||||
_createExtraPlatformSpecificElement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
_createMainElement: (React$Element<*>, Object) => ?React$Element<*>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,6 @@ import { Platform } from '../../base/react';
|
||||
import '../../base/responsive-ui';
|
||||
import { updateSettings } from '../../base/settings';
|
||||
import '../../google-api';
|
||||
import { HelpView } from '../../help';
|
||||
import '../../mobile/audio-mode';
|
||||
import '../../mobile/back-button';
|
||||
import '../../mobile/background';
|
||||
@@ -108,17 +107,6 @@ export class App extends AbstractApp {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders platform specific extra elements to be added alongside with the main element, if need be.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
_createExtraPlatformSpecificElement() {
|
||||
return (
|
||||
<HelpView />
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to disable the use of React Native
|
||||
* {@link ExceptionsManager#handleException} on platforms and in
|
||||
|
||||
@@ -87,6 +87,7 @@ export default [
|
||||
'disableDeepLinking',
|
||||
'disableH264',
|
||||
'disableHPF',
|
||||
'disableInviteFunctions',
|
||||
'disableLocalVideoFlip',
|
||||
'disableNS',
|
||||
'disableRemoteControl',
|
||||
@@ -95,6 +96,7 @@ export default [
|
||||
'disableSuspendVideo',
|
||||
'disableThirdPartyRequests',
|
||||
'displayJids',
|
||||
'doNotStoreRoom',
|
||||
'e2eping',
|
||||
'enableDisplayNameInStats',
|
||||
'enableEmailInStats',
|
||||
|
||||
@@ -6,14 +6,16 @@ import { SET_ACTIVE_MODAL_ID } from './actionTypes';
|
||||
* Action to set the ID of the active modal (or undefined if needs to be hidden).
|
||||
*
|
||||
* @param {string} activeModalId - The new modal ID or undefined.
|
||||
* @param {Object} modalProps - The props to pass to the modal.
|
||||
* @returns {{
|
||||
* activeModalId: string,
|
||||
* type: SET_ACTIVE_MODAL_ID
|
||||
* }}
|
||||
*/
|
||||
export function setActiveModalId(activeModalId: ?string) {
|
||||
export function setActiveModalId(activeModalId: ?string, modalProps: Object = {}) {
|
||||
return {
|
||||
activeModalId,
|
||||
modalProps,
|
||||
type: SET_ACTIVE_MODAL_ID
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { SafeAreaView, View } from 'react-native';
|
||||
import { KeyboardAvoidingView, SafeAreaView } from 'react-native';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../color-scheme';
|
||||
import { HeaderWithNavigation, SlidingView } from '../../react';
|
||||
@@ -40,9 +40,16 @@ type Props = {
|
||||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* The i18n label key of the header title.
|
||||
* Optional function that renders a footer component, if needed.
|
||||
*/
|
||||
headerLabelKey: string,
|
||||
footerComponent?: Function,
|
||||
|
||||
/**
|
||||
* Props to be passed over to the header.
|
||||
*
|
||||
* See {@code HeaderWithNavigation} for more details.
|
||||
*/
|
||||
headerProps: Object,
|
||||
|
||||
/**
|
||||
* The ID of the modal that is being rendered. This is used to show/hide the modal.
|
||||
@@ -58,7 +65,12 @@ type Props = {
|
||||
* The position from where the modal should be opened. This is derived from the
|
||||
* props of the {@code SlidingView} with the same name.
|
||||
*/
|
||||
position?: string
|
||||
position?: string,
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the View containing the content of the modal.
|
||||
*/
|
||||
style?: StyleType
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -87,25 +99,28 @@ class JitsiModal extends PureComponent<Props> {
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { _headerStyles, _show, _styles, children, headerLabelKey, position } = this.props;
|
||||
const { _headerStyles, _show, _styles, children, footerComponent, headerProps, position, style } = this.props;
|
||||
|
||||
return (
|
||||
<SlidingView
|
||||
onHide = { this._onRequestClose }
|
||||
position = { position }
|
||||
show = { _show }>
|
||||
<View
|
||||
<KeyboardAvoidingView
|
||||
behavior = 'height'
|
||||
style = { [
|
||||
_headerStyles.page,
|
||||
_styles.page
|
||||
_styles.page,
|
||||
style
|
||||
] }>
|
||||
<HeaderWithNavigation
|
||||
headerLabelKey = { headerLabelKey }
|
||||
{ ...headerProps }
|
||||
onPressBack = { this._onRequestClose } />
|
||||
<SafeAreaView style = { styles.safeArea }>
|
||||
{ children }
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
{ footerComponent && footerComponent() }
|
||||
</KeyboardAvoidingView>
|
||||
</SlidingView>
|
||||
);
|
||||
}
|
||||
@@ -119,14 +134,15 @@ class JitsiModal extends PureComponent<Props> {
|
||||
*/
|
||||
_onRequestClose() {
|
||||
const { _show, dispatch, onClose } = this.props;
|
||||
let shouldCloseModal = true;
|
||||
|
||||
if (_show) {
|
||||
if (typeof onClose === 'function') {
|
||||
onClose();
|
||||
shouldCloseModal = onClose();
|
||||
}
|
||||
dispatch(setActiveModalId());
|
||||
shouldCloseModal && dispatch(setActiveModalId());
|
||||
|
||||
return true;
|
||||
return shouldCloseModal;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -10,6 +10,7 @@ export default {
|
||||
|
||||
ColorSchemeRegistry.register('Modal', {
|
||||
page: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: schemeColor('background')
|
||||
}
|
||||
});
|
||||
|
||||
@@ -9,7 +9,8 @@ ReducerRegistry.register('features/base/modal', (state = {}, action) => {
|
||||
case SET_ACTIVE_MODAL_ID:
|
||||
return {
|
||||
...state,
|
||||
activeModalId: action.activeModalId
|
||||
activeModalId: action.activeModalId,
|
||||
modalProps: action.modalProps
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -137,8 +137,9 @@ function _updateLocalParticipantFromUrl({ dispatch, getState }) {
|
||||
const urlParams
|
||||
= parseURLParams(getState()['features/base/connection'].locationURL);
|
||||
const urlEmail = urlParams['userInfo.email'];
|
||||
const urlDisplayName = urlParams['userInfo.displayName'];
|
||||
|
||||
if (!urlEmail) {
|
||||
if (!urlEmail && !urlDisplayName) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,7 +148,8 @@ function _updateLocalParticipantFromUrl({ dispatch, getState }) {
|
||||
if (localParticipant) {
|
||||
dispatch(participantUpdated({
|
||||
...localParticipant,
|
||||
email: _.escape(urlEmail)
|
||||
email: _.escape(urlEmail),
|
||||
name: _.escape(urlDisplayName)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { KeyboardAvoidingView } from 'react-native';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
@@ -18,7 +17,6 @@ import AbstractChat, {
|
||||
import ChatInputBar from './ChatInputBar';
|
||||
import MessageContainer from './MessageContainer';
|
||||
import MessageRecipient from './MessageRecipient';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* Implements a React native component that renders the chat window (modal) of
|
||||
@@ -33,15 +31,13 @@ class Chat extends AbstractChat<Props> {
|
||||
render() {
|
||||
return (
|
||||
<JitsiModal
|
||||
headerLabelKey = 'chat.title'
|
||||
headerProps = {{
|
||||
headerLabelKey: 'chat.title'
|
||||
}}
|
||||
modalId = { CHAT_VIEW_MODAL_ID }>
|
||||
<KeyboardAvoidingView
|
||||
behavior = 'padding'
|
||||
style = { styles.chatContainer }>
|
||||
<MessageContainer messages = { this.props._messages } />
|
||||
<MessageRecipient />
|
||||
<ChatInputBar onSend = { this.props._onSendMessage } />
|
||||
</KeyboardAvoidingView>
|
||||
<MessageContainer messages = { this.props._messages } />
|
||||
<MessageRecipient />
|
||||
<ChatInputBar onSend = { this.props._onSendMessage } />
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import { Platform, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { Icon, IconChatSend } from '../../../base/icons';
|
||||
@@ -135,7 +135,7 @@ class ChatInputBar extends Component<Props, State> {
|
||||
*/
|
||||
_onFocused(focused) {
|
||||
return () => {
|
||||
this.setState({
|
||||
Platform.OS === 'android' && this.setState({
|
||||
addPadding: focused
|
||||
});
|
||||
};
|
||||
|
||||
@@ -23,12 +23,6 @@ export default {
|
||||
width: 32
|
||||
},
|
||||
|
||||
chatContainer: {
|
||||
alignItems: 'stretch',
|
||||
flex: 1,
|
||||
flexDirection: 'column'
|
||||
},
|
||||
|
||||
chatLink: {
|
||||
color: ColorPalette.blue
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
JitsiConferenceErrors,
|
||||
JitsiConferenceEvents
|
||||
} from '../base/lib-jitsi-meet';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
@@ -22,7 +23,13 @@ import { isButtonEnabled, showToolbox } from '../toolbox';
|
||||
import { SEND_MESSAGE, SET_PRIVATE_MESSAGE_RECIPIENT } from './actionTypes';
|
||||
import { addMessage, clearMessages, toggleChat } from './actions';
|
||||
import { ChatPrivacyDialog } from './components';
|
||||
import { INCOMING_MSG_SOUND_ID, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_LOCAL, MESSAGE_TYPE_REMOTE } from './constants';
|
||||
import {
|
||||
CHAT_VIEW_MODAL_ID,
|
||||
INCOMING_MSG_SOUND_ID,
|
||||
MESSAGE_TYPE_ERROR,
|
||||
MESSAGE_TYPE_LOCAL,
|
||||
MESSAGE_TYPE_REMOTE
|
||||
} from './constants';
|
||||
import { INCOMING_MSG_SOUND_FILE } from './sounds';
|
||||
|
||||
declare var APP: Object;
|
||||
@@ -94,6 +101,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
}
|
||||
|
||||
case SET_PRIVATE_MESSAGE_RECIPIENT: {
|
||||
Boolean(action.participant) && dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
_maybeFocusField();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -213,6 +213,19 @@ class Conference extends AbstractConference<Props, *> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders JitsiModals that are supposed to be on the conference screen.
|
||||
*
|
||||
* @returns {Array<ReactElement>}
|
||||
*/
|
||||
_renderConferenceModals() {
|
||||
return [
|
||||
<AddPeopleDialog key = 'addPeopleDialog' />,
|
||||
<Chat key = 'chat' />,
|
||||
<SharedDocument key = 'sharedDocument' />
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the conference notification badge if the feature is enabled.
|
||||
*
|
||||
@@ -252,10 +265,6 @@ class Conference extends AbstractConference<Props, *> {
|
||||
|
||||
return (
|
||||
<>
|
||||
<AddPeopleDialog />
|
||||
<Chat />
|
||||
<SharedDocument />
|
||||
|
||||
{/*
|
||||
* The LargeVideo is the lowermost stacking layer.
|
||||
*/
|
||||
@@ -335,6 +344,8 @@ class Conference extends AbstractConference<Props, *> {
|
||||
<TestConnectionInfo />
|
||||
|
||||
{ this._renderConferenceNotification() }
|
||||
|
||||
{ this._renderConferenceModals() }
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@ import { Icon, IconAddPeople } from '../../../base/icons';
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* True if the invite functions (dial out, invite, share...etc) are disabled.
|
||||
*/
|
||||
_isInviteFunctionsDiabled: boolean,
|
||||
|
||||
/**
|
||||
* True if it's a lonely meeting (participant count excluding fakes is 1).
|
||||
*/
|
||||
@@ -60,7 +65,7 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { _isLonelyMeeting, _styles, t } = this.props;
|
||||
const { _isInviteFunctionsDiabled, _isLonelyMeeting, _styles, t } = this.props;
|
||||
|
||||
if (!_isLonelyMeeting) {
|
||||
return null;
|
||||
@@ -75,24 +80,26 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||
] }>
|
||||
{ t('lonelyMeetingExperience.youAreAlone') }
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onPress = { this._onPress }
|
||||
style = { [
|
||||
styles.lonelyButton,
|
||||
_styles.lonelyButton
|
||||
] }>
|
||||
<Icon
|
||||
size = { 24 }
|
||||
src = { IconAddPeople }
|
||||
style = { styles.lonelyButtonComponents } />
|
||||
<Text
|
||||
{ !_isInviteFunctionsDiabled && (
|
||||
<TouchableOpacity
|
||||
onPress = { this._onPress }
|
||||
style = { [
|
||||
styles.lonelyButtonComponents,
|
||||
_styles.lonelyMessage
|
||||
styles.lonelyButton,
|
||||
_styles.lonelyButton
|
||||
] }>
|
||||
{ t('lonelyMeetingExperience.button') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Icon
|
||||
size = { 24 }
|
||||
src = { IconAddPeople }
|
||||
style = { styles.lonelyButtonComponents } />
|
||||
<Text
|
||||
style = { [
|
||||
styles.lonelyButtonComponents,
|
||||
_styles.lonelyMessage
|
||||
] }>
|
||||
{ t('lonelyMeetingExperience.button') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
) }
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +124,10 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state): $Shape<Props> {
|
||||
const { disableInviteFunctions } = state['features/base/config'];
|
||||
|
||||
return {
|
||||
_isInviteFunctionsDiabled: disableInviteFunctions,
|
||||
_isLonelyMeeting: getParticipantCount(state) === 1,
|
||||
_styles: ColorSchemeRegistry.get(state, 'Conference')
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
setPreferredReceiverVideoQuality
|
||||
} from '../base/conference';
|
||||
import { hideDialog, isDialogOpen } from '../base/dialog';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import { pinParticipant } from '../base/participants';
|
||||
import { SET_REDUCED_UI } from '../base/responsive-ui';
|
||||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||
@@ -84,5 +85,8 @@ StateListenerRegistry.register(
|
||||
// dialog we might have open.
|
||||
dispatch(hideDialog());
|
||||
}
|
||||
|
||||
// We want to close all modals.
|
||||
dispatch(setActiveModalId());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { SafeAreaView, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { WebView } from 'react-native-webview';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { HeaderWithNavigation, LoadingIndicator, SlidingView } from '../../../base/react';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
import { LoadingIndicator } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
|
||||
import { toggleDocument } from '../../actions';
|
||||
import { SHARE_DOCUMENT_VIEW_ID } from '../../constants';
|
||||
import { getSharedDocumentUrl } from '../../functions';
|
||||
|
||||
import styles, { INDICATOR_COLOR } from './styles';
|
||||
@@ -69,42 +71,24 @@ class SharedDocument extends PureComponent<Props> {
|
||||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { _documentUrl, _isOpen } = this.props;
|
||||
const webViewStyles = this._getWebViewStyles();
|
||||
const { _documentUrl } = this.props;
|
||||
|
||||
return (
|
||||
<SlidingView
|
||||
onHide = { this._onClose }
|
||||
position = 'bottom'
|
||||
show = { _isOpen } >
|
||||
<View style = { styles.webViewWrapper }>
|
||||
<HeaderWithNavigation
|
||||
headerLabelKey = 'documentSharing.title'
|
||||
onPressBack = { this._onClose } />
|
||||
<SafeAreaView style = { webViewStyles }>
|
||||
<WebView
|
||||
onError = { this._onError }
|
||||
renderLoading = { this._renderLoading }
|
||||
source = {{ uri: _documentUrl }}
|
||||
startInLoadingState = { true } />
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
</SlidingView>
|
||||
<JitsiModal
|
||||
headerProps = {{
|
||||
headerLabelKey: 'documentSharing.title'
|
||||
}}
|
||||
modalId = { SHARE_DOCUMENT_VIEW_ID }
|
||||
style = { styles.webView }>
|
||||
<WebView
|
||||
onError = { this._onError }
|
||||
renderLoading = { this._renderLoading }
|
||||
source = {{ uri: _documentUrl }}
|
||||
startInLoadingState = { true } />
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the styles required for the WebView component.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getWebViewStyles() {
|
||||
return {
|
||||
...styles.webView,
|
||||
backgroundColor: this.props._headerStyles.screenHeader.backgroundColor
|
||||
};
|
||||
}
|
||||
|
||||
_onClose: () => boolean
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,11 +14,6 @@ export default {
|
||||
},
|
||||
|
||||
webView: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
webViewWrapper: {
|
||||
flex: 1,
|
||||
flexDirection: 'column'
|
||||
backgroundColor: 'rgb(242, 242, 242)'
|
||||
}
|
||||
};
|
||||
|
||||
4
react/features/etherpad/constants.js
Normal file
4
react/features/etherpad/constants.js
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Modal view ID of the SharedDocument view.
|
||||
*/
|
||||
export const SHARE_DOCUMENT_VIEW_ID = 'SHARE_DOCUMENT_VIEW_ID';
|
||||
@@ -1,6 +1,7 @@
|
||||
export * from './actions';
|
||||
export * from './actionTypes';
|
||||
export * from './components';
|
||||
export * from './constants';
|
||||
export * from './functions';
|
||||
|
||||
import './middleware';
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// @flow
|
||||
|
||||
import { getCurrentConference } from '../base/conference';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||
import UIEvents from '../../../service/UI/UIEvents';
|
||||
|
||||
import { TOGGLE_DOCUMENT_EDITING } from './actionTypes';
|
||||
import { setDocumentEditingState, setDocumentUrl } from './actions';
|
||||
import { SHARE_DOCUMENT_VIEW_ID } from './constants';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
@@ -23,9 +25,15 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
switch (action.type) {
|
||||
case TOGGLE_DOCUMENT_EDITING: {
|
||||
if (typeof APP === 'undefined') {
|
||||
const { editing } = getState()['features/etherpad'];
|
||||
const editing = !getState()['features/etherpad'].editing;
|
||||
|
||||
dispatch(setDocumentEditingState(!editing));
|
||||
dispatch(setDocumentEditingState(editing));
|
||||
|
||||
if (editing) {
|
||||
dispatch(setActiveModalId(SHARE_DOCUMENT_VIEW_ID));
|
||||
} else if (getState()['features/base/modal'].activeModalId === SHARE_DOCUMENT_VIEW_ID) {
|
||||
dispatch(setActiveModalId(undefined));
|
||||
}
|
||||
} else {
|
||||
APP.UI.emitEvent(UIEvents.ETHERPAD_CLICKED);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ class HelpView extends PureComponent<Props> {
|
||||
render() {
|
||||
return (
|
||||
<JitsiModal
|
||||
headerLabelKey = 'helpView.header'
|
||||
headerProps = {{
|
||||
headerLabelKey: 'helpView.header'
|
||||
}}
|
||||
modalId = { HELP_VIEW_MODAL_ID }>
|
||||
<WebView source = {{ uri: this.props._url }} />
|
||||
</JitsiModal>
|
||||
|
||||
@@ -41,26 +41,6 @@ export const REMOVE_PENDING_INVITE_REQUESTS
|
||||
*/
|
||||
export const SET_CALLEE_INFO_VISIBLE = 'SET_CALLEE_INFO_VISIBLE';
|
||||
|
||||
/**
|
||||
* The type of Redux action to set the visibility of the dial in summary.
|
||||
*
|
||||
* {
|
||||
* type: SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||
* visible: boolean
|
||||
* }
|
||||
*/
|
||||
export const SET_DIAL_IN_SUMMARY_VISIBLE = 'SET_DIAL_IN_SUMMARY_VISIBLE';
|
||||
|
||||
/**
|
||||
* The type of redux action which sets the invite dialog visible or invisible.
|
||||
*
|
||||
* {
|
||||
* type: SET_INVITE_DIALOG_VISIBLE,
|
||||
* visible: boolean
|
||||
* }
|
||||
*/
|
||||
export const SET_INVITE_DIALOG_VISIBLE = 'SET_INVITE_DIALOG_VISIBLE';
|
||||
|
||||
/**
|
||||
* The type of the action which signals an error occurred while requesting dial-
|
||||
* in numbers.
|
||||
|
||||
@@ -11,8 +11,6 @@ import {
|
||||
BEGIN_ADD_PEOPLE,
|
||||
REMOVE_PENDING_INVITE_REQUESTS,
|
||||
SET_CALLEE_INFO_VISIBLE,
|
||||
SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||
SET_INVITE_DIALOG_VISIBLE,
|
||||
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
||||
UPDATE_DIAL_IN_NUMBERS_SUCCESS
|
||||
} from './actionTypes';
|
||||
@@ -200,22 +198,6 @@ export function updateDialInNumbers() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of the invite dialog.
|
||||
*
|
||||
* @param {boolean} visible - The visibility to set.
|
||||
* @returns {{
|
||||
* type: SET_INVITE_DIALOG_VISIBLE,
|
||||
* visible: boolean
|
||||
* }}
|
||||
*/
|
||||
export function setAddPeopleDialogVisible(visible: boolean) {
|
||||
return {
|
||||
type: SET_INVITE_DIALOG_VISIBLE,
|
||||
visible
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of {@code CalleeInfo}.
|
||||
*
|
||||
@@ -256,15 +238,6 @@ export function addPendingInviteRequest(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to hide the dial in summary.
|
||||
*
|
||||
* @returns {showDialInSummary}
|
||||
*/
|
||||
export function hideDialInSummary() {
|
||||
return showDialInSummary(undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all pending invite requests.
|
||||
*
|
||||
@@ -277,19 +250,3 @@ export function removePendingInviteRequests() {
|
||||
type: REMOVE_PENDING_INVITE_REQUESTS
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to set the dial in summary url (and show it).
|
||||
*
|
||||
* @param {?string} locationUrl - The location URL to show the dial in summary for.
|
||||
* @returns {{
|
||||
* type: SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||
* summaryUrl: ?string
|
||||
* }}
|
||||
*/
|
||||
export function showDialInSummary(locationUrl: ?string) {
|
||||
return {
|
||||
type: SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||
summaryUrl: locationUrl
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { getFeatureFlag, INVITE_ENABLED } from '../base/flags';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import { beginShareRoom } from '../share-room';
|
||||
|
||||
import { setAddPeopleDialogVisible } from './actions.any';
|
||||
import { isAddPeopleEnabled, isDialOutEnabled } from './functions';
|
||||
import { ADD_PEOPLE_DIALOG_VIEW_ID } from './constants';
|
||||
|
||||
export * from './actions.any';
|
||||
|
||||
@@ -23,7 +24,7 @@ export function doInvitePeople() {
|
||||
&& (isAddPeopleEnabled(state) || isDialOutEnabled(state));
|
||||
|
||||
if (addPeopleEnabled) {
|
||||
return dispatch(setAddPeopleDialogVisible(true));
|
||||
return dispatch(setActiveModalId(ADD_PEOPLE_DIALOG_VIEW_ID));
|
||||
}
|
||||
|
||||
return dispatch(beginShareRoom());
|
||||
|
||||
@@ -5,7 +5,6 @@ import React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
FlatList,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
SafeAreaView,
|
||||
TextInput,
|
||||
@@ -25,16 +24,15 @@ import {
|
||||
IconSearch,
|
||||
IconShare
|
||||
} from '../../../../base/icons';
|
||||
import { JitsiModal, setActiveModalId } from '../../../../base/modal';
|
||||
import {
|
||||
AvatarListItem,
|
||||
HeaderWithNavigation,
|
||||
SlidingView,
|
||||
type Item
|
||||
} from '../../../../base/react';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import { beginShareRoom } from '../../../../share-room';
|
||||
|
||||
import { setAddPeopleDialogVisible } from '../../../actions.native';
|
||||
import { ADD_PEOPLE_DIALOG_VIEW_ID } from '../../../constants';
|
||||
|
||||
import AbstractAddPeopleDialog, {
|
||||
type Props as AbstractProps,
|
||||
@@ -131,11 +129,11 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
this._renderItem = this._renderItem.bind(this);
|
||||
this._renderSeparator = this._renderSeparator.bind(this);
|
||||
this._onClearField = this._onClearField.bind(this);
|
||||
this._onCloseAddPeopleDialog = this._onCloseAddPeopleDialog.bind(this);
|
||||
this._onInvite = this._onInvite.bind(this);
|
||||
this._onPressItem = this._onPressItem.bind(this);
|
||||
this._onShareMeeting = this._onShareMeeting.bind(this);
|
||||
this._onTypeQuery = this._onTypeQuery.bind(this);
|
||||
this._renderShareMeetingButton = this._renderShareMeetingButton.bind(this);
|
||||
this._setFieldRef = this._setFieldRef.bind(this);
|
||||
}
|
||||
|
||||
@@ -159,8 +157,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
render() {
|
||||
const {
|
||||
_addPeopleEnabled,
|
||||
_dialOutEnabled,
|
||||
_headerStyles
|
||||
_dialOutEnabled
|
||||
} = this.props;
|
||||
const { inviteItems, selectableItems } = this.state;
|
||||
|
||||
@@ -173,72 +170,58 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
}
|
||||
|
||||
return (
|
||||
<SlidingView
|
||||
onHide = { this._onCloseAddPeopleDialog }
|
||||
position = 'bottom'
|
||||
show = { this.props._isVisible } >
|
||||
<HeaderWithNavigation
|
||||
forwardDisabled = { this._isAddDisabled() }
|
||||
forwardLabelKey = 'inviteDialog.send'
|
||||
headerLabelKey = 'inviteDialog.header'
|
||||
onPressBack = { this._onCloseAddPeopleDialog }
|
||||
onPressForward = { this._onInvite } />
|
||||
<KeyboardAvoidingView
|
||||
behavior = 'padding'
|
||||
style = { styles.avoidingView }>
|
||||
<SafeAreaView style = { styles.dialogWrapper }>
|
||||
<View
|
||||
style = { styles.searchFieldWrapper }>
|
||||
<View style = { styles.searchIconWrapper }>
|
||||
{ this.state.searchInprogress
|
||||
? <ActivityIndicator
|
||||
color = { DARK_GREY }
|
||||
size = 'small' />
|
||||
: <Icon
|
||||
src = { IconSearch }
|
||||
style = { styles.searchIcon } />}
|
||||
</View>
|
||||
<TextInput
|
||||
autoCorrect = { false }
|
||||
autoFocus = { false }
|
||||
onBlur = { this._onFocused(false) }
|
||||
onChangeText = { this._onTypeQuery }
|
||||
onFocus = { this._onFocused(true) }
|
||||
placeholder = {
|
||||
this.props.t(`inviteDialog.${placeholderKey}`)
|
||||
}
|
||||
ref = { this._setFieldRef }
|
||||
style = { styles.searchField }
|
||||
value = { this.state.fieldValue } />
|
||||
{ this._renderClearButton() }
|
||||
</View>
|
||||
{ Boolean(inviteItems.length) && <View style = { styles.invitedList }>
|
||||
<FlatList
|
||||
data = { inviteItems }
|
||||
horizontal = { true }
|
||||
keyExtractor = { this._keyExtractor }
|
||||
keyboardShouldPersistTaps = 'always'
|
||||
renderItem = { this._renderInvitedItem } />
|
||||
</View> }
|
||||
<View style = { styles.resultList }>
|
||||
<FlatList
|
||||
ItemSeparatorComponent = { this._renderSeparator }
|
||||
data = { selectableItems }
|
||||
extraData = { inviteItems }
|
||||
keyExtractor = { this._keyExtractor }
|
||||
keyboardShouldPersistTaps = 'always'
|
||||
renderItem = { this._renderItem } />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
<SafeAreaView
|
||||
style = { [
|
||||
styles.bottomBar,
|
||||
_headerStyles.headerOverlay,
|
||||
this.state.bottomPadding ? styles.extraBarPadding : null ] }>
|
||||
{ this._renderShareMeetingButton() }
|
||||
</SafeAreaView>
|
||||
</KeyboardAvoidingView>
|
||||
</SlidingView>
|
||||
<JitsiModal
|
||||
footerComponent = { this._renderShareMeetingButton }
|
||||
headerProps = {{
|
||||
forwardDisabled: this._isAddDisabled(),
|
||||
forwardLabelKey: 'inviteDialog.send',
|
||||
headerLabelKey: 'inviteDialog.header',
|
||||
onPressForward: this._onInvite
|
||||
}}
|
||||
modalId = { ADD_PEOPLE_DIALOG_VIEW_ID }>
|
||||
<View
|
||||
style = { styles.searchFieldWrapper }>
|
||||
<View style = { styles.searchIconWrapper }>
|
||||
{ this.state.searchInprogress
|
||||
? <ActivityIndicator
|
||||
color = { DARK_GREY }
|
||||
size = 'small' />
|
||||
: <Icon
|
||||
src = { IconSearch }
|
||||
style = { styles.searchIcon } />}
|
||||
</View>
|
||||
<TextInput
|
||||
autoCorrect = { false }
|
||||
autoFocus = { false }
|
||||
onBlur = { this._onFocused(false) }
|
||||
onChangeText = { this._onTypeQuery }
|
||||
onFocus = { this._onFocused(true) }
|
||||
placeholder = {
|
||||
this.props.t(`inviteDialog.${placeholderKey}`)
|
||||
}
|
||||
ref = { this._setFieldRef }
|
||||
style = { styles.searchField }
|
||||
value = { this.state.fieldValue } />
|
||||
{ this._renderClearButton() }
|
||||
</View>
|
||||
{ Boolean(inviteItems.length) && <View style = { styles.invitedList }>
|
||||
<FlatList
|
||||
data = { inviteItems }
|
||||
horizontal = { true }
|
||||
keyExtractor = { this._keyExtractor }
|
||||
keyboardShouldPersistTaps = 'always'
|
||||
renderItem = { this._renderInvitedItem } />
|
||||
</View> }
|
||||
<View style = { styles.resultList }>
|
||||
<FlatList
|
||||
ItemSeparatorComponent = { this._renderSeparator }
|
||||
data = { selectableItems }
|
||||
extraData = { inviteItems }
|
||||
keyExtractor = { this._keyExtractor }
|
||||
keyboardShouldPersistTaps = 'always'
|
||||
renderItem = { this._renderItem } />
|
||||
</View>
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -311,23 +294,6 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
this._onTypeQuery('');
|
||||
}
|
||||
|
||||
_onCloseAddPeopleDialog: () => boolean
|
||||
|
||||
/**
|
||||
* Closes the dialog.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onCloseAddPeopleDialog() {
|
||||
if (this.props._isVisible) {
|
||||
this.props.dispatch(setAddPeopleDialogVisible(false));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_onFocused: boolean => Function;
|
||||
|
||||
/**
|
||||
@@ -360,7 +326,7 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
});
|
||||
this._showFailedInviteAlert();
|
||||
} else {
|
||||
this._onCloseAddPeopleDialog();
|
||||
this.props.dispatch(setActiveModalId());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -587,6 +553,8 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
_renderShareMeetingButton: () => React$Element<any>;
|
||||
|
||||
/**
|
||||
* Renders a button to share the meeting info.
|
||||
*
|
||||
@@ -596,12 +564,19 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
|
||||
const { _headerStyles } = this.props;
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress = { this._onShareMeeting }>
|
||||
<Icon
|
||||
src = { IconShare }
|
||||
style = { [ _headerStyles.headerButtonText, styles.shareIcon ] } />
|
||||
</TouchableOpacity>
|
||||
<SafeAreaView
|
||||
style = { [
|
||||
styles.bottomBar,
|
||||
_headerStyles.headerOverlay,
|
||||
this.state.bottomPadding ? styles.extraBarPadding : null
|
||||
] }>
|
||||
<TouchableOpacity
|
||||
onPress = { this._onShareMeeting }>
|
||||
<Icon
|
||||
src = { IconShare }
|
||||
style = { [ _headerStyles.headerButtonText, styles.shareIcon ] } />
|
||||
</TouchableOpacity>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -647,7 +622,7 @@ function _mapStateToProps(state: Object) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header'),
|
||||
_isVisible: state['features/invite'].inviteDialogVisible
|
||||
_isVisible: state['features/base/modal'].activeModalId === ADD_PEOPLE_DIALOG_VIEW_ID
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -38,5 +38,20 @@ class InviteButton extends AbstractButton<Props, *> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @param {Props} ownProps - The own props of the component.
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state, ownProps: Props) {
|
||||
const { disableInviteFunctions } = state['features/base/config'];
|
||||
|
||||
export default translate(connect()(InviteButton));
|
||||
return {
|
||||
visible: !disableInviteFunctions && ownProps.visible
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default translate(connect(_mapStateToProps)(InviteButton));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
|
||||
import { BoxModel, ColorPalette } from '../../../../base/styles';
|
||||
import { BoxModel } from '../../../../base/styles';
|
||||
|
||||
export const AVATAR_SIZE = 40;
|
||||
export const DARK_GREY = 'rgb(28, 32, 37)';
|
||||
@@ -19,10 +19,6 @@ export default {
|
||||
fontSize: 12
|
||||
},
|
||||
|
||||
avoidingView: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
bottomBar: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
@@ -50,14 +46,6 @@ export default {
|
||||
width: 24
|
||||
},
|
||||
|
||||
dialogWrapper: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: ColorPalette.white,
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-start'
|
||||
},
|
||||
|
||||
/**
|
||||
* A special padding to avoid issues on some devices (such as Android devices with custom suggestions bar).
|
||||
*/
|
||||
|
||||
@@ -7,14 +7,11 @@ import { type Dispatch } from 'redux';
|
||||
|
||||
import { openDialog } from '../../../../base/dialog';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import {
|
||||
HeaderWithNavigation,
|
||||
LoadingIndicator,
|
||||
SlidingView
|
||||
} from '../../../../base/react';
|
||||
import { JitsiModal, setActiveModalId } from '../../../../base/modal';
|
||||
import { LoadingIndicator } from '../../../../base/react';
|
||||
import { connect } from '../../../../base/redux';
|
||||
|
||||
import { hideDialInSummary } from '../../../actions';
|
||||
import { DIAL_IN_SUMMARY_VIEW_ID } from '../../../constants';
|
||||
import { getDialInfoPageURLForURIString } from '../../../functions';
|
||||
|
||||
import DialInSummaryErrorDialog from './DialInSummaryErrorDialog';
|
||||
@@ -43,7 +40,6 @@ class DialInSummary extends Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this._onCloseView = this._onCloseView.bind(this);
|
||||
this._onError = this._onError.bind(this);
|
||||
this._onNavigate = this._onNavigate.bind(this);
|
||||
this._renderLoading = this._renderLoading.bind(this);
|
||||
@@ -58,43 +54,23 @@ class DialInSummary extends Component<Props> {
|
||||
const { _summaryUrl } = this.props;
|
||||
|
||||
return (
|
||||
<SlidingView
|
||||
onHide = { this._onCloseView }
|
||||
position = 'bottom'
|
||||
show = { Boolean(_summaryUrl) } >
|
||||
<View style = { styles.webViewWrapper }>
|
||||
<HeaderWithNavigation
|
||||
headerLabelKey = 'info.label'
|
||||
onPressBack = { this._onCloseView } />
|
||||
<WebView
|
||||
onError = { this._onError }
|
||||
onShouldStartLoadWithRequest = { this._onNavigate }
|
||||
renderLoading = { this._renderLoading }
|
||||
source = {{ uri: getDialInfoPageURLForURIString(_summaryUrl) }}
|
||||
startInLoadingState = { true }
|
||||
style = { styles.webView } />
|
||||
</View>
|
||||
</SlidingView>
|
||||
<JitsiModal
|
||||
headerProps = {{
|
||||
headerLabelKey: 'info.label'
|
||||
}}
|
||||
modalId = { DIAL_IN_SUMMARY_VIEW_ID }
|
||||
style = { styles.backDrop } >
|
||||
<WebView
|
||||
onError = { this._onError }
|
||||
onShouldStartLoadWithRequest = { this._onNavigate }
|
||||
renderLoading = { this._renderLoading }
|
||||
source = {{ uri: getDialInfoPageURLForURIString(_summaryUrl) }}
|
||||
startInLoadingState = { true }
|
||||
style = { styles.webView } />
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
_onCloseView: () => boolean;
|
||||
|
||||
/**
|
||||
* Closes the view.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_onCloseView() {
|
||||
if (this.props._summaryUrl) {
|
||||
this.props.dispatch(hideDialInSummary());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_onError: () => void;
|
||||
|
||||
/**
|
||||
@@ -103,7 +79,7 @@ class DialInSummary extends Component<Props> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onError() {
|
||||
this.props.dispatch(hideDialInSummary());
|
||||
this.props.dispatch(setActiveModalId());
|
||||
this.props.dispatch(openDialog(DialInSummaryErrorDialog));
|
||||
}
|
||||
|
||||
@@ -122,7 +98,8 @@ class DialInSummary extends Component<Props> {
|
||||
|
||||
if (url.startsWith('tel:')) {
|
||||
Linking.openURL(url);
|
||||
this.props.dispatch(hideDialInSummary());
|
||||
|
||||
this.props.dispatch(setActiveModalId());
|
||||
}
|
||||
|
||||
return url === getDialInfoPageURLForURIString(this.props._summaryUrl);
|
||||
@@ -156,7 +133,7 @@ class DialInSummary extends Component<Props> {
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_summaryUrl: state['features/invite'].summaryUrl
|
||||
_summaryUrl: (state['features/base/modal'].modalProps || {}).summaryUrl
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,14 @@ import { ColorPalette } from '../../../../base/styles';
|
||||
|
||||
export const INDICATOR_COLOR = ColorPalette.lightGrey;
|
||||
|
||||
const WV_BACKGROUND = 'rgb(71, 71, 71)';
|
||||
|
||||
export default {
|
||||
|
||||
backDrop: {
|
||||
backgroundColor: WV_BACKGROUND
|
||||
},
|
||||
|
||||
indicatorWrapper: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: ColorPalette.white,
|
||||
@@ -14,11 +20,7 @@ export default {
|
||||
},
|
||||
|
||||
webView: {
|
||||
backgroundColor: WV_BACKGROUND,
|
||||
flex: 1
|
||||
},
|
||||
|
||||
webViewWrapper: {
|
||||
flex: 1,
|
||||
flexDirection: 'column'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
// @flow
|
||||
|
||||
/**
|
||||
* Modal ID for the AddPeopleDialog modal.
|
||||
*/
|
||||
export const ADD_PEOPLE_DIALOG_VIEW_ID = 'ADD_PEOPLE_DIALOG_VIEW_ID';
|
||||
|
||||
/**
|
||||
* Modal ID for the DialInSummary modal.
|
||||
*/
|
||||
export const DIAL_IN_SUMMARY_VIEW_ID = 'DIAL_IN_SUMMARY_VIEW_ID';
|
||||
|
||||
/**
|
||||
* The identifier of the sound to be played when the status of an outgoing call
|
||||
* is expired.
|
||||
|
||||
@@ -6,8 +6,6 @@ import {
|
||||
ADD_PENDING_INVITE_REQUEST,
|
||||
REMOVE_PENDING_INVITE_REQUESTS,
|
||||
SET_CALLEE_INFO_VISIBLE,
|
||||
SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||
SET_INVITE_DIALOG_VISIBLE,
|
||||
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
||||
UPDATE_DIAL_IN_NUMBERS_SUCCESS
|
||||
} from './actionTypes';
|
||||
@@ -21,7 +19,6 @@ const DEFAULT_STATE = {
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
calleeInfoVisible: false,
|
||||
inviteDialogVisible: false,
|
||||
numbersEnabled: true,
|
||||
pendingInviteRequests: []
|
||||
};
|
||||
@@ -50,18 +47,6 @@ ReducerRegistry.register('features/invite', (state = DEFAULT_STATE, action) => {
|
||||
initialCalleeInfo: action.initialCalleeInfo
|
||||
};
|
||||
|
||||
case SET_DIAL_IN_SUMMARY_VISIBLE:
|
||||
return {
|
||||
...state,
|
||||
summaryUrl: action.summaryUrl
|
||||
};
|
||||
|
||||
case SET_INVITE_DIALOG_VISIBLE:
|
||||
return {
|
||||
...state,
|
||||
inviteDialogVisible: action.visible
|
||||
};
|
||||
|
||||
case UPDATE_DIAL_IN_NUMBERS_FAILED:
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -5,10 +5,11 @@ import type { Dispatch } from 'redux';
|
||||
|
||||
import { getDefaultURL } from '../../app';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { setActiveModalId } from '../../base/modal';
|
||||
import { NavigateSectionList, type Section } from '../../base/react';
|
||||
import { connect } from '../../base/redux';
|
||||
import { ColorPalette } from '../../base/styles';
|
||||
import { showDialInSummary } from '../../invite';
|
||||
import { DIAL_IN_SUMMARY_VIEW_ID } from '../../invite/constants';
|
||||
|
||||
import { deleteRecentListEntry } from '../actions';
|
||||
import { isRecentListEnabled, toDisplayableList } from '../functions';
|
||||
@@ -124,7 +125,7 @@ class RecentList extends AbstractRecentList<Props> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onShowDialInInfo(itemId) {
|
||||
this.props.dispatch(showDialInSummary(itemId.url));
|
||||
this.props.dispatch(setActiveModalId(DIAL_IN_SUMMARY_VIEW_ID, { summaryUrl: itemId.url }));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,27 +86,31 @@ function _appWillMount({ dispatch, getState }, next, action) {
|
||||
* @returns {*} The result returned by {@code next(action)}.
|
||||
*/
|
||||
function _conferenceWillLeave({ dispatch, getState }, next, action) {
|
||||
let locationURL;
|
||||
const { doNotStoreRoom } = getState()['features/base/config'];
|
||||
|
||||
/**
|
||||
* FIXME:
|
||||
* It is better to use action.conference[JITSI_CONFERENCE_URL_KEY]
|
||||
* in order to make sure we get the url the conference is leaving
|
||||
* from (i.e. the room we are leaving from) because if the order of events
|
||||
* is different, we cannot be guranteed that the location URL in base
|
||||
* connection is the url we are leaving from... not the one we are going to
|
||||
* (the latter happens on mobile -- if we use the web implementation);
|
||||
* however, the conference object on web does not have
|
||||
* JITSI_CONFERENCE_URL_KEY so we cannot call it and must use the other way
|
||||
*/
|
||||
if (typeof APP === 'undefined') {
|
||||
locationURL = action.conference[JITSI_CONFERENCE_URL_KEY];
|
||||
} else {
|
||||
locationURL = getState()['features/base/connection'].locationURL;
|
||||
if (!doNotStoreRoom) {
|
||||
let locationURL;
|
||||
|
||||
/**
|
||||
* FIXME:
|
||||
* It is better to use action.conference[JITSI_CONFERENCE_URL_KEY]
|
||||
* in order to make sure we get the url the conference is leaving
|
||||
* from (i.e. the room we are leaving from) because if the order of events
|
||||
* is different, we cannot be guranteed that the location URL in base
|
||||
* connection is the url we are leaving from... not the one we are going to
|
||||
* (the latter happens on mobile -- if we use the web implementation);
|
||||
* however, the conference object on web does not have
|
||||
* JITSI_CONFERENCE_URL_KEY so we cannot call it and must use the other way
|
||||
*/
|
||||
if (typeof APP === 'undefined') {
|
||||
locationURL = action.conference[JITSI_CONFERENCE_URL_KEY];
|
||||
} else {
|
||||
locationURL = getState()['features/base/connection'].locationURL;
|
||||
}
|
||||
dispatch(
|
||||
_updateConferenceDuration(
|
||||
locationURL));
|
||||
}
|
||||
dispatch(
|
||||
_updateConferenceDuration(
|
||||
locationURL));
|
||||
|
||||
return next(action);
|
||||
}
|
||||
@@ -122,7 +126,9 @@ function _conferenceWillLeave({ dispatch, getState }, next, action) {
|
||||
* @returns {*} The result returned by {@code next(action)}.
|
||||
*/
|
||||
function _setRoom({ dispatch, getState }, next, action) {
|
||||
if (action.room) {
|
||||
const { doNotStoreRoom } = getState()['features/base/config'];
|
||||
|
||||
if (!doNotStoreRoom && action.room) {
|
||||
const { locationURL } = getState()['features/base/connection'];
|
||||
|
||||
if (locationURL) {
|
||||
|
||||
@@ -3,17 +3,6 @@
|
||||
*/
|
||||
export const SET_AUDIO_SETTINGS_VISIBILITY = 'SET_AUDIO_SETTINGS_VISIBILITY';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which sets the visibility of the view/UI rendering
|
||||
* the app's settings.
|
||||
*
|
||||
* {
|
||||
* type: SET_SETTINGS_VIEW_VISIBLE
|
||||
* visible: boolean
|
||||
* }
|
||||
*/
|
||||
export const SET_SETTINGS_VIEW_VISIBLE = 'SET_SETTINGS_VIEW_VISIBLE';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which sets the visibility of the video settings popup.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import { i18next } from '../base/i18n';
|
||||
|
||||
import {
|
||||
SET_AUDIO_SETTINGS_VISIBILITY,
|
||||
SET_SETTINGS_VIEW_VISIBLE,
|
||||
SET_VIDEO_SETTINGS_VISIBILITY
|
||||
} from './actionTypes';
|
||||
import { SettingsDialog } from './components';
|
||||
@@ -14,23 +13,6 @@ import { getMoreTabProps, getProfileTabProps } from './functions';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Sets the visibility of the view/UI which renders the app's settings.
|
||||
*
|
||||
* @param {boolean} visible - If the view/UI which renders the app's settings is
|
||||
* to be made visible, {@code true}; otherwise, {@code false}.
|
||||
* @returns {{
|
||||
* type: SET_SETTINGS_VIEW_VISIBLE,
|
||||
* visible: boolean
|
||||
* }}
|
||||
*/
|
||||
export function setSettingsViewVisible(visible: boolean) {
|
||||
return {
|
||||
type: SET_SETTINGS_VIEW_VISIBLE,
|
||||
visible
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens {@code SettingsDialog}.
|
||||
*
|
||||
|
||||
@@ -1,37 +1,29 @@
|
||||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Alert, NativeModules, SafeAreaView, ScrollView, Switch, Text, TextInput, View } from 'react-native';
|
||||
import { Alert, NativeModules, ScrollView, Switch, Text, TextInput } from 'react-native';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { HeaderWithNavigation, Modal } from '../../../base/react';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
import { connect } from '../../../base/redux';
|
||||
|
||||
import { SETTINGS_VIEW_ID } from '../../constants';
|
||||
import { normalizeUserInputURL } from '../../functions';
|
||||
|
||||
import {
|
||||
AbstractSettingsView,
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props as AbstractProps
|
||||
type Props
|
||||
} from '../AbstractSettingsView';
|
||||
import { setSettingsViewVisible } from '../../actions';
|
||||
|
||||
import FormRow from './FormRow';
|
||||
import FormSectionHeader from './FormSectionHeader';
|
||||
import { normalizeUserInputURL } from '../../functions';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* Application information module.
|
||||
*/
|
||||
const { AppInfo } = NativeModules;
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* Color schemed style of the header component.
|
||||
*/
|
||||
_headerStyles: Object
|
||||
}
|
||||
|
||||
type State = {
|
||||
|
||||
/**
|
||||
@@ -113,9 +105,9 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onBlurServerURL = this._onBlurServerURL.bind(this);
|
||||
this._onClose = this._onClose.bind(this);
|
||||
this._onDisableCallIntegration = this._onDisableCallIntegration.bind(this);
|
||||
this._onDisableP2P = this._onDisableP2P.bind(this);
|
||||
this._onRequestClose = this._onRequestClose.bind(this);
|
||||
this._onShowAdvanced = this._onShowAdvanced.bind(this);
|
||||
this._setURLFieldReference = this._setURLFieldReference.bind(this);
|
||||
this._showURLAlert = this._showURLAlert.bind(this);
|
||||
@@ -128,16 +120,78 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { displayName, email, serverURL, startWithAudioMuted, startWithVideoMuted } = this.state;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
onRequestClose = { this._onRequestClose }
|
||||
presentationStyle = 'overFullScreen'
|
||||
visible = { this.props._visible }>
|
||||
<View style = { this.props._headerStyles.page }>
|
||||
{ this._renderHeader() }
|
||||
{ this._renderBody() }
|
||||
</View>
|
||||
</Modal>
|
||||
<JitsiModal
|
||||
headerProps = {{
|
||||
headerLabelKey: 'settingsView.header'
|
||||
}}
|
||||
modalId = { SETTINGS_VIEW_ID }
|
||||
onClose = { this._onClose }>
|
||||
<ScrollView>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.profileSection' />
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.displayName'
|
||||
layout = 'column'>
|
||||
<TextInput
|
||||
autoCorrect = { false }
|
||||
onChangeText = { this._onChangeDisplayName }
|
||||
placeholder = 'John Doe'
|
||||
value = { displayName } />
|
||||
</FormRow>
|
||||
<FormRow
|
||||
label = 'settingsView.email'
|
||||
layout = 'column'>
|
||||
<TextInput
|
||||
autoCapitalize = 'none'
|
||||
autoCorrect = { false }
|
||||
keyboardType = { 'email-address' }
|
||||
onChangeText = { this._onChangeEmail }
|
||||
placeholder = 'email@example.com'
|
||||
value = { email } />
|
||||
</FormRow>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.conferenceSection' />
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.serverURL'
|
||||
layout = 'column'>
|
||||
<TextInput
|
||||
autoCapitalize = 'none'
|
||||
autoCorrect = { false }
|
||||
onBlur = { this._onBlurServerURL }
|
||||
onChangeText = { this._onChangeServerURL }
|
||||
placeholder = { this.props._serverURL }
|
||||
value = { serverURL } />
|
||||
</FormRow>
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.startWithAudioMuted'>
|
||||
<Switch
|
||||
onValueChange = { this._onStartAudioMutedChange }
|
||||
value = { startWithAudioMuted } />
|
||||
</FormRow>
|
||||
<FormRow label = 'settingsView.startWithVideoMuted'>
|
||||
<Switch
|
||||
onValueChange = { this._onStartVideoMutedChange }
|
||||
value = { startWithVideoMuted } />
|
||||
</FormRow>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.buildInfoSection' />
|
||||
<FormRow
|
||||
label = 'settingsView.version'>
|
||||
<Text>
|
||||
{ `${AppInfo.version} build ${AppInfo.buildNumber}` }
|
||||
</Text>
|
||||
</FormRow>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.advanced' />
|
||||
{ this._renderAdvancedSettings() }
|
||||
</ScrollView>
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -231,17 +285,18 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
||||
});
|
||||
}
|
||||
|
||||
_onRequestClose: () => void;
|
||||
_onClose: () => void;
|
||||
|
||||
/**
|
||||
* Handles the back button. Also invokes normalizeUserInputURL to validate
|
||||
* Callback to be invoked on closing the modal. Also invokes normalizeUserInputURL to validate
|
||||
* the URL entered by the user.
|
||||
*
|
||||
* @returns {void}
|
||||
* @returns {boolean} - True if the modal can be closed.
|
||||
*/
|
||||
_onRequestClose() {
|
||||
_onClose() {
|
||||
this.setState({ showAdvanced: false });
|
||||
this._processServerURL(true /* hideOnSuccess */);
|
||||
|
||||
return this._processServerURL(true /* hideOnSuccess */);
|
||||
}
|
||||
|
||||
_onShowAdvanced: () => void;
|
||||
@@ -296,12 +351,13 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
||||
|
||||
if (normalizedURL === null) {
|
||||
this._showURLAlert();
|
||||
} else {
|
||||
this._onChangeServerURL(normalizedURL);
|
||||
if (hideOnSuccess) {
|
||||
this.props.dispatch(setSettingsViewVisible(false));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this._onChangeServerURL(normalizedURL);
|
||||
|
||||
return hideOnSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,97 +401,6 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the body (under the header) of {@code SettingsView}.
|
||||
*
|
||||
* @private
|
||||
* @returns {React$Element}
|
||||
*/
|
||||
_renderBody() {
|
||||
const { displayName, email, serverURL, startWithAudioMuted, startWithVideoMuted } = this.state;
|
||||
|
||||
return (
|
||||
<SafeAreaView style = { styles.settingsForm }>
|
||||
<ScrollView>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.profileSection' />
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.displayName'
|
||||
layout = 'column'>
|
||||
<TextInput
|
||||
autoCorrect = { false }
|
||||
onChangeText = { this._onChangeDisplayName }
|
||||
placeholder = 'John Doe'
|
||||
value = { displayName } />
|
||||
</FormRow>
|
||||
<FormRow
|
||||
label = 'settingsView.email'
|
||||
layout = 'column'>
|
||||
<TextInput
|
||||
autoCapitalize = 'none'
|
||||
autoCorrect = { false }
|
||||
keyboardType = { 'email-address' }
|
||||
onChangeText = { this._onChangeEmail }
|
||||
placeholder = 'email@example.com'
|
||||
value = { email } />
|
||||
</FormRow>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.conferenceSection' />
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.serverURL'
|
||||
layout = 'column'>
|
||||
<TextInput
|
||||
autoCapitalize = 'none'
|
||||
autoCorrect = { false }
|
||||
onBlur = { this._onBlurServerURL }
|
||||
onChangeText = { this._onChangeServerURL }
|
||||
placeholder = { this.props._serverURL }
|
||||
value = { serverURL } />
|
||||
</FormRow>
|
||||
<FormRow
|
||||
fieldSeparator = { true }
|
||||
label = 'settingsView.startWithAudioMuted'>
|
||||
<Switch
|
||||
onValueChange = { this._onStartAudioMutedChange }
|
||||
value = { startWithAudioMuted } />
|
||||
</FormRow>
|
||||
<FormRow label = 'settingsView.startWithVideoMuted'>
|
||||
<Switch
|
||||
onValueChange = { this._onStartVideoMutedChange }
|
||||
value = { startWithVideoMuted } />
|
||||
</FormRow>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.buildInfoSection' />
|
||||
<FormRow
|
||||
label = 'settingsView.version'>
|
||||
<Text>
|
||||
{ `${AppInfo.version} build ${AppInfo.buildNumber}` }
|
||||
</Text>
|
||||
</FormRow>
|
||||
<FormSectionHeader
|
||||
label = 'settingsView.advanced' />
|
||||
{ this._renderAdvancedSettings() }
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the header of {@code SettingsView}.
|
||||
*
|
||||
* @private
|
||||
* @returns {React$Element}
|
||||
*/
|
||||
_renderHeader() {
|
||||
return (
|
||||
<HeaderWithNavigation
|
||||
headerLabelKey = 'settingsView.header'
|
||||
onPressBack = { this._onRequestClose } />
|
||||
);
|
||||
}
|
||||
|
||||
_setURLFieldReference: (React$ElementRef<*> | null) => void;
|
||||
|
||||
/**
|
||||
@@ -478,14 +443,11 @@ class SettingsView extends AbstractSettingsView<Props, State> {
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _headerStyles: Object
|
||||
* }}
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
..._abstractMapStateToProps(state)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -78,11 +78,6 @@ export default {
|
||||
padding: 5
|
||||
},
|
||||
|
||||
settingsForm: {
|
||||
backgroundColor: ColorPalette.white,
|
||||
flex: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* Global {@code Text} color for the components.
|
||||
*/
|
||||
|
||||
@@ -4,3 +4,8 @@ export const SETTINGS_TABS = {
|
||||
MORE: 'more_tab',
|
||||
PROFILE: 'profile_tab'
|
||||
};
|
||||
|
||||
/**
|
||||
* View ID for the Settings modal.
|
||||
*/
|
||||
export const SETTINGS_VIEW_ID = 'SETTINGS_VIEW_ID';
|
||||
|
||||
@@ -4,5 +4,4 @@ export * from './components';
|
||||
export * from './constants';
|
||||
export * from './functions';
|
||||
|
||||
import './middleware';
|
||||
import './reducer';
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// @flow
|
||||
|
||||
import { SET_ROOM } from '../base/conference';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { setSettingsViewVisible } from './actions';
|
||||
|
||||
/**
|
||||
* The redux middleware to set the visibility of {@link SettingsView}.
|
||||
*
|
||||
* @param {Store} store - The redux store.
|
||||
* @returns {Function}
|
||||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case SET_ROOM:
|
||||
return _hideSettingsView(store, next, action);
|
||||
}
|
||||
|
||||
return next(action);
|
||||
});
|
||||
|
||||
/**
|
||||
* Hides {@link SettingsView}.
|
||||
*
|
||||
* @param {Store} store - The redux store.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function.
|
||||
* @param {Action} action - The redux action.
|
||||
* @private
|
||||
* @returns {Object} The new state.
|
||||
*/
|
||||
function _hideSettingsView({ dispatch }, next, action) {
|
||||
dispatch(setSettingsViewVisible(false));
|
||||
|
||||
return next(action);
|
||||
}
|
||||
@@ -4,17 +4,11 @@ import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import {
|
||||
SET_AUDIO_SETTINGS_VISIBILITY,
|
||||
SET_SETTINGS_VIEW_VISIBLE,
|
||||
SET_VIDEO_SETTINGS_VISIBILITY
|
||||
} from './actionTypes';
|
||||
|
||||
ReducerRegistry.register('features/settings', (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case SET_SETTINGS_VIEW_VISIBLE:
|
||||
return {
|
||||
...state,
|
||||
visible: action.visible
|
||||
};
|
||||
case SET_AUDIO_SETTINGS_VISIBILITY:
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
createDesiredLocalTracks,
|
||||
destroyLocalTracks
|
||||
} from '../../base/tracks';
|
||||
import { HelpView } from '../../help';
|
||||
import { DialInSummary } from '../../invite';
|
||||
import { SettingsView } from '../../settings';
|
||||
|
||||
@@ -288,10 +289,9 @@ class WelcomePage extends AbstractWelcomePage {
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
<WelcomePageLists disabled = { this.state._fieldFocused } />
|
||||
<SettingsView />
|
||||
<DialInSummary />
|
||||
</View>
|
||||
<WelcomePageSideBar />
|
||||
{ this._renderWelcomePageModals() }
|
||||
</LocalVideoTrackUnderlay>
|
||||
);
|
||||
}
|
||||
@@ -312,6 +312,19 @@ class WelcomePage extends AbstractWelcomePage {
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders JitsiModals that are supposed to be on the welcome page.
|
||||
*
|
||||
* @returns {Array<ReactElement>}
|
||||
*/
|
||||
_renderWelcomePageModals() {
|
||||
return [
|
||||
<HelpView key = 'helpView' />,
|
||||
<DialInSummary key = 'dialInSummary' />,
|
||||
<SettingsView key = 'settings' />
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from '../../base/react';
|
||||
import { connect } from '../../base/redux';
|
||||
import { HELP_VIEW_MODAL_ID } from '../../help';
|
||||
import { setSettingsViewVisible } from '../../settings';
|
||||
import { SETTINGS_VIEW_ID } from '../../settings';
|
||||
|
||||
import { setSideBarVisible } from '../actions';
|
||||
import SideBarItem from './SideBarItem';
|
||||
@@ -157,7 +157,7 @@ class WelcomePageSideBar extends Component<Props> {
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch(setSideBarVisible(false));
|
||||
dispatch(setSettingsViewVisible(true));
|
||||
dispatch(setActiveModalId(SETTINGS_VIEW_ID));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user