diff --git a/src/Expensify.js b/src/Expensify.js index 28ae6f527928..dbe03ca0d76e 100644 --- a/src/Expensify.js +++ b/src/Expensify.js @@ -17,6 +17,10 @@ import GrowlNotification from './components/GrowlNotification'; import * as Growl from './libs/Growl'; import StartupTimer from './libs/StartupTimer'; import Log from './libs/Log'; +import ConfirmModal from './components/ConfirmModal'; +import compose from './libs/compose'; +import withLocalize, {withLocalizePropTypes} from './components/withLocalize'; +import * as User from './libs/actions/User'; Onyx.registerLogger(({level, message}) => { if (level === 'alert') { @@ -48,6 +52,18 @@ const propTypes = { /** Tells us if the sidebar has rendered */ isSidebarLoaded: PropTypes.bool, + + /** Information about a screen share call requested by a GuidesPlus agent */ + screenShareRequest: PropTypes.shape({ + + /** Access token required to join a screen share room, generated by the backend */ + accessToken: PropTypes.string, + + /** Name of the screen share room to join */ + roomName: PropTypes.string, + }), + + ...withLocalizePropTypes, }; const defaultProps = { @@ -58,6 +74,7 @@ const defaultProps = { updateAvailable: false, initialReportDataLoaded: false, isSidebarLoaded: false, + screenShareRequest: null, }; class Expensify extends PureComponent { @@ -167,6 +184,17 @@ class Expensify extends PureComponent { {/* We include the modal for showing a new update at the top level so the option is always present. */} {this.props.updateAvailable ? : null} + {this.props.screenShareRequest ? ( + User.joinScreenShare(this.props.screenShareRequest.accessToken, this.props.screenShareRequest.roomName)} + onCancel={User.clearScreenShareRequest} + prompt={this.props.translate('guides.screenShareRequest')} + confirmText={this.props.translate('common.join')} + cancelText={this.props.translate('common.decline')} + isVisible + /> + ) : null} )} @@ -181,18 +209,24 @@ class Expensify extends PureComponent { Expensify.propTypes = propTypes; Expensify.defaultProps = defaultProps; -export default withOnyx({ - session: { - key: ONYXKEYS.SESSION, - }, - updateAvailable: { - key: ONYXKEYS.UPDATE_AVAILABLE, - initWithStoredValues: false, - }, - initialReportDataLoaded: { - key: ONYXKEYS.INITIAL_REPORT_DATA_LOADED, - }, - isSidebarLoaded: { - key: ONYXKEYS.IS_SIDEBAR_LOADED, - }, -})(Expensify); +export default compose( + withLocalize, + withOnyx({ + session: { + key: ONYXKEYS.SESSION, + }, + updateAvailable: { + key: ONYXKEYS.UPDATE_AVAILABLE, + initWithStoredValues: false, + }, + initialReportDataLoaded: { + key: ONYXKEYS.INITIAL_REPORT_DATA_LOADED, + }, + isSidebarLoaded: { + key: ONYXKEYS.IS_SIDEBAR_LOADED, + }, + screenShareRequest: { + key: ONYXKEYS.SCREEN_SHARE_REQUEST, + }, + }), +)(Expensify); diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index c97e2e24b1ec..a79ffb6c2a71 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -58,9 +58,12 @@ export default { // select a currency based on the list CURRENCY_LIST: 'currencyList', - // Indicates whether an update is available and ready to beinstalled. + // Indicates whether an update is available and ready to be installed. UPDATE_AVAILABLE: 'updateAvailable', + // Indicates that a request to join a screen share with a GuidesPlus agent was received + SCREEN_SHARE_REQUEST: 'screenShareRequest', + // Saves the current country code which is displayed when the user types a phone number without // an international code COUNTRY_CODE: 'countryCode', diff --git a/src/languages/en.js b/src/languages/en.js index e4ee9f8fb9bd..ec2d7c206b2b 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -90,6 +90,8 @@ export default { debitCard: 'Debit card', payPalMe: 'PayPal.me', bankAccount: 'Bank account', + join: 'Join', + decline: 'Decline', }, attachmentPicker: { cameraPermissionRequired: 'Camera permission required', @@ -194,7 +196,6 @@ export default { viewDetails: 'View details', settleExpensify: 'Pay with Expensify', settleElsewhere: 'I\'ll settle up elsewhere', - decline: 'Decline', settlePaypalMe: 'Pay with PayPal.me', settleVenmo: 'Pay with Venmo', request: ({amount}) => `Request ${amount}`, @@ -818,4 +819,8 @@ export default { newGroup: 'New group screen', }, }, + guides: { + screenShare: 'Screen share', + screenShareRequest: 'Expensify is inviting you to a screen share', + }, }; diff --git a/src/languages/es.js b/src/languages/es.js index 932e74d8de52..59561df79595 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -90,6 +90,8 @@ export default { debitCard: 'Tarjeta de débito', payPalMe: 'PayPal.me', bankAccount: 'Cuenta bancaria', + join: 'Unirse', + decline: 'Rechazar', }, attachmentPicker: { cameraPermissionRequired: 'Se necesita permiso para usar la cámara', @@ -194,7 +196,6 @@ export default { viewDetails: 'Ver detalles', settleExpensify: 'Pagar con Expensify', settleElsewhere: 'Voy a pagar de otra forma', - decline: 'Rechazar', settlePaypalMe: 'Pagar con PayPal.me', settleVenmo: 'Pagar con Venmo', request: ({amount}) => `Solicitar ${amount}`, @@ -820,4 +821,8 @@ export default { newGroup: 'Nueva pantalla de grupo', }, }, + guides: { + screenShare: 'Compartir pantalla', + screenShareRequest: 'Expensify te está invitando a compartir la pantalla', + }, }; diff --git a/src/libs/Pusher/EventType.js b/src/libs/Pusher/EventType.js index b65ca8e7d7ac..f23d5b6863ba 100644 --- a/src/libs/Pusher/EventType.js +++ b/src/libs/Pusher/EventType.js @@ -10,4 +10,5 @@ export default { REPORT_TOGGLE_PINNED: 'reportTogglePinned', PREFERRED_LOCALE: 'preferredLocale', EXPENSIFY_CARD_UPDATE: 'expensifyCardUpdate', + SCREEN_SHARE_REQUEST: 'screenshareRequest', }; diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index dc61916e877f..c87c0849b632 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -14,6 +14,7 @@ import Log from '../Log'; import NetworkConnection from '../NetworkConnection'; import NameValuePair from './NameValuePair'; import getSkinToneEmojiFromIndex from '../../pages/home/report/EmojiPickerMenu/getSkinToneEmojiFromIndex'; +import * as Link from './Link'; let sessionAuthToken = ''; let sessionEmail = ''; @@ -279,6 +280,14 @@ function subscribeToUserEvents() { {error, pusherChannelName, eventName: Pusher.TYPE.PREFERRED_LOCALE}, ); }); + + // Subscribe to screen share requests sent by GuidesPlus agents + Pusher.subscribe(pusherChannelName, Pusher.TYPE.SCREEN_SHARE_REQUEST, (pushJSON) => { + Onyx.merge(ONYXKEYS.SCREEN_SHARE_REQUEST, pushJSON); + }, false, + () => { + NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel'); + }); } /** @@ -341,6 +350,23 @@ function clearUserErrorMessage() { Onyx.merge(ONYXKEYS.USER, {error: ''}); } +/** + * Clear the data about a screen share request from Onyx. + */ +function clearScreenShareRequest() { + Onyx.set(ONYXKEYS.SCREEN_SHARE_REQUEST, null); +} + +/** + * Open an OldDot tab linking to a screen share request. + * @param {String} accessToken Access token required to join a screen share room, generated by the backend + * @param {String} roomName Name of the screen share room to join + */ +function joinScreenShare(accessToken, roomName) { + Link.openOldDotLink(`inbox?action=screenShare&accessToken=${accessToken}&name=${roomName}`); + clearScreenShareRequest(); +} + export { changePasswordAndNavigate, getBetas, @@ -357,4 +383,6 @@ export { clearUserErrorMessage, subscribeToExpensifyCardUpdates, setFrequentlyUsedEmojis, + joinScreenShare, + clearScreenShareRequest, }; diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js index 00e87170d7a4..1532697fc1f3 100644 --- a/src/pages/iou/IOUTransactions.js +++ b/src/pages/iou/IOUTransactions.js @@ -92,7 +92,7 @@ class IOUTransactions extends Component { canBeRejected={canBeRejected} rejectButtonLabelText={isCurrentUserTransactionCreator ? this.props.translate('common.cancel') - : this.props.translate('iou.decline')} + : this.props.translate('common.decline')} /> ); })}