MM-56899 - prevent app block when setting custom status if no internet (#8283)

* MM-56899 - prevent app block when setting custom status if no internet

* remove alert and use build in error message

* remove unused translations

* implement pr feedback

* keep function in local file

* remove unnecessary change

* fix placeholder position

* block the done button while the server replies

* add close button to the modal
This commit is contained in:
Pablo Vélez 2024-12-05 15:53:54 -05:00 committed by GitHub
parent 9632ce5038
commit 8b9779d4b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 21 deletions

View file

@ -22,4 +22,3 @@ const useNavButtonPressed = (navButtonId: string, componentId: string, callback:
};
export default useNavButtonPressed;

View file

@ -3,7 +3,7 @@
import React from 'react';
import {useIntl} from 'react-intl';
import {TextInput, View} from 'react-native';
import {Platform, TextInput, View} from 'react-native';
import ClearButton from '@components/custom_status/clear_button';
import {CUSTOM_STATUS_TEXT_CHARACTER_LIMIT} from '@constants/custom_status';
@ -35,7 +35,14 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
color: theme.centerChannelColor,
flex: 1,
paddingHorizontal: 16,
textAlignVertical: 'center',
...Platform.select({
ios: {
paddingVertical: 25,
},
android: {
textAlignVertical: 'center',
},
}),
height: '100%',
...typography('Body', 200, 'Regular'),
},

View file

@ -2,13 +2,15 @@
// See LICENSE.txt for license information.
import moment from 'moment-timezone';
import React, {useCallback, useEffect, useMemo, useReducer} from 'react';
import React, {useCallback, useEffect, useMemo, useReducer, useState} from 'react';
import {useIntl} from 'react-intl';
import {DeviceEventEmitter, Keyboard, KeyboardAvoidingView, Platform, ScrollView, View} from 'react-native';
import {type Options} from 'react-native-navigation';
import {type Edge, SafeAreaView} from 'react-native-safe-area-context';
import {updateLocalCustomStatus} from '@actions/local/user';
import {removeRecentCustomStatus, updateCustomStatus, unsetCustomStatus} from '@actions/remote/user';
import CompassIcon from '@components/compass_icon';
import TabletTitle from '@components/tablet_title';
import {Events, Screens} from '@constants';
import {CustomStatusDurationEnum, SET_CUSTOM_STATUS_FAILURE} from '@constants/custom_status';
@ -145,6 +147,17 @@ function reducer(state: NewStatusType, action: {
}
}
const dismissModalAndKeyboard = (isTablet: boolean, options?: Options & { componentId: AvailableScreens}) => {
if (isTablet) {
DeviceEventEmitter.emit(Events.ACCOUNT_SELECT_TABLET_VIEW, '');
} else {
dismissModal(options);
}
Keyboard.dismiss();
};
const closeCustomStatusModalId = 'close-custom-status';
const CustomStatus = ({
customStatusExpirySupported,
currentUser,
@ -156,7 +169,10 @@ const CustomStatus = ({
const theme = useTheme();
const style = getStyleSheet(theme);
const serverUrl = useServerUrl();
const [isBtnEnabled, setIsBtnEnabled] = useState(true);
useNavButtonPressed('close-custom-status', componentId, () => {
dismissModalAndKeyboard(isTablet, {componentId});
}, [componentId, isTablet]);
const storedStatus = useMemo(() => {
return getUserCustomStatus(currentUser);
}, [currentUser]);
@ -222,6 +238,7 @@ const CustomStatus = ({
initialDuration: newStatus.duration,
intl,
theme,
closeButtonId: 'close-custom-status',
};
if (isTablet) {
@ -242,6 +259,7 @@ const CustomStatus = ({
if (!currentUser) {
return;
}
setIsBtnEnabled(false);
if (isStatusSet) {
let isStatusSame =
@ -264,12 +282,15 @@ const CustomStatus = ({
status.duration = newStatus.duration;
status.expires_at = newExpiresAt;
}
const {error} = await updateCustomStatus(serverUrl, status);
if (error) {
dismissModalAndKeyboard(isTablet, {componentId});
DeviceEventEmitter.emit(SET_CUSTOM_STATUS_FAILURE);
setIsBtnEnabled(true);
return;
}
setIsBtnEnabled(true);
updateLocalCustomStatus(serverUrl, currentUser, status);
dispatchStatus({type: 'fromUserCustomStatus', status});
}
@ -280,13 +301,8 @@ const CustomStatus = ({
updateLocalCustomStatus(serverUrl, currentUser, undefined);
}
}
Keyboard.dismiss();
if (isTablet) {
DeviceEventEmitter.emit(Events.ACCOUNT_SELECT_TABLET_VIEW, '');
} else {
dismissModal();
}
}, [newStatus, isStatusSet, storedStatus, currentUser]);
dismissModalAndKeyboard(isTablet, {componentId});
}, [newStatus, isStatusSet, storedStatus, currentUser, isTablet]);
const openEmojiPicker = useCallback(preventDoubleTap(() => {
openAsBottomSheet({
@ -299,22 +315,19 @@ const CustomStatus = ({
}), [theme, intl, handleEmojiClick]);
const handleBackButton = useCallback(() => {
if (isTablet) {
DeviceEventEmitter.emit(Events.ACCOUNT_SELECT_TABLET_VIEW, '');
} else {
dismissModal({componentId});
}
dismissModalAndKeyboard(isTablet, {componentId});
}, [componentId, isTablet]);
useAndroidHardwareBackHandler(componentId, handleBackButton);
useNavButtonPressed(BTN_UPDATE_STATUS, componentId, handleSetStatus, [handleSetStatus]);
useEffect(() => {
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
mergeNavigationOptions(componentId, {
topBar: {
rightButtons: [
{
enabled: true,
enabled: isBtnEnabled,
id: BTN_UPDATE_STATUS,
showAsAction: 'always',
testID: 'custom_status.done.button',
@ -322,9 +335,14 @@ const CustomStatus = ({
color: theme.sidebarHeaderTextColor,
},
],
leftButtons: [{
id: closeCustomStatusModalId,
icon: closeButton,
testID: 'close.custom_status.button',
}],
},
});
}, []);
}, [isBtnEnabled]);
return (
<>

View file

@ -10,6 +10,7 @@ import CustomStatusExpiry from '@components/custom_status/custom_status_expiry';
import FormattedText from '@components/formatted_text';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import CustomStatusText from './custom_status_text';
@ -38,8 +39,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
color: changeOpacity(theme.centerChannelColor, 0.35),
},
retryMessage: {
position: 'absolute',
top: 25,
left: 40,
color: theme.errorTextColor,
paddingBottom: 25,
...typography('Body', 100),
},
};
});