mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-17 22:07:48 +00:00
* Button conditionally shown based on if the feature is enabled and available * Hooks for launching the invite UI (delegates to the native layer) * Hooks for using the search and dial out checks from the native layer (calls back into JS) * Hooks for handling sending invites and passing any failures back to the native layer * Android and iOS handling for those hooks Author: Ryan Peck <rpeck@atlassian.com> Author: Eric Brynsvold <ebrynsvold@atlassian.com>
234 lines
6.6 KiB
JavaScript
234 lines
6.6 KiB
JavaScript
/* @flow */
|
|
|
|
import i18next from 'i18next';
|
|
import { NativeModules, NativeEventEmitter } from 'react-native';
|
|
|
|
import { MiddlewareRegistry } from '../../base/redux';
|
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../app';
|
|
import { getInviteURL } from '../../base/connection';
|
|
import {
|
|
getInviteResultsForQuery,
|
|
isAddPeopleEnabled,
|
|
isDialOutEnabled,
|
|
sendInvitesForItems
|
|
} from '../../invite';
|
|
import { inviteVideoRooms } from '../../videosipgw';
|
|
|
|
import { sendInviteSuccess, sendInviteFailure } from './actions';
|
|
import {
|
|
_SET_INVITE_SEARCH_SUBSCRIPTIONS,
|
|
LAUNCH_NATIVE_INVITE,
|
|
SEND_INVITE_SUCCESS,
|
|
SEND_INVITE_FAILURE
|
|
} from './actionTypes';
|
|
|
|
/**
|
|
* Middleware that captures Redux actions and uses the InviteSearch module to
|
|
* turn them into native events so the application knows about them.
|
|
*
|
|
* @param {Store} store - Redux store.
|
|
* @returns {Function}
|
|
*/
|
|
MiddlewareRegistry.register(store => next => action => {
|
|
const result = next(action);
|
|
|
|
switch (action.type) {
|
|
|
|
case APP_WILL_MOUNT:
|
|
return _appWillMount(store, next, action);
|
|
|
|
case APP_WILL_UNMOUNT:
|
|
store.dispatch({
|
|
type: _SET_INVITE_SEARCH_SUBSCRIPTIONS,
|
|
subscriptions: undefined
|
|
});
|
|
break;
|
|
|
|
case LAUNCH_NATIVE_INVITE:
|
|
launchNativeInvite(store);
|
|
break;
|
|
|
|
case SEND_INVITE_SUCCESS:
|
|
onSendInviteSuccess(action);
|
|
break;
|
|
|
|
case SEND_INVITE_FAILURE:
|
|
onSendInviteFailure(action);
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Notifies the feature jwt that the action {@link APP_WILL_MOUNT} is being
|
|
* dispatched within a specific redux {@code store}.
|
|
*
|
|
* @param {Store} store - The redux store in which the specified {@code action}
|
|
* is being dispatched.
|
|
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
|
* specified {@code action} to the specified {@code store}.
|
|
* @param {Action} action - The redux action {@code APP_WILL_MOUNT} which is
|
|
* being dispatched in the specified {@code store}.
|
|
* @private
|
|
* @returns {*}
|
|
*/
|
|
function _appWillMount({ dispatch, getState }, next, action) {
|
|
const result = next(action);
|
|
|
|
const emitter = new NativeEventEmitter(NativeModules.InviteSearch);
|
|
|
|
const context = {
|
|
dispatch,
|
|
getState
|
|
};
|
|
const subscriptions = [
|
|
emitter.addListener(
|
|
'performQueryAction',
|
|
_onPerformQueryAction,
|
|
context),
|
|
emitter.addListener(
|
|
'performSubmitInviteAction',
|
|
_onPerformSubmitInviteAction,
|
|
context)
|
|
];
|
|
|
|
dispatch({
|
|
type: _SET_INVITE_SEARCH_SUBSCRIPTIONS,
|
|
subscriptions
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Sends a request to the native counterpart of InviteSearch to launch a native.
|
|
* invite search.
|
|
*
|
|
* @param {Object} store - The redux store.
|
|
* @private
|
|
* @returns {void}
|
|
*/
|
|
function launchNativeInvite(store: { getState: Function }) {
|
|
// The JavaScript App needs to provide uniquely identifying information
|
|
// to the native module so that the latter may match the former
|
|
// to the native JitsiMeetView which hosts it.
|
|
const { app } = store.getState()['features/app'];
|
|
|
|
if (app) {
|
|
const { externalAPIScope } = app.props;
|
|
|
|
if (externalAPIScope) {
|
|
NativeModules.InviteSearch.launchNativeInvite(externalAPIScope);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends a notification to the native counterpart of InviteSearch that all
|
|
* invites were sent successfully.
|
|
*
|
|
* @param {Object} action - The redux action {@code SEND_INVITE_SUCCESS} which
|
|
* is being dispatched.
|
|
* @returns {void}
|
|
*/
|
|
function onSendInviteSuccess({ inviteScope }) {
|
|
NativeModules.InviteSearch.inviteSucceeded(inviteScope);
|
|
}
|
|
|
|
/**
|
|
* Sends a notification to the native counterpart of InviteSearch that some
|
|
* invite items failed to send successfully.
|
|
*
|
|
* @param {Object} action - The redux action {@code SEND_INVITE_FAILURE} which
|
|
* is being dispatched.
|
|
* @returns {void}
|
|
*/
|
|
function onSendInviteFailure({ items, inviteScope }) {
|
|
NativeModules.InviteSearch.inviteFailedForItems(items, inviteScope);
|
|
}
|
|
|
|
/**
|
|
* Handles InviteSearch's event {@code performQueryAction}.
|
|
*
|
|
* @param {Object} event - The details of the InviteSearch event
|
|
* {@code performQueryAction}.
|
|
* @returns {void}
|
|
*/
|
|
function _onPerformQueryAction({ query, inviteScope }) {
|
|
const { getState } = this; // eslint-disable-line no-invalid-this
|
|
|
|
const state = getState();
|
|
|
|
const {
|
|
dialOutAuthUrl,
|
|
peopleSearchQueryTypes,
|
|
peopleSearchUrl
|
|
} = state['features/base/config'];
|
|
|
|
const options = {
|
|
dialOutAuthUrl,
|
|
enableAddPeople: isAddPeopleEnabled(state),
|
|
enableDialOut: isDialOutEnabled(state),
|
|
jwt: state['features/base/jwt'].jwt,
|
|
peopleSearchQueryTypes,
|
|
peopleSearchUrl
|
|
};
|
|
|
|
getInviteResultsForQuery(query, options)
|
|
.catch(() => [])
|
|
.then(results => {
|
|
const translatedResults = results.map(result => {
|
|
if (result.type === 'phone') {
|
|
result.title = i18next.t('addPeople.telephone', {
|
|
number: result.number
|
|
});
|
|
|
|
if (result.showCountryCodeReminder) {
|
|
result.subtitle = i18next.t(
|
|
'addPeople.countryReminder'
|
|
);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}).filter(result => result.type !== 'phone' || result.allowed);
|
|
|
|
NativeModules.InviteSearch.receivedResults(
|
|
translatedResults,
|
|
query,
|
|
inviteScope);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handles InviteSearch's event {@code performSubmitInviteAction}.
|
|
*
|
|
* @param {Object} event - The details of the InviteSearch event.
|
|
* @returns {void}
|
|
*/
|
|
function _onPerformSubmitInviteAction({ selectedItems, inviteScope }) {
|
|
const { dispatch, getState } = this; // eslint-disable-line no-invalid-this
|
|
const state = getState();
|
|
const { conference } = state['features/base/conference'];
|
|
const {
|
|
inviteServiceUrl
|
|
} = state['features/base/config'];
|
|
const options = {
|
|
conference,
|
|
inviteServiceUrl,
|
|
inviteUrl: getInviteURL(state),
|
|
inviteVideoRooms,
|
|
jwt: state['features/base/jwt'].jwt
|
|
};
|
|
|
|
sendInvitesForItems(selectedItems, options)
|
|
.then(invitesLeftToSend => {
|
|
if (invitesLeftToSend.length) {
|
|
dispatch(sendInviteFailure(invitesLeftToSend, inviteScope));
|
|
} else {
|
|
dispatch(sendInviteSuccess(inviteScope));
|
|
}
|
|
});
|
|
}
|