rn: add DialInSummary
This commit is contained in:
parent
7e9df74e60
commit
86d0d4fc22
|
@ -62,6 +62,7 @@ dependencies {
|
||||||
implementation project(':react-native-sound')
|
implementation project(':react-native-sound')
|
||||||
implementation project(':react-native-vector-icons')
|
implementation project(':react-native-vector-icons')
|
||||||
implementation project(':react-native-webrtc')
|
implementation project(':react-native-webrtc')
|
||||||
|
implementation project(':react-native-webview')
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,6 +147,7 @@ class ReactInstanceManagerHolder {
|
||||||
new com.oblador.vectoricons.VectorIconsPackage(),
|
new com.oblador.vectoricons.VectorIconsPackage(),
|
||||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||||
|
new com.reactnativecommunity.webview.RNCWebViewPackage(),
|
||||||
new com.rnimmersive.RNImmersivePackage(),
|
new com.rnimmersive.RNImmersivePackage(),
|
||||||
new com.zmxv.RNSound.RNSoundPackage(),
|
new com.zmxv.RNSound.RNSoundPackage(),
|
||||||
new ReactPackageAdapter() {
|
new ReactPackageAdapter() {
|
||||||
|
|
|
@ -3,6 +3,8 @@ rootProject.name = 'jitsi-meet'
|
||||||
include ':app', ':sdk'
|
include ':app', ':sdk'
|
||||||
include ':react-native-background-timer'
|
include ':react-native-background-timer'
|
||||||
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
|
project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
|
||||||
|
include ':react-native-calendar-events'
|
||||||
|
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
|
||||||
include ':react-native-fast-image'
|
include ':react-native-fast-image'
|
||||||
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
|
||||||
include ':react-native-google-signin'
|
include ':react-native-google-signin'
|
||||||
|
@ -19,5 +21,5 @@ include ':react-native-vector-icons'
|
||||||
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
|
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
|
||||||
include ':react-native-webrtc'
|
include ':react-native-webrtc'
|
||||||
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
|
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
|
||||||
include ':react-native-calendar-events'
|
include ':react-native-webview'
|
||||||
project(':react-native-calendar-events').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-calendar-events/android')
|
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
|
||||||
|
|
|
@ -185,6 +185,7 @@
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
padding: 15pt;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
|
@ -40,10 +40,14 @@ target 'JitsiMeet' do
|
||||||
|
|
||||||
pod 'react-native-background-timer',
|
pod 'react-native-background-timer',
|
||||||
:path => '../node_modules/react-native-background-timer'
|
:path => '../node_modules/react-native-background-timer'
|
||||||
|
pod 'react-native-calendar-events',
|
||||||
|
:path => '../node_modules/react-native-calendar-events'
|
||||||
pod 'react-native-fast-image',
|
pod 'react-native-fast-image',
|
||||||
:path => '../node_modules/react-native-fast-image'
|
:path => '../node_modules/react-native-fast-image'
|
||||||
pod 'react-native-keep-awake',
|
pod 'react-native-keep-awake',
|
||||||
:path => '../node_modules/react-native-keep-awake'
|
:path => '../node_modules/react-native-keep-awake'
|
||||||
|
pod 'react-native-webview',
|
||||||
|
:path => '../node_modules/react-native-webview'
|
||||||
pod 'BVLinearGradient',
|
pod 'BVLinearGradient',
|
||||||
:path => '../node_modules/react-native-linear-gradient'
|
:path => '../node_modules/react-native-linear-gradient'
|
||||||
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
pod 'react-native-webrtc', :path => '../node_modules/react-native-webrtc'
|
||||||
|
@ -52,8 +56,6 @@ target 'JitsiMeet' do
|
||||||
pod 'RNSound', :path => '../node_modules/react-native-sound'
|
pod 'RNSound', :path => '../node_modules/react-native-sound'
|
||||||
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
|
||||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
||||||
pod 'react-native-calendar-events',
|
|
||||||
:path => '../node_modules/react-native-calendar-events'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
|
|
|
@ -99,6 +99,8 @@ PODS:
|
||||||
- React
|
- React
|
||||||
- react-native-webrtc (1.69.1):
|
- react-native-webrtc (1.69.1):
|
||||||
- React
|
- React
|
||||||
|
- react-native-webview (5.8.1):
|
||||||
|
- React
|
||||||
- React/Core (0.59.5):
|
- React/Core (0.59.5):
|
||||||
- yoga (= 0.59.5.React)
|
- yoga (= 0.59.5.React)
|
||||||
- React/CxxBridge (0.59.5):
|
- React/CxxBridge (0.59.5):
|
||||||
|
@ -180,6 +182,7 @@ DEPENDENCIES:
|
||||||
- react-native-fast-image (from `../node_modules/react-native-fast-image`)
|
- react-native-fast-image (from `../node_modules/react-native-fast-image`)
|
||||||
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
|
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
|
||||||
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
|
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
|
||||||
|
- react-native-webview (from `../node_modules/react-native-webview`)
|
||||||
- React/Core (from `../node_modules/react-native`)
|
- React/Core (from `../node_modules/react-native`)
|
||||||
- React/CxxBridge (from `../node_modules/react-native`)
|
- React/CxxBridge (from `../node_modules/react-native`)
|
||||||
- React/DevSupport (from `../node_modules/react-native`)
|
- React/DevSupport (from `../node_modules/react-native`)
|
||||||
|
@ -239,6 +242,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native-keep-awake"
|
:path: "../node_modules/react-native-keep-awake"
|
||||||
react-native-webrtc:
|
react-native-webrtc:
|
||||||
:path: "../node_modules/react-native-webrtc"
|
:path: "../node_modules/react-native-webrtc"
|
||||||
|
react-native-webview:
|
||||||
|
:path: "../node_modules/react-native-webview"
|
||||||
RNGoogleSignin:
|
RNGoogleSignin:
|
||||||
:path: "../node_modules/react-native-google-signin"
|
:path: "../node_modules/react-native-google-signin"
|
||||||
RNSound:
|
RNSound:
|
||||||
|
@ -279,6 +284,7 @@ SPEC CHECKSUMS:
|
||||||
react-native-fast-image: 47487b71169aea34868e7b38bf870b6b3f2157c5
|
react-native-fast-image: 47487b71169aea34868e7b38bf870b6b3f2157c5
|
||||||
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
|
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
|
||||||
react-native-webrtc: 90a847d19deb2d7323fef8cc89ca12b8995fbc90
|
react-native-webrtc: 90a847d19deb2d7323fef8cc89ca12b8995fbc90
|
||||||
|
react-native-webview: a95842e3f351a6d2c8bc8bcc9eab689c7e7e5ad4
|
||||||
RNGoogleSignin: 361174d9a3090d295b06257162b560d8efc8a6ed
|
RNGoogleSignin: 361174d9a3090d295b06257162b560d8efc8a6ed
|
||||||
RNSound: e157320f503bdd4f4ee6d8542e948d54f90c3c3a
|
RNSound: e157320f503bdd4f4ee6d8542e948d54f90c3c3a
|
||||||
RNVectorIcons: d819334932bcda3332deb3d2c8ea4d069e0b98f9
|
RNVectorIcons: d819334932bcda3332deb3d2c8ea4d069e0b98f9
|
||||||
|
@ -286,6 +292,6 @@ SPEC CHECKSUMS:
|
||||||
SDWebImage: 3f3f0c02f09798048c47a5ed0a13f17b063572d8
|
SDWebImage: 3f3f0c02f09798048c47a5ed0a13f17b063572d8
|
||||||
yoga: 2e571f113e8cbeb0eb752aeebc86c1bfe7a8200c
|
yoga: 2e571f113e8cbeb0eb752aeebc86c1bfe7a8200c
|
||||||
|
|
||||||
PODFILE CHECKSUM: 9e6bc935ea7d2974604572cc68938281a88cf35c
|
PODFILE CHECKSUM: 0efc5cf3d69bf87368dc776a4e9a3c21935a16cf
|
||||||
|
|
||||||
COCOAPODS: 1.6.1
|
COCOAPODS: 1.6.1
|
||||||
|
|
|
@ -351,6 +351,7 @@
|
||||||
"dialInConferenceID": "PIN:",
|
"dialInConferenceID": "PIN:",
|
||||||
"dialInNotSupported": "Sorry, dialing in is currently not supported.",
|
"dialInNotSupported": "Sorry, dialing in is currently not supported.",
|
||||||
"dialInNumber": "Dial-in:",
|
"dialInNumber": "Dial-in:",
|
||||||
|
"dialInSummaryError": "Error fetching dial-in info now. Please try again later.",
|
||||||
"dialInTollFree": "Toll Free",
|
"dialInTollFree": "Toll Free",
|
||||||
"genericError": "Whoops, something went wrong.",
|
"genericError": "Whoops, something went wrong.",
|
||||||
"inviteLiveStream": "To view the live stream of this meeting, click this link: __url__",
|
"inviteLiveStream": "To view the live stream of this meeting, click this link: __url__",
|
||||||
|
@ -773,6 +774,7 @@
|
||||||
"enterRoomTitle": "Start a new meeting",
|
"enterRoomTitle": "Start a new meeting",
|
||||||
"go": "GO",
|
"go": "GO",
|
||||||
"join": "JOIN",
|
"join": "JOIN",
|
||||||
|
"info": "Info",
|
||||||
"privacy": "Privacy",
|
"privacy": "Privacy",
|
||||||
"recentList": "Recent",
|
"recentList": "Recent",
|
||||||
"recentListDelete": "Delete",
|
"recentListDelete": "Delete",
|
||||||
|
|
|
@ -12274,6 +12274,25 @@
|
||||||
"prop-types": "^15.5.10"
|
"prop-types": "^15.5.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-native-webview": {
|
||||||
|
"version": "5.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-5.8.1.tgz",
|
||||||
|
"integrity": "sha512-b6pSvmjoiWtcz6YspggW02X+BRXJWuquHwkh37BRx1NMW1iwMZA31SnFQvTpPzWYYIb9WF/mRsy2nGtt9C6NIg==",
|
||||||
|
"requires": {
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"invariant": "2.2.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"invariant": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-node-resolver": {
|
"react-node-resolver": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-node-resolver/-/react-node-resolver-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-node-resolver/-/react-node-resolver-1.0.1.tgz",
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
"react-native-vector-icons": "6.0.2",
|
"react-native-vector-icons": "6.0.2",
|
||||||
"react-native-watch-connectivity": "0.2.0",
|
"react-native-watch-connectivity": "0.2.0",
|
||||||
"react-native-webrtc": "github:jitsi/react-native-webrtc#4064c6f2db4f8b961daaaa8dafc6a896d7cfbc43",
|
"react-native-webrtc": "github:jitsi/react-native-webrtc#4064c6f2db4f8b961daaaa8dafc6a896d7cfbc43",
|
||||||
|
"react-native-webview": "5.8.1",
|
||||||
"react-redux": "5.0.7",
|
"react-redux": "5.0.7",
|
||||||
"react-transition-group": "2.4.0",
|
"react-transition-group": "2.4.0",
|
||||||
"redux": "4.0.0",
|
"redux": "4.0.0",
|
||||||
|
|
|
@ -5,12 +5,11 @@ import Swipeout from 'react-native-swipeout';
|
||||||
|
|
||||||
import { ColorPalette } from '../../../styles';
|
import { ColorPalette } from '../../../styles';
|
||||||
|
|
||||||
import Container from './Container';
|
|
||||||
import Text from './Text';
|
|
||||||
import styles from './styles';
|
|
||||||
import type { Item } from '../../Types';
|
import type { Item } from '../../Types';
|
||||||
|
|
||||||
import AvatarListItem from './AvatarListItem';
|
import AvatarListItem from './AvatarListItem';
|
||||||
|
import Text from './Text';
|
||||||
|
import styles from './styles';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
|
@ -93,24 +92,6 @@ export default class NavigateSectionListItem extends Component<Props> {
|
||||||
return lines && lines.length ? lines.map(this._renderItemLine) : null;
|
return lines && lines.length ? lines.map(this._renderItemLine) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the secondary action label.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {React$Node}
|
|
||||||
*/
|
|
||||||
_renderSecondaryAction() {
|
|
||||||
const { secondaryAction } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Container
|
|
||||||
onClick = { secondaryAction }
|
|
||||||
style = { styles.secondaryActionContainer }>
|
|
||||||
<Text style = { styles.secondaryActionLabel }>+</Text>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the content of this component.
|
* Renders the content of this component.
|
||||||
*
|
*
|
||||||
|
@ -138,14 +119,12 @@ export default class NavigateSectionListItem extends Component<Props> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Swipeout
|
<Swipeout
|
||||||
|
autoClose = { true }
|
||||||
backgroundColor = { ColorPalette.transparent }
|
backgroundColor = { ColorPalette.transparent }
|
||||||
right = { right }>
|
right = { right }>
|
||||||
<AvatarListItem
|
<AvatarListItem
|
||||||
item = { item }
|
item = { item }
|
||||||
onPress = { this.props.onPress }>
|
onPress = { this.props.onPress } />
|
||||||
{ this.props.secondaryAction
|
|
||||||
&& this._renderSecondaryAction() }
|
|
||||||
</AvatarListItem>
|
|
||||||
</Swipeout>
|
</Swipeout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { BoxModel, ColorPalette, createStyleSheet } from '../../../styles';
|
||||||
|
|
||||||
const AVATAR_OPACITY = 0.4;
|
const AVATAR_OPACITY = 0.4;
|
||||||
const OVERLAY_FONT_COLOR = 'rgba(255, 255, 255, 0.6)';
|
const OVERLAY_FONT_COLOR = 'rgba(255, 255, 255, 0.6)';
|
||||||
const SECONDARY_ACTION_BUTTON_SIZE = 30;
|
|
||||||
|
|
||||||
export const AVATAR_SIZE = 65;
|
export const AVATAR_SIZE = 65;
|
||||||
export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)';
|
export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)';
|
||||||
|
@ -218,21 +217,6 @@ const SECTION_LIST_STYLES = {
|
||||||
color: OVERLAY_FONT_COLOR
|
color: OVERLAY_FONT_COLOR
|
||||||
},
|
},
|
||||||
|
|
||||||
secondaryActionContainer: {
|
|
||||||
alignItems: 'center',
|
|
||||||
backgroundColor: ColorPalette.blue,
|
|
||||||
borderRadius: 3,
|
|
||||||
height: SECONDARY_ACTION_BUTTON_SIZE,
|
|
||||||
justifyContent: 'center',
|
|
||||||
margin: BoxModel.margin * 0.5,
|
|
||||||
marginRight: BoxModel.margin,
|
|
||||||
width: SECONDARY_ACTION_BUTTON_SIZE
|
|
||||||
},
|
|
||||||
|
|
||||||
secondaryActionLabel: {
|
|
||||||
color: ColorPalette.white
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableView: {
|
touchableView: {
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,16 @@ export const REMOVE_PENDING_INVITE_REQUESTS
|
||||||
*/
|
*/
|
||||||
export const SET_CALLEE_INFO_VISIBLE = 'SET_CALLEE_INFO_VISIBLE';
|
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.
|
* The type of redux action which sets the invite dialog visible or invisible.
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
BEGIN_ADD_PEOPLE,
|
BEGIN_ADD_PEOPLE,
|
||||||
REMOVE_PENDING_INVITE_REQUESTS,
|
REMOVE_PENDING_INVITE_REQUESTS,
|
||||||
SET_CALLEE_INFO_VISIBLE,
|
SET_CALLEE_INFO_VISIBLE,
|
||||||
|
SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||||
SET_INVITE_DIALOG_VISIBLE,
|
SET_INVITE_DIALOG_VISIBLE,
|
||||||
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
||||||
UPDATE_DIAL_IN_NUMBERS_SUCCESS
|
UPDATE_DIAL_IN_NUMBERS_SUCCESS
|
||||||
|
@ -256,6 +257,15 @@ export function addPendingInviteRequest(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to hide the dial in summary.
|
||||||
|
*
|
||||||
|
* @returns {showDialInSummary}
|
||||||
|
*/
|
||||||
|
export function hideDialInSummary() {
|
||||||
|
return showDialInSummary(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all pending invite requests.
|
* Removes all pending invite requests.
|
||||||
*
|
*
|
||||||
|
@ -268,3 +278,19 @@ export function removePendingInviteRequests() {
|
||||||
type: REMOVE_PENDING_INVITE_REQUESTS
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
export * from './native';
|
|
@ -0,0 +1,3 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
export * from './web';
|
|
@ -0,0 +1,156 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Linking, View } from 'react-native';
|
||||||
|
import { WebView } from 'react-native-webview';
|
||||||
|
import { type Dispatch } from 'redux';
|
||||||
|
|
||||||
|
import { openDialog } from '../../../../base/dialog';
|
||||||
|
import { translate } from '../../../../base/i18n';
|
||||||
|
import {
|
||||||
|
HeaderWithNavigation,
|
||||||
|
LoadingIndicator,
|
||||||
|
SlidingView
|
||||||
|
} from '../../../../base/react';
|
||||||
|
import { connect } from '../../../../base/redux';
|
||||||
|
|
||||||
|
import { hideDialInSummary } from '../../../actions';
|
||||||
|
import { getDialInfoPageURLForURIString } from '../../../functions';
|
||||||
|
|
||||||
|
import DialInSummaryErrorDialog from './DialInSummaryErrorDialog';
|
||||||
|
import styles, { INDICATOR_COLOR } from './styles';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to display the summary for.
|
||||||
|
*/
|
||||||
|
_summaryUrl: ?string,
|
||||||
|
|
||||||
|
dispatch: Dispatch<any>
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a React native component that displays the dial in info page for a specific room.
|
||||||
|
*/
|
||||||
|
class DialInSummary extends Component<Props> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new instance.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { _summaryUrl } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SlidingView
|
||||||
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onCloseView: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the view.
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_onCloseView() {
|
||||||
|
this.props.dispatch(hideDialInSummary());
|
||||||
|
}
|
||||||
|
|
||||||
|
_onError: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to handle the error if the page fails to load.
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_onError() {
|
||||||
|
this.props.dispatch(hideDialInSummary());
|
||||||
|
this.props.dispatch(openDialog(DialInSummaryErrorDialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
_onNavigate: Object => Boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to intercept navigation inside the webview and make the native app handle the dial requests.
|
||||||
|
*
|
||||||
|
* NOTE: We don't navigate to anywhere else form that view.
|
||||||
|
*
|
||||||
|
* @param {any} request - The request object.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
_onNavigate(request) {
|
||||||
|
const { url } = request;
|
||||||
|
|
||||||
|
if (url.startsWith('tel:')) {
|
||||||
|
Linking.openURL(url);
|
||||||
|
this.props.dispatch(hideDialInSummary());
|
||||||
|
}
|
||||||
|
|
||||||
|
return url === getDialInfoPageURLForURIString(this.props._summaryUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderLoading: () => React$Component<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the loading indicator.
|
||||||
|
*
|
||||||
|
* @returns {React$Component<any>}
|
||||||
|
*/
|
||||||
|
_renderLoading() {
|
||||||
|
return (
|
||||||
|
<View style = { styles.indicatorWrapper }>
|
||||||
|
<LoadingIndicator
|
||||||
|
color = { INDICATOR_COLOR }
|
||||||
|
size = 'large' />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps part of the Redux state to the props of this component.
|
||||||
|
*
|
||||||
|
* @param {Object} state - The Redux state.
|
||||||
|
* @returns {{
|
||||||
|
* _summaryUrl: ?string
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
function _mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
_summaryUrl: state['features/invite'].summaryUrl
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default translate(connect(_mapStateToProps)(DialInSummary));
|
|
@ -0,0 +1,29 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import { AlertDialog } from '../../../../base/dialog';
|
||||||
|
import { translate } from '../../../../base/i18n';
|
||||||
|
import { connect } from '../../../../base/redux';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialog to inform the user that we could't fetch the dial-in info page.
|
||||||
|
*/
|
||||||
|
class DialInSummaryErrorDialog extends Component<{}> {
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {ReactElement}
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<AlertDialog
|
||||||
|
contentKey = 'info.dialInSummaryError' />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default translate(connect()(DialInSummaryErrorDialog));
|
|
@ -1 +1,3 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
export { default as DialInSummary } from './DialInSummary';
|
export { default as DialInSummary } from './DialInSummary';
|
|
@ -0,0 +1,24 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import { ColorPalette } from '../../../../base/styles';
|
||||||
|
|
||||||
|
export const INDICATOR_COLOR = ColorPalette.lightGrey;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
indicatorWrapper: {
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: ColorPalette.white,
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
|
||||||
|
webView: {
|
||||||
|
flex: 1
|
||||||
|
},
|
||||||
|
|
||||||
|
webViewWrapper: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column'
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,8 +1,8 @@
|
||||||
/* @flow */
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link ConferenceID}.
|
* The type of the React {@code Component} props of {@link ConferenceID}.
|
|
@ -1,8 +1,8 @@
|
||||||
/* @flow */
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
import ConferenceID from './ConferenceID';
|
import ConferenceID from './ConferenceID';
|
||||||
import NumbersList from './NumbersList';
|
import NumbersList from './NumbersList';
|
|
@ -1,8 +1,8 @@
|
||||||
/* @flow */
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
export { default as DialInSummary } from './DialInSummary';
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
export * from './add-people-dialog';
|
export * from './add-people-dialog';
|
||||||
export { DialInSummary } from './dial-in-summary';
|
export * from './dial-in-summary';
|
||||||
export * from './info-dialog';
|
export * from './info-dialog';
|
||||||
export * from './callee-info';
|
export * from './callee-info';
|
||||||
|
|
|
@ -508,6 +508,22 @@ export function getDialInfoPageURL(
|
||||||
return `${origin}${newPath}/static/dialInInfo.html?room=${conferenceName}`;
|
return `${origin}${newPath}/static/dialInInfo.html?room=${conferenceName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the URL for the static dial in info page.
|
||||||
|
*
|
||||||
|
* @param {string} uri - The conference URI string.
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function getDialInfoPageURLForURIString(
|
||||||
|
uri: ?string) {
|
||||||
|
if (!uri) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const { protocol, host, contextRoot, room } = parseURIString(uri);
|
||||||
|
|
||||||
|
return `${protocol}//${host}${contextRoot}static/dialInInfo.html?room=${room}`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the internal state of which dial-in number to display.
|
* Sets the internal state of which dial-in number to display.
|
||||||
*
|
*
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
ADD_PENDING_INVITE_REQUEST,
|
ADD_PENDING_INVITE_REQUEST,
|
||||||
REMOVE_PENDING_INVITE_REQUESTS,
|
REMOVE_PENDING_INVITE_REQUESTS,
|
||||||
SET_CALLEE_INFO_VISIBLE,
|
SET_CALLEE_INFO_VISIBLE,
|
||||||
|
SET_DIAL_IN_SUMMARY_VISIBLE,
|
||||||
SET_INVITE_DIALOG_VISIBLE,
|
SET_INVITE_DIALOG_VISIBLE,
|
||||||
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
UPDATE_DIAL_IN_NUMBERS_FAILED,
|
||||||
UPDATE_DIAL_IN_NUMBERS_SUCCESS
|
UPDATE_DIAL_IN_NUMBERS_SUCCESS
|
||||||
|
@ -50,6 +51,12 @@ ReducerRegistry.register('features/invite', (state = DEFAULT_STATE, action) => {
|
||||||
initialCalleeInfo: action.initialCalleeInfo
|
initialCalleeInfo: action.initialCalleeInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case SET_DIAL_IN_SUMMARY_VISIBLE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
summaryUrl: action.summaryUrl
|
||||||
|
};
|
||||||
|
|
||||||
case SET_INVITE_DIALOG_VISIBLE:
|
case SET_INVITE_DIALOG_VISIBLE:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -7,6 +7,8 @@ import { getDefaultURL } from '../../app';
|
||||||
import { translate } from '../../base/i18n';
|
import { translate } from '../../base/i18n';
|
||||||
import { NavigateSectionList, type Section } from '../../base/react';
|
import { NavigateSectionList, type Section } from '../../base/react';
|
||||||
import { connect } from '../../base/redux';
|
import { connect } from '../../base/redux';
|
||||||
|
import { ColorPalette } from '../../base/styles';
|
||||||
|
import { showDialInSummary } from '../../invite';
|
||||||
|
|
||||||
import { deleteRecentListEntry } from '../actions';
|
import { deleteRecentListEntry } from '../actions';
|
||||||
import { isRecentListEnabled, toDisplayableList } from '../functions';
|
import { isRecentListEnabled, toDisplayableList } from '../functions';
|
||||||
|
@ -60,6 +62,7 @@ class RecentList extends AbstractRecentList<Props> {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this._onDelete = this._onDelete.bind(this);
|
this._onDelete = this._onDelete.bind(this);
|
||||||
|
this._onShowDialInInfo = this._onShowDialInInfo.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,6 +82,10 @@ class RecentList extends AbstractRecentList<Props> {
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const recentList = toDisplayableList(_recentList, t, _defaultServerURL);
|
const recentList = toDisplayableList(_recentList, t, _defaultServerURL);
|
||||||
const slideActions = [ {
|
const slideActions = [ {
|
||||||
|
backgroundColor: ColorPalette.blue,
|
||||||
|
onPress: this._onShowDialInInfo,
|
||||||
|
text: t('welcomepage.info')
|
||||||
|
}, {
|
||||||
backgroundColor: 'red',
|
backgroundColor: 'red',
|
||||||
onPress: this._onDelete,
|
onPress: this._onDelete,
|
||||||
text: t('welcomepage.recentListDelete')
|
text: t('welcomepage.recentListDelete')
|
||||||
|
@ -107,6 +114,18 @@ class RecentList extends AbstractRecentList<Props> {
|
||||||
_onDelete(itemId) {
|
_onDelete(itemId) {
|
||||||
this.props.dispatch(deleteRecentListEntry(itemId));
|
this.props.dispatch(deleteRecentListEntry(itemId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onShowDialInInfo: Object => void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for the dial-in info action of the list.
|
||||||
|
*
|
||||||
|
* @param {Object} itemId - The ID of the entry for which we'd like to show the dial in numbers.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_onShowDialInInfo(itemId) {
|
||||||
|
this.props.dispatch(showDialInSummary(itemId.url));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
createDesiredLocalTracks,
|
createDesiredLocalTracks,
|
||||||
destroyLocalTracks
|
destroyLocalTracks
|
||||||
} from '../../base/tracks';
|
} from '../../base/tracks';
|
||||||
|
import { DialInSummary } from '../../invite';
|
||||||
import { SettingsView } from '../../settings';
|
import { SettingsView } from '../../settings';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -135,6 +136,7 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
<WelcomePageLists disabled = { this.state._fieldFocused } />
|
<WelcomePageLists disabled = { this.state._fieldFocused } />
|
||||||
<SettingsView />
|
<SettingsView />
|
||||||
|
<DialInSummary />
|
||||||
</View>
|
</View>
|
||||||
<WelcomePageSideBar />
|
<WelcomePageSideBar />
|
||||||
</LocalVideoTrackUnderlay>
|
</LocalVideoTrackUnderlay>
|
||||||
|
|
Loading…
Reference in New Issue