From 78aef7320e93bca9efb3fc93cce7225c65b38690 Mon Sep 17 00:00:00 2001 From: Djorkaeff Alexandre Date: Tue, 18 Feb 2020 12:56:02 -0300 Subject: [PATCH] [FIX] UIKit submit when connection lost (#1748) --- app/lib/Navigation.js | 7 +++++++ app/lib/methods/actions.js | 25 ++++++++++--------------- app/views/ModalBlockView.js | 29 +++++++++++++++++------------ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/app/lib/Navigation.js b/app/lib/Navigation.js index 23281225..252c6ed9 100644 --- a/app/lib/Navigation.js +++ b/app/lib/Navigation.js @@ -6,6 +6,12 @@ function setTopLevelNavigator(navigatorRef) { _navigator = navigatorRef; } +function back() { + _navigator.dispatch( + NavigationActions.back() + ); +} + function navigate(routeName, params) { _navigator.dispatch( NavigationActions.navigate({ @@ -16,6 +22,7 @@ function navigate(routeName, params) { } export default { + back, navigate, setTopLevelNavigator }; diff --git a/app/lib/methods/actions.js b/app/lib/methods/actions.js index e2ac9697..5bd7e107 100644 --- a/app/lib/methods/actions.js +++ b/app/lib/methods/actions.js @@ -2,8 +2,6 @@ import random from '../../utils/random'; import EventEmitter from '../../utils/events'; import Navigation from '../Navigation'; -const TRIGGER_TIMEOUT = 5000; - const ACTION_TYPES = { ACTION: 'blockAction', SUBMIT: 'viewSubmit', @@ -34,7 +32,7 @@ const invalidateTriggerId = (id) => { export const generateTriggerId = (appId) => { const triggerId = random(17); triggersId.set(triggerId, appId); - setTimeout(invalidateTriggerId, TRIGGER_TIMEOUT, triggerId); + return triggerId; }; @@ -105,12 +103,10 @@ export function triggerAction({ const payload = rest.payload || rest; - setTimeout(reject, TRIGGER_TIMEOUT, triggerId); - - const { userId, authToken } = this.sdk.currentLogin; - const { host } = this.sdk.client; - try { + const { userId, authToken } = this.sdk.currentLogin; + const { host } = this.sdk.client; + // we need to use fetch because this.sdk.post add /v1 to url const result = await fetch(`${ host }/api/apps/ui.interaction/${ appId }/`, { method: 'POST', @@ -133,11 +129,7 @@ export function triggerAction({ try { const { type: interactionType, ...data } = await result.json(); - handlePayloadUserInteraction(interactionType, data); - - if (data.success) { - return resolve(); - } + return resolve(handlePayloadUserInteraction(interactionType, data)); } catch (e) { // modal.close has no body, so result.json will fail // but it returns ok status @@ -156,8 +148,11 @@ export default function triggerBlockAction(options) { return triggerAction.call(this, { type: ACTION_TYPES.ACTION, ...options }); } -export function triggerSubmitView({ viewId, ...options }) { - return triggerAction.call(this, { type: ACTION_TYPES.SUBMIT, viewId, ...options }); +export async function triggerSubmitView({ viewId, ...options }) { + const result = await triggerAction.call(this, { type: ACTION_TYPES.SUBMIT, viewId, ...options }); + if (!result || MODAL_ACTIONS.CLOSE === result) { + Navigation.back(); + } } export function triggerCancel({ view, ...options }) { diff --git a/app/views/ModalBlockView.js b/app/views/ModalBlockView.js index 2a6350de..e00c8493 100644 --- a/app/views/ModalBlockView.js +++ b/app/views/ModalBlockView.js @@ -17,6 +17,7 @@ import { MODAL_ACTIONS, CONTAINER_TYPES } from '../lib/methods/actions'; import sharedStyles from './Styles'; import { textParser } from '../containers/UIKit/utils'; +import Navigation from '../lib/Navigation'; const styles = StyleSheet.create({ container: { @@ -60,6 +61,7 @@ class ModalBlockView extends React.Component { const { theme, closeModal } = screenProps; const data = navigation.getParam('data'); const cancel = navigation.getParam('cancel', () => {}); + const submitting = navigation.getParam('submitting', false); const { view } = data; const { title, submit, close } = view; return { @@ -70,7 +72,7 @@ class ModalBlockView extends React.Component { cancel({ closeModal })} + onPress={!submitting && (() => cancel({ closeModal }))} testID='close-modal-uikit' /> @@ -80,7 +82,7 @@ class ModalBlockView extends React.Component { {})} + onPress={!submitting && (navigation.getParam('submit', () => {}))} testID='submit-modal-uikit' /> @@ -100,6 +102,7 @@ class ModalBlockView extends React.Component { constructor(props) { super(props); + this.submitting = false; const { navigation } = props; const data = navigation.getParam('data'); this.values = data.view.blocks.filter(filterInputFields).map(mapElementToState).reduce(reduceState, {}); @@ -155,9 +158,15 @@ class ModalBlockView extends React.Component { cancel = async({ closeModal }) => { const { data } = this.state; - const { navigation } = this.props; const { appId, viewId, view } = data; - this.setState({ loading: true }); + + // handle tablet case + if (closeModal) { + closeModal(); + } else { + Navigation.back(); + } + try { await RocketChat.triggerCancel({ appId, @@ -172,18 +181,13 @@ class ModalBlockView extends React.Component { } catch (e) { // do nothing } - // handle tablet case - if (closeModal) { - closeModal(); - } else { - navigation.pop(); - } - this.setState({ loading: false }); } submit = async() => { const { data } = this.state; const { navigation } = this.props; + navigation.setParams({ submitting: true }); + const { appId, viewId } = data; this.setState({ loading: true }); try { @@ -197,10 +201,11 @@ class ModalBlockView extends React.Component { } } }); - navigation.pop(); } catch (e) { // do nothing } + + navigation.setParams({ submitting: false }); this.setState({ loading: false }); };