[RN] Add ability to share the URL for a conference

This commit is contained in:
Saúl Ibarra Corretgé 2017-01-31 10:52:29 +01:00 committed by Lyubo Marinov
parent 13e3375e8a
commit 54bb5f1879
5 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,24 @@
import { Symbol } from '../base/react';
/**
* The type of (redux) action which begins the UI procedure to share the current
* conference/room URL.
*
* {
* type: BEGIN_SHARE_ROOM,
* roomURL: string
* }
*/
export const BEGIN_SHARE_ROOM = Symbol('BEGIN_SHARE_ROOM');
/**
* The type of (redux) action which ends the UI procedure to share a specific
* conference/room URL.
*
* {
* type: END_SHARE_ROOM,
* roomURL: string,
* shared: boolean
* }
*/
export const END_SHARE_ROOM = Symbol('END_SHARE_ROOM');

View File

@ -0,0 +1,65 @@
/* @flow */
import { BEGIN_SHARE_ROOM, END_SHARE_ROOM } from './actionTypes';
/**
* Begins the UI procedure to share the URL for the current conference/room.
*
* @param {string} roomURL - The URL of the room to share.
* @public
* @returns {Function}
*/
export function beginShareRoom(roomURL: ?string): Function {
return (dispatch, getState) => {
if (!roomURL) {
const { conference, room } = getState()['features/base/conference'];
// eslint-disable-next-line no-param-reassign
roomURL = _getRoomURL(conference, room);
}
if (roomURL) {
dispatch({
type: BEGIN_SHARE_ROOM,
roomURL
});
}
};
}
/**
* Ends the UI procedure to share a specific conference/room URL.
*
* @param {string} roomURL - The URL of the conference/room which was shared.
* @param {boolean} shared - True if the URL was shared successfully; false,
* otherwise.
* @public
* @returns {{
* type: END_SHARE_ROOM,
* roomURL: string,
* shared: boolean
* }}
*/
export function endShareRoom(roomURL: string, shared: boolean): Object {
return {
type: END_SHARE_ROOM,
roomURL,
shared
};
}
/**
* Gets the public URL of a conference/room.
*
* @param {JitsiConference} conference - The JitsiConference to share the URL
* of.
* @param {string} room - The name of the room to share the URL of.
* @private
* @returns {string|null}
*/
function _getRoomURL(conference, room) {
return (
conference
&& room
&& `https://${conference.connection.options.hosts.domain}/${room}`);
}

View File

@ -0,0 +1,4 @@
export * from './actions';
export * from './actionTypes';
import './middleware';

View File

@ -0,0 +1,63 @@
/* @flow */
import { Share } from 'react-native';
import { MiddlewareRegistry } from '../base/redux';
import { endShareRoom } from './actions';
import { BEGIN_SHARE_ROOM } from './actionTypes';
/**
* Middleware that captures room URL sharing actions and starts the sharing
* process.
*
* @param {Store} store - Redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case BEGIN_SHARE_ROOM:
_shareRoom(action.roomURL, store.dispatch);
break;
}
return next(action);
});
/**
* Open the native sheet for sharing a specific conference/room URL.
*
* @param {string} roomURL - The URL of the conference/room to be shared.
* @param {Dispatch} dispatch - The Redux dispatch function.
* @private
* @returns {void}
*/
function _shareRoom(roomURL: string, dispatch: Function) {
// TODO The following display/human-readable strings were submitted for
// review before i18n was introduces in react/. However, I reviewed it
// afterwards. Translate the display/human-readable strings.
const message = `Click the following link to join the meeting: ${roomURL}`;
const title = 'Jitsi Meet Conference';
const onFulfilled
= (shared: boolean) => dispatch(endShareRoom(roomURL, shared));
Share.share(
/* content */ {
message,
title
},
/* options */ {
dialogTitle: title, // Android
subject: title // iOS
})
.then(
/* onFulfilled */ value => {
onFulfilled(value.action === Share.sharedAction);
},
/* onRejected */ reason => {
console.error(
`Failed to share conference/room URL ${roomURL}:`,
reason);
onFulfilled(false);
});
}

View File

@ -7,6 +7,7 @@ import { MEDIA_TYPE, toggleCameraFacingMode } from '../../base/media';
import { Container } from '../../base/react'; import { Container } from '../../base/react';
import { ColorPalette } from '../../base/styles'; import { ColorPalette } from '../../base/styles';
import { beginRoomLockRequest } from '../../room-lock'; import { beginRoomLockRequest } from '../../room-lock';
import { beginShareRoom } from '../../share-room';
import { import {
abstractMapDispatchToProps, abstractMapDispatchToProps,
@ -45,6 +46,11 @@ class Toolbox extends Component {
*/ */
_onRoomLock: React.PropTypes.func, _onRoomLock: React.PropTypes.func,
/**
* Begins the UI procedure to share the conference/room URL.
*/
_onShareRoom: React.PropTypes.func,
/** /**
* Handler for toggle audio. * Handler for toggle audio.
*/ */
@ -211,6 +217,12 @@ class Toolbox extends Component {
onClick = { this.props._onToggleAudioOnly } onClick = { this.props._onToggleAudioOnly }
style = { style } style = { style }
underlayColor = { underlayColor } /> underlayColor = { underlayColor } />
<ToolbarButton
iconName = 'link'
iconStyle = { iconStyle }
onClick = { this.props._onShareRoom }
style = { style }
underlayColor = { underlayColor } />
</View> </View>
); );
@ -257,6 +269,17 @@ function _mapDispatchToProps(dispatch) {
return dispatch(beginRoomLockRequest()); return dispatch(beginRoomLockRequest());
}, },
/**
* Begins the UI procedure to share the conference/room URL.
*
* @private
* @returns {void} Dispatched action.
* @type {Function}
*/
_onShareRoom() {
return dispatch(beginShareRoom());
},
/** /**
* Toggles the audio-only flag of the conference. * Toggles the audio-only flag of the conference.
* *