[IMPROVE] Migrate away from react-native-prompt-android to action sheet (#4300)
* Chore: Migrate away from react-native-prompt-android to action sheet * fix header provile view with action sheet * finished change password * Close livechat and removed closeRoom dispatch * remove lib react-native-prompt-android * fix right buttons * fix profile view in tablets * fix action and room action for tablets * remove onSubmitEditing * fix keyboard for android tablet in landscape * create base for actionSheet containers * migrate EnterPasswordSheet to base * migrate to base component * fix colors and copy * remove secure entry * fix onSubmit * fix android animation Co-authored-by: GleidsonDaniel <gleidson10daniel@hotmail.com>
This commit is contained in:
parent
1e9ae6e157
commit
18c44178d7
|
@ -27,7 +27,6 @@ export const ROOM = createRequestTypes('ROOM', [
|
||||||
'LEAVE',
|
'LEAVE',
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'REMOVED',
|
'REMOVED',
|
||||||
'CLOSE',
|
|
||||||
'FORWARD',
|
'FORWARD',
|
||||||
'USER_TYPING'
|
'USER_TYPING'
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -19,7 +19,6 @@ interface IBaseReturn extends Action {
|
||||||
|
|
||||||
type TSubscribeRoom = IBaseReturn;
|
type TSubscribeRoom = IBaseReturn;
|
||||||
type TUnsubscribeRoom = IBaseReturn;
|
type TUnsubscribeRoom = IBaseReturn;
|
||||||
type TCloseRoom = IBaseReturn;
|
|
||||||
|
|
||||||
type TRoom = Record<string, any>;
|
type TRoom = Record<string, any>;
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ interface IUserTyping extends Action {
|
||||||
status: boolean;
|
status: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TActionsRoom = TSubscribeRoom & TUnsubscribeRoom & TCloseRoom & ILeaveRoom & IDeleteRoom & IForwardRoom & IUserTyping;
|
export type TActionsRoom = TSubscribeRoom & TUnsubscribeRoom & ILeaveRoom & IDeleteRoom & IForwardRoom & IUserTyping;
|
||||||
|
|
||||||
export function subscribeRoom(rid: string): TSubscribeRoom {
|
export function subscribeRoom(rid: string): TSubscribeRoom {
|
||||||
return {
|
return {
|
||||||
|
@ -79,13 +78,6 @@ export function deleteRoom(roomType: ERoomType, room: TRoom, selected?: ISelecte
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function closeRoom(rid: string): TCloseRoom {
|
|
||||||
return {
|
|
||||||
type: ROOM.CLOSE,
|
|
||||||
rid
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function forwardRoom(rid: string, transferData: ITransferData): IForwardRoom {
|
export function forwardRoom(rid: string, transferData: ITransferData): IForwardRoom {
|
||||||
return {
|
return {
|
||||||
type: ROOM.FORWARD,
|
type: ROOM.FORWARD,
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
|
|
||||||
|
import { CustomIcon, TIconsName } from '../../CustomIcon';
|
||||||
|
import i18n from '../../../i18n';
|
||||||
|
import { isIOS } from '../../../lib/methods/helpers';
|
||||||
|
import { useTheme } from '../../../theme';
|
||||||
|
import sharedStyles from '../../../views/Styles';
|
||||||
|
import Button from '../../Button';
|
||||||
|
import { FormTextInput } from '../../TextInput/FormTextInput';
|
||||||
|
import { useActionSheet } from '../Provider';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
subtitleText: {
|
||||||
|
fontSize: 14,
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
marginBottom: 10
|
||||||
|
},
|
||||||
|
buttonSeparator: {
|
||||||
|
marginRight: 8
|
||||||
|
},
|
||||||
|
footerButtonsContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
paddingTop: 16
|
||||||
|
},
|
||||||
|
titleContainerText: {
|
||||||
|
fontSize: 16,
|
||||||
|
...sharedStyles.textSemibold
|
||||||
|
},
|
||||||
|
titleContainer: {
|
||||||
|
paddingRight: 80,
|
||||||
|
marginBottom: 16,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const FooterButtons = ({
|
||||||
|
cancelAction = () => {},
|
||||||
|
confirmAction = () => {},
|
||||||
|
cancelTitle = '',
|
||||||
|
confirmTitle = '',
|
||||||
|
disabled = false,
|
||||||
|
cancelBackgroundColor = '',
|
||||||
|
confirmBackgroundColor = ''
|
||||||
|
}): React.ReactElement => {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
return (
|
||||||
|
<View style={styles.footerButtonsContainer}>
|
||||||
|
<Button
|
||||||
|
style={[styles.buttonSeparator, { flex: 1, backgroundColor: cancelBackgroundColor || colors.cancelButton }]}
|
||||||
|
color={colors.backdropColor}
|
||||||
|
title={cancelTitle}
|
||||||
|
onPress={cancelAction}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
style={{ flex: 1, backgroundColor: confirmBackgroundColor || colors.dangerColor }}
|
||||||
|
title={confirmTitle}
|
||||||
|
onPress={confirmAction}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ActionSheetContentWithInputAndSubmit = ({
|
||||||
|
onSubmit = () => {},
|
||||||
|
onCancel,
|
||||||
|
title = '',
|
||||||
|
description = '',
|
||||||
|
testID = '',
|
||||||
|
secureTextEntry = true,
|
||||||
|
placeholder = '',
|
||||||
|
confirmTitle,
|
||||||
|
iconName,
|
||||||
|
iconColor,
|
||||||
|
customText,
|
||||||
|
confirmBackgroundColor
|
||||||
|
}: {
|
||||||
|
onSubmit: (inputValue: string) => void;
|
||||||
|
onCancel?: () => void;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
testID: string;
|
||||||
|
secureTextEntry?: boolean;
|
||||||
|
placeholder: string;
|
||||||
|
confirmTitle?: string;
|
||||||
|
iconName?: TIconsName;
|
||||||
|
iconColor?: string;
|
||||||
|
customText?: React.ReactElement;
|
||||||
|
confirmBackgroundColor?: string;
|
||||||
|
}): React.ReactElement => {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const [inputValue, setInputValue] = useState('');
|
||||||
|
const { hideActionSheet } = useActionSheet();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={sharedStyles.containerScrollView}>
|
||||||
|
<>
|
||||||
|
<View style={styles.titleContainer}>
|
||||||
|
{iconName ? <CustomIcon name={iconName} size={32} color={iconColor || colors.dangerColor} /> : null}
|
||||||
|
<Text style={[styles.titleContainerText, { color: colors.passcodePrimary, paddingLeft: iconName ? 16 : 0 }]}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text style={[styles.subtitleText, { color: colors.titleText }]}>{description}</Text>
|
||||||
|
{customText}
|
||||||
|
</>
|
||||||
|
<FormTextInput
|
||||||
|
value={inputValue}
|
||||||
|
placeholder={placeholder}
|
||||||
|
onChangeText={value => setInputValue(value)}
|
||||||
|
onSubmitEditing={() => {
|
||||||
|
// fix android animation
|
||||||
|
setTimeout(() => {
|
||||||
|
hideActionSheet();
|
||||||
|
}, 100);
|
||||||
|
if (inputValue) onSubmit(inputValue);
|
||||||
|
}}
|
||||||
|
testID={testID}
|
||||||
|
secureTextEntry={secureTextEntry}
|
||||||
|
inputStyle={{ borderWidth: 2 }}
|
||||||
|
bottomSheet={isIOS}
|
||||||
|
/>
|
||||||
|
<FooterButtons
|
||||||
|
confirmBackgroundColor={confirmBackgroundColor || colors.actionTintColor}
|
||||||
|
cancelAction={onCancel || hideActionSheet}
|
||||||
|
confirmAction={() => onSubmit(inputValue)}
|
||||||
|
cancelTitle={i18n.t('Cancel')}
|
||||||
|
confirmTitle={confirmTitle || i18n.t('Save')}
|
||||||
|
disabled={!inputValue}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActionSheetContentWithInputAndSubmit;
|
|
@ -1,36 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { View } from 'react-native';
|
|
||||||
|
|
||||||
import Button from '../Button';
|
|
||||||
import { useTheme } from '../../theme';
|
|
||||||
import styles from './styles';
|
|
||||||
|
|
||||||
const FooterButtons = ({
|
|
||||||
cancelAction = () => {},
|
|
||||||
confirmAction = () => {},
|
|
||||||
cancelTitle = '',
|
|
||||||
confirmTitle = '',
|
|
||||||
disabled = false,
|
|
||||||
cancelBackgroundColor = '',
|
|
||||||
confirmBackgroundColor = ''
|
|
||||||
}): React.ReactElement => {
|
|
||||||
const { colors } = useTheme();
|
|
||||||
return (
|
|
||||||
<View style={styles.footerButtonsContainer}>
|
|
||||||
<Button
|
|
||||||
style={[styles.buttonSeparator, { flex: 1, backgroundColor: cancelBackgroundColor || colors.cancelButton }]}
|
|
||||||
color={colors.backdropColor}
|
|
||||||
title={cancelTitle}
|
|
||||||
onPress={cancelAction}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
style={{ flex: 1, backgroundColor: confirmBackgroundColor || colors.dangerColor }}
|
|
||||||
title={confirmTitle}
|
|
||||||
onPress={confirmAction}
|
|
||||||
disabled={disabled}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FooterButtons;
|
|
|
@ -63,12 +63,5 @@ export default StyleSheet.create({
|
||||||
},
|
},
|
||||||
rightContainer: {
|
rightContainer: {
|
||||||
paddingLeft: 12
|
paddingLeft: 12
|
||||||
},
|
|
||||||
footerButtonsContainer: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
paddingTop: 16
|
|
||||||
},
|
|
||||||
buttonSeparator: {
|
|
||||||
marginRight: 8
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import ActionSheetContentWithInputAndSubmit from '../../../../containers/ActionSheet/ActionSheetContentWithInputAndSubmit';
|
||||||
|
import I18n from '../../../../i18n';
|
||||||
|
|
||||||
|
const CloseLivechatSheet = ({
|
||||||
|
onSubmit = () => {},
|
||||||
|
onCancel = () => {}
|
||||||
|
}: {
|
||||||
|
onSubmit: (comment: string) => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
}) => (
|
||||||
|
<ActionSheetContentWithInputAndSubmit
|
||||||
|
title={I18n.t('Closing_chat')}
|
||||||
|
description={I18n.t('Please_add_a_comment')}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
testID='room-actions-view-close-livechat'
|
||||||
|
placeholder=''
|
||||||
|
secureTextEntry={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default CloseLivechatSheet;
|
|
@ -9,6 +9,5 @@ declare module 'react-native-config-reader';
|
||||||
declare module 'react-native-keycommands';
|
declare module 'react-native-keycommands';
|
||||||
declare module 'react-native-mime-types';
|
declare module 'react-native-mime-types';
|
||||||
declare module 'react-native-restart';
|
declare module 'react-native-restart';
|
||||||
declare module 'react-native-prompt-android';
|
|
||||||
declare module 'react-native-jitsi-meet';
|
declare module 'react-native-jitsi-meet';
|
||||||
declare module 'rn-root-view';
|
declare module 'rn-root-view';
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import I18n from '../../../i18n';
|
||||||
|
import Navigation from '../../navigation/appNavigation';
|
||||||
|
import { Services } from '../../services';
|
||||||
|
import { showErrorAlert } from './info';
|
||||||
|
import log from './log';
|
||||||
|
|
||||||
|
export const closeLivechat = async ({
|
||||||
|
rid,
|
||||||
|
comment,
|
||||||
|
isMasterDetail
|
||||||
|
}: {
|
||||||
|
rid: string;
|
||||||
|
isMasterDetail: boolean;
|
||||||
|
comment?: string;
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
await Services.closeLivechat(rid, comment);
|
||||||
|
if (isMasterDetail) {
|
||||||
|
Navigation.navigate('DrawerNavigator');
|
||||||
|
} else {
|
||||||
|
Navigation.navigate('RoomsListView');
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
showErrorAlert(I18n.isTranslated(e.error) ? I18n.t(e.error) : e.reason, I18n.t('Oops'));
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
};
|
|
@ -347,7 +347,7 @@ export const getTeamListRoom = ({
|
||||||
return sdk.get('teams.listRooms', params);
|
return sdk.get('teams.listRooms', params);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const closeLivechat = (rid: string, comment: string) =>
|
export const closeLivechat = (rid: string, comment?: string) =>
|
||||||
// RC 0.29.0
|
// RC 0.29.0
|
||||||
sdk.methodCallWrapper('livechat:closeRoom', rid, comment, { clientAction: true });
|
sdk.methodCallWrapper('livechat:closeRoom', rid, comment, { clientAction: true });
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { closeRoom, deleteRoom, forwardRoom, leaveRoom, removedRoom, subscribeRoom, unsubscribeRoom } from '../actions/room';
|
import { deleteRoom, forwardRoom, leaveRoom, removedRoom, subscribeRoom, unsubscribeRoom } from '../actions/room';
|
||||||
import { ERoomType } from '../definitions/ERoomType';
|
import { ERoomType } from '../definitions/ERoomType';
|
||||||
import { mockedStore } from './mockedStore';
|
import { mockedStore } from './mockedStore';
|
||||||
import { initialState } from './room';
|
import { initialState } from './room';
|
||||||
|
@ -35,13 +35,6 @@ describe('test room reducer', () => {
|
||||||
expect(isDeleting).toEqual(true);
|
expect(isDeleting).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return initial state after closeRoom', () => {
|
|
||||||
mockedStore.dispatch(closeRoom('CLOSING'));
|
|
||||||
const { rid, isDeleting } = mockedStore.getState().room;
|
|
||||||
expect(rid).toEqual('CLOSING');
|
|
||||||
expect(isDeleting).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return initial state after forwardRoom', () => {
|
it('should return initial state after forwardRoom', () => {
|
||||||
const transferData = { roomId: 'FORWARDING' };
|
const transferData = { roomId: 'FORWARDING' };
|
||||||
mockedStore.dispatch(forwardRoom('FORWARDING', transferData));
|
mockedStore.dispatch(forwardRoom('FORWARDING', transferData));
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Alert } from 'react-native';
|
import { Alert } from 'react-native';
|
||||||
import prompt from 'react-native-prompt-android';
|
|
||||||
import { delay, put, race, select, take, takeLatest } from 'redux-saga/effects';
|
import { delay, put, race, select, take, takeLatest } from 'redux-saga/effects';
|
||||||
|
|
||||||
import EventEmitter from '../lib/methods/helpers/events';
|
import EventEmitter from '../lib/methods/helpers/events';
|
||||||
|
@ -110,44 +109,6 @@ const handleDeleteRoom = function* handleDeleteRoom({ room, roomType, selected }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseRoom = function* handleCloseRoom({ rid }) {
|
|
||||||
const isMasterDetail = yield select(state => state.app.isMasterDetail);
|
|
||||||
const requestComment = yield select(state => state.settings.Livechat_request_comment_when_closing_conversation);
|
|
||||||
|
|
||||||
const closeRoom = async (comment = '') => {
|
|
||||||
try {
|
|
||||||
await Services.closeLivechat(rid, comment);
|
|
||||||
if (isMasterDetail) {
|
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
Navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!requestComment) {
|
|
||||||
const comment = I18n.t('Chat_closed_by_agent');
|
|
||||||
return closeRoom(comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
prompt(
|
|
||||||
I18n.t('Closing_chat'),
|
|
||||||
I18n.t('Please_add_a_comment'),
|
|
||||||
[
|
|
||||||
{ text: I18n.t('Cancel'), onPress: () => {}, style: 'cancel' },
|
|
||||||
{
|
|
||||||
text: I18n.t('Submit'),
|
|
||||||
onPress: comment => closeRoom(comment)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
{
|
|
||||||
cancelable: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleForwardRoom = function* handleForwardRoom({ transferData }) {
|
const handleForwardRoom = function* handleForwardRoom({ transferData }) {
|
||||||
try {
|
try {
|
||||||
const result = yield Services.forwardLivechat(transferData);
|
const result = yield Services.forwardLivechat(transferData);
|
||||||
|
@ -170,7 +131,6 @@ const root = function* root() {
|
||||||
yield takeLatest(types.ROOM.USER_TYPING, watchUserTyping);
|
yield takeLatest(types.ROOM.USER_TYPING, watchUserTyping);
|
||||||
yield takeLatest(types.ROOM.LEAVE, handleLeaveRoom);
|
yield takeLatest(types.ROOM.LEAVE, handleLeaveRoom);
|
||||||
yield takeLatest(types.ROOM.DELETE, handleDeleteRoom);
|
yield takeLatest(types.ROOM.DELETE, handleDeleteRoom);
|
||||||
yield takeLatest(types.ROOM.CLOSE, handleCloseRoom);
|
|
||||||
yield takeLatest(types.ROOM.FORWARD, handleForwardRoom);
|
yield takeLatest(types.ROOM.FORWARD, handleForwardRoom);
|
||||||
};
|
};
|
||||||
export default root;
|
export default root;
|
||||||
|
|
|
@ -119,11 +119,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
|
||||||
<ModalContainer navigation={navigation} theme={theme}>
|
<ModalContainer navigation={navigation} theme={theme}>
|
||||||
<ModalStack.Navigator
|
<ModalStack.Navigator
|
||||||
screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation } as StackNavigationOptions}>
|
screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation } as StackNavigationOptions}>
|
||||||
<ModalStack.Screen
|
<ModalStack.Screen name='RoomActionsView' component={RoomActionsView} />
|
||||||
name='RoomActionsView'
|
|
||||||
component={RoomActionsView}
|
|
||||||
options={props => RoomActionsView.navigationOptions!({ ...props, isMasterDetail: true })}
|
|
||||||
/>
|
|
||||||
<ModalStack.Screen name='RoomInfoView' component={RoomInfoView} options={RoomInfoView.navigationOptions} />
|
<ModalStack.Screen name='RoomInfoView' component={RoomInfoView} options={RoomInfoView.navigationOptions} />
|
||||||
<ModalStack.Screen name='SelectListView' component={SelectListView} />
|
<ModalStack.Screen name='SelectListView' component={SelectListView} />
|
||||||
<ModalStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
<ModalStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
||||||
|
|
|
@ -1,41 +1,27 @@
|
||||||
import { sha256 } from 'js-sha256';
|
import { sha256 } from 'js-sha256';
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { Keyboard, Text, View } from 'react-native';
|
import { Keyboard, Text } from 'react-native';
|
||||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import { deleteAccount } from '../../../../actions/login';
|
import { deleteAccount } from '../../../../actions/login';
|
||||||
import { useActionSheet } from '../../../../containers/ActionSheet';
|
import { useActionSheet } from '../../../../containers/ActionSheet';
|
||||||
import FooterButtons from '../../../../containers/ActionSheet/FooterButtons';
|
import ActionSheetContentWithInputAndSubmit from '../../../../containers/ActionSheet/ActionSheetContentWithInputAndSubmit';
|
||||||
import { CustomIcon } from '../../../../containers/CustomIcon';
|
|
||||||
import { FormTextInput } from '../../../../containers/TextInput/FormTextInput';
|
|
||||||
import i18n from '../../../../i18n';
|
import i18n from '../../../../i18n';
|
||||||
import { showErrorAlert } from '../../../../lib/methods/helpers';
|
import { showErrorAlert } from '../../../../lib/methods/helpers';
|
||||||
import { events, logEvent } from '../../../../lib/methods/helpers/log';
|
import { events, logEvent } from '../../../../lib/methods/helpers/log';
|
||||||
import { deleteOwnAccount } from '../../../../lib/services/restApi';
|
import { deleteOwnAccount } from '../../../../lib/services/restApi';
|
||||||
import { useTheme } from '../../../../theme';
|
import { useTheme } from '../../../../theme';
|
||||||
import { getTranslations } from './getTranslations';
|
import { getTranslations } from './getTranslations';
|
||||||
import styles from './styles';
|
import sharedStyles from '../../../Styles';
|
||||||
|
|
||||||
const AlertHeader = ({ title = '', subTitle = '' }) => {
|
|
||||||
const { colors } = useTheme();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<View style={styles.titleContainer}>
|
|
||||||
<CustomIcon name='warning' size={32} color={colors.dangerColor} />
|
|
||||||
<Text style={[styles.titleContainerText, { color: colors.passcodePrimary }]}>{title}</Text>
|
|
||||||
</View>
|
|
||||||
<Text style={[styles.subTitleContainerText, { color: colors.passcodePrimary }]}>{subTitle}</Text>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function DeleteAccountActionSheetContent(): React.ReactElement {
|
export function DeleteAccountActionSheetContent(): React.ReactElement {
|
||||||
const [password, setPassword] = useState('');
|
|
||||||
const { hideActionSheet, showActionSheet } = useActionSheet();
|
const { hideActionSheet, showActionSheet } = useActionSheet();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
const handleDeleteAccount = async () => {
|
const { colors } = useTheme();
|
||||||
|
|
||||||
|
const handleDeleteAccount = async (password: string) => {
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
try {
|
try {
|
||||||
await deleteOwnAccount(sha256(password));
|
await deleteOwnAccount(sha256(password));
|
||||||
|
@ -71,37 +57,29 @@ export function DeleteAccountActionSheetContent(): React.ReactElement {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<ActionSheetContentWithInputAndSubmit
|
||||||
<AlertHeader
|
title={i18n.t('Are_you_sure_you_want_to_delete_your_account')}
|
||||||
title={i18n.t('Are_you_sure_you_want_to_delete_your_account')}
|
description={i18n.t('For_your_security_you_must_enter_your_current_password_to_continue')}
|
||||||
subTitle={i18n.t('For_your_security_you_must_enter_your_current_password_to_continue')}
|
onCancel={hideActionSheet}
|
||||||
/>
|
onSubmit={password => handleDeleteAccount(password)}
|
||||||
<FormTextInput
|
placeholder={i18n.t('Password')}
|
||||||
value={password}
|
testID='room-info-edit-view-name'
|
||||||
placeholder={i18n.t('Password')}
|
iconName='warning'
|
||||||
onChangeText={value => setPassword(value)}
|
confirmTitle={i18n.t('Delete_Account')}
|
||||||
onSubmitEditing={handleDeleteAccount}
|
confirmBackgroundColor={colors.dangerColor}
|
||||||
testID='room-info-edit-view-name'
|
/>
|
||||||
secureTextEntry
|
|
||||||
inputStyle={{ borderWidth: 2 }}
|
|
||||||
bottomSheet
|
|
||||||
/>
|
|
||||||
<FooterButtons
|
|
||||||
cancelTitle={i18n.t('Cancel')}
|
|
||||||
cancelAction={hideActionSheet}
|
|
||||||
confirmTitle={i18n.t('Delete_Account')}
|
|
||||||
confirmAction={handleDeleteAccount}
|
|
||||||
disabled={!password}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConfirmDeleteAccountActionSheetContent({ changeOwnerRooms = '', removedRooms = '', password = '' }) {
|
const AlertText = ({ text = '' }) => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
return <Text style={{ fontSize: 14, ...sharedStyles.textRegular, marginBottom: 10, color: colors.dangerColor }}>{text}</Text>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ConfirmDeleteAccountActionSheetContent({ changeOwnerRooms = '', removedRooms = '', password = '' }) {
|
||||||
const { hideActionSheet } = useActionSheet();
|
const { hideActionSheet } = useActionSheet();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const { colors } = useTheme();
|
||||||
const handleDeleteAccount = async () => {
|
const handleDeleteAccount = async () => {
|
||||||
hideActionSheet();
|
hideActionSheet();
|
||||||
await deleteOwnAccount(password, true);
|
await deleteOwnAccount(password, true);
|
||||||
|
@ -109,18 +87,22 @@ function ConfirmDeleteAccountActionSheetContent({ changeOwnerRooms = '', removed
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<ActionSheetContentWithInputAndSubmit
|
||||||
<AlertHeader title={i18n.t('Are_you_sure_question_mark')} subTitle={i18n.t('Deleting_a_user_will_delete_all_messages')} />
|
title={i18n.t('Are_you_sure_question_mark')}
|
||||||
{!!changeOwnerRooms && (
|
iconName='warning'
|
||||||
<Text style={{ ...styles.subTitleContainerText, color: colors.dangerColor }}>{changeOwnerRooms}</Text>
|
description={i18n.t('Deleting_a_user_will_delete_all_messages')}
|
||||||
)}
|
onCancel={hideActionSheet}
|
||||||
{!!removedRooms && <Text style={{ ...styles.subTitleContainerText, color: colors.dangerColor }}>{removedRooms}</Text>}
|
onSubmit={handleDeleteAccount}
|
||||||
<FooterButtons
|
placeholder={i18n.t('Password')}
|
||||||
cancelTitle={i18n.t('Cancel')}
|
testID='room-info-edit-view-name'
|
||||||
cancelAction={hideActionSheet}
|
confirmTitle={i18n.t('Delete_Account_confirm')}
|
||||||
confirmTitle={i18n.t('Delete_Account_confirm')}
|
confirmBackgroundColor={colors.dangerColor}
|
||||||
confirmAction={handleDeleteAccount}
|
customText={
|
||||||
/>
|
<>
|
||||||
</View>
|
{!!changeOwnerRooms && <AlertText text={changeOwnerRooms} />}
|
||||||
|
{!!removedRooms && <AlertText text={removedRooms} />}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Keyboard, ScrollView, TextInput, View } from 'react-native';
|
import { Keyboard, ScrollView, TextInput, View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import prompt from 'react-native-prompt-android';
|
|
||||||
import { sha256 } from 'js-sha256';
|
import { sha256 } from 'js-sha256';
|
||||||
import ImagePicker, { Image } from 'react-native-image-crop-picker';
|
import ImagePicker, { Image } from 'react-native-image-crop-picker';
|
||||||
import RNPickerSelect from 'react-native-picker-select';
|
import RNPickerSelect from 'react-native-picker-select';
|
||||||
|
@ -45,6 +44,7 @@ import { twoFactor } from '../../lib/services/twoFactor';
|
||||||
import { TwoFactorMethods } from '../../definitions/ITotp';
|
import { TwoFactorMethods } from '../../definitions/ITotp';
|
||||||
import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
|
import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
|
||||||
import { DeleteAccountActionSheetContent } from './components/DeleteAccountActionSheetContent';
|
import { DeleteAccountActionSheetContent } from './components/DeleteAccountActionSheetContent';
|
||||||
|
import ActionSheetContentWithInputAndSubmit from '../../containers/ActionSheet/ActionSheetContentWithInputAndSubmit';
|
||||||
|
|
||||||
interface IProfileViewProps extends IActionSheetProvider, IBaseScreen<ProfileStackParamList, 'ProfileView'> {
|
interface IProfileViewProps extends IActionSheetProvider, IBaseScreen<ProfileStackParamList, 'ProfileView'> {
|
||||||
user: IUser;
|
user: IUser;
|
||||||
|
@ -250,26 +250,25 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
}
|
}
|
||||||
|
|
||||||
const requirePassword = !!params.email || newPassword;
|
const requirePassword = !!params.email || newPassword;
|
||||||
|
|
||||||
if (requirePassword && !params.currentPassword) {
|
if (requirePassword && !params.currentPassword) {
|
||||||
this.setState({ saving: false });
|
this.setState({ saving: false });
|
||||||
prompt(
|
this.props.showActionSheet({
|
||||||
I18n.t('Please_enter_your_password'),
|
children: (
|
||||||
I18n.t('For_your_security_you_must_enter_your_current_password_to_continue'),
|
<ActionSheetContentWithInputAndSubmit
|
||||||
[
|
title={I18n.t('Please_enter_your_password')}
|
||||||
{ text: I18n.t('Cancel'), onPress: () => {}, style: 'cancel' },
|
description={I18n.t('For_your_security_you_must_enter_your_current_password_to_continue')}
|
||||||
{
|
testID='profile-view-enter-password-sheet'
|
||||||
text: I18n.t('Save'),
|
placeholder={I18n.t('Password')}
|
||||||
onPress: (p: string) => {
|
onSubmit={(p: string) => {
|
||||||
this.setState({ currentPassword: p });
|
this.props.hideActionSheet();
|
||||||
this.submit();
|
this.setState({ currentPassword: p }, () => this.submit());
|
||||||
}
|
}}
|
||||||
}
|
onCancel={this.props.hideActionSheet}
|
||||||
],
|
/>
|
||||||
{
|
),
|
||||||
type: 'secure-text',
|
headerHeight: 225
|
||||||
cancelable: false
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,6 +660,7 @@ class ProfileView extends React.Component<IProfileViewProps, IProfileViewState>
|
||||||
|
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
user: getUserSelector(state),
|
user: getUserSelector(state),
|
||||||
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
Accounts_AllowEmailChange: state.settings.Accounts_AllowEmailChange as boolean,
|
Accounts_AllowEmailChange: state.settings.Accounts_AllowEmailChange as boolean,
|
||||||
Accounts_AllowPasswordChange: state.settings.Accounts_AllowPasswordChange as boolean,
|
Accounts_AllowPasswordChange: state.settings.Accounts_AllowPasswordChange as boolean,
|
||||||
Accounts_AllowRealNameChange: state.settings.Accounts_AllowRealNameChange as boolean,
|
Accounts_AllowRealNameChange: state.settings.Accounts_AllowRealNameChange as boolean,
|
||||||
|
@ -668,8 +668,7 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
Accounts_AllowUsernameChange: state.settings.Accounts_AllowUsernameChange as boolean,
|
Accounts_AllowUsernameChange: state.settings.Accounts_AllowUsernameChange as boolean,
|
||||||
Accounts_CustomFields: state.settings.Accounts_CustomFields as string,
|
Accounts_CustomFields: state.settings.Accounts_CustomFields as string,
|
||||||
baseUrl: state.server.server,
|
baseUrl: state.server.server,
|
||||||
Accounts_AllowDeleteOwnAccount: state.settings.Accounts_AllowDeleteOwnAccount as boolean,
|
Accounts_AllowDeleteOwnAccount: state.settings.Accounts_AllowDeleteOwnAccount as boolean
|
||||||
isMasterDetail: state.app.isMasterDetail
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withTheme(withActionSheet(ProfileView)));
|
export default connect(mapStateToProps)(withTheme(withActionSheet(ProfileView)));
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
/* eslint-disable complexity */
|
/* eslint-disable complexity */
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
import { StackNavigationOptions } from '@react-navigation/stack';
|
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import isEmpty from 'lodash/isEmpty';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Share, Switch, Text, View } from 'react-native';
|
import { Share, Switch, Text, View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { CompositeNavigationProp } from '@react-navigation/native';
|
||||||
|
|
||||||
import { closeRoom, leaveRoom } from '../../actions/room';
|
import { leaveRoom } from '../../actions/room';
|
||||||
import { setLoading } from '../../actions/selectedUsers';
|
import { setLoading } from '../../actions/selectedUsers';
|
||||||
import Avatar from '../../containers/Avatar';
|
import Avatar from '../../containers/Avatar';
|
||||||
import * as HeaderButton from '../../containers/HeaderButton';
|
import * as HeaderButton from '../../containers/HeaderButton';
|
||||||
|
@ -44,13 +45,17 @@ import {
|
||||||
} from '../../lib/methods/helpers';
|
} from '../../lib/methods/helpers';
|
||||||
import { Services } from '../../lib/services';
|
import { Services } from '../../lib/services';
|
||||||
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
||||||
|
import { IActionSheetProvider, withActionSheet } from '../../containers/ActionSheet';
|
||||||
|
import CloseLivechatSheet from '../../ee/omnichannel/containers/CloseLivechatSheet';
|
||||||
|
import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types';
|
||||||
|
import { closeLivechat } from '../../lib/methods/helpers/closeLivechat';
|
||||||
import { videoConfStartAndJoin } from '../../lib/methods/videoConf';
|
import { videoConfStartAndJoin } from '../../lib/methods/videoConf';
|
||||||
|
|
||||||
interface IOnPressTouch {
|
interface IOnPressTouch {
|
||||||
<T extends keyof ChatsStackParamList>(item: { route?: T; params?: ChatsStackParamList[T]; event?: Function }): void;
|
<T extends keyof ChatsStackParamList>(item: { route?: T; params?: ChatsStackParamList[T]; event?: Function }): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRoomActionsViewProps extends IBaseScreen<ChatsStackParamList, 'RoomActionsView'> {
|
interface IRoomActionsViewProps extends IActionSheetProvider, IBaseScreen<ChatsStackParamList, 'RoomActionsView'> {
|
||||||
userId: string;
|
userId: string;
|
||||||
jitsiEnabled: boolean;
|
jitsiEnabled: boolean;
|
||||||
jitsiEnableTeams: boolean;
|
jitsiEnableTeams: boolean;
|
||||||
|
@ -69,6 +74,12 @@ interface IRoomActionsViewProps extends IBaseScreen<ChatsStackParamList, 'RoomAc
|
||||||
addTeamChannelPermission?: string[];
|
addTeamChannelPermission?: string[];
|
||||||
convertTeamPermission?: string[];
|
convertTeamPermission?: string[];
|
||||||
viewCannedResponsesPermission?: string[];
|
viewCannedResponsesPermission?: string[];
|
||||||
|
livechatAllowManualOnHold?: boolean;
|
||||||
|
livechatRequestComment?: boolean;
|
||||||
|
navigation: CompositeNavigationProp<
|
||||||
|
StackNavigationProp<ChatsStackParamList, 'RoomActionsView'>,
|
||||||
|
StackNavigationProp<MasterDetailInsideStackParamList>
|
||||||
|
>;
|
||||||
videoConf_Enable_DMs: boolean;
|
videoConf_Enable_DMs: boolean;
|
||||||
videoConf_Enable_Channels: boolean;
|
videoConf_Enable_Channels: boolean;
|
||||||
videoConf_Enable_Groups: boolean;
|
videoConf_Enable_Groups: boolean;
|
||||||
|
@ -369,9 +380,25 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
const {
|
const {
|
||||||
room: { rid }
|
room: { rid }
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { dispatch } = this.props;
|
const { livechatRequestComment, showActionSheet, hideActionSheet, isMasterDetail } = this.props;
|
||||||
|
|
||||||
dispatch(closeRoom(rid));
|
if (!livechatRequestComment) {
|
||||||
|
const comment = I18n.t('Chat_closed_by_agent');
|
||||||
|
return closeLivechat({ rid, isMasterDetail, comment });
|
||||||
|
}
|
||||||
|
|
||||||
|
showActionSheet({
|
||||||
|
children: (
|
||||||
|
<CloseLivechatSheet
|
||||||
|
onSubmit={(comment: string) => {
|
||||||
|
hideActionSheet();
|
||||||
|
closeLivechat({ rid, isMasterDetail, comment });
|
||||||
|
}}
|
||||||
|
onCancel={() => hideActionSheet()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
headerHeight: 225
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
placeOnHoldLivechat = () => {
|
placeOnHoldLivechat = () => {
|
||||||
|
@ -1363,7 +1390,10 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'],
|
viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'],
|
||||||
createTeamPermission: state.permissions['create-team'],
|
createTeamPermission: state.permissions['create-team'],
|
||||||
addTeamChannelPermission: state.permissions['add-team-channel'],
|
addTeamChannelPermission: state.permissions['add-team-channel'],
|
||||||
convertTeamPermission: state.permissions['convert-team']
|
convertTeamPermission: state.permissions['convert-team'],
|
||||||
|
viewCannedResponsesPermission: state.permissions['view-canned-responses'],
|
||||||
|
livechatAllowManualOnHold: state.settings.Livechat_allow_manual_on_hold as boolean,
|
||||||
|
livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withTheme(withDimensions(RoomActionsView)));
|
export default connect(mapStateToProps)(withTheme(withActionSheet(withDimensions(RoomActionsView))));
|
||||||
|
|
|
@ -12,13 +12,14 @@ import { events, logEvent } from '../../lib/methods/helpers/log';
|
||||||
import { isTeamRoom } from '../../lib/methods/helpers/room';
|
import { isTeamRoom } from '../../lib/methods/helpers/room';
|
||||||
import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
|
import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
import { TActionSheetOptions, TActionSheetOptionsItem, withActionSheet } from '../../containers/ActionSheet';
|
import { IActionSheetProvider, TActionSheetOptionsItem, withActionSheet } from '../../containers/ActionSheet';
|
||||||
import i18n from '../../i18n';
|
import i18n from '../../i18n';
|
||||||
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers';
|
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers';
|
||||||
import { closeRoom } from '../../actions/room';
|
|
||||||
import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi';
|
import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi';
|
||||||
|
import { closeLivechat as closeLivechatService } from '../../lib/methods/helpers/closeLivechat';
|
||||||
|
import CloseLivechatSheet from '../../ee/omnichannel/containers/CloseLivechatSheet';
|
||||||
|
|
||||||
interface IRightButtonsProps {
|
interface IRightButtonsProps extends IActionSheetProvider {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
threadsEnabled: boolean;
|
threadsEnabled: boolean;
|
||||||
rid: string;
|
rid: string;
|
||||||
|
@ -31,7 +32,6 @@ interface IRightButtonsProps {
|
||||||
status?: string;
|
status?: string;
|
||||||
dispatch: Dispatch;
|
dispatch: Dispatch;
|
||||||
encrypted?: boolean;
|
encrypted?: boolean;
|
||||||
showActionSheet: (item: TActionSheetOptions) => void;
|
|
||||||
transferLivechatGuestPermission: boolean;
|
transferLivechatGuestPermission: boolean;
|
||||||
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
|
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
|
||||||
omnichannelPermissions: {
|
omnichannelPermissions: {
|
||||||
|
@ -39,6 +39,7 @@ interface IRightButtonsProps {
|
||||||
canReturnQueue: boolean;
|
canReturnQueue: boolean;
|
||||||
canPlaceLivechatOnHold: boolean;
|
canPlaceLivechatOnHold: boolean;
|
||||||
};
|
};
|
||||||
|
livechatRequestComment: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRigthButtonsState {
|
interface IRigthButtonsState {
|
||||||
|
@ -214,8 +215,29 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
};
|
};
|
||||||
|
|
||||||
closeLivechat = () => {
|
closeLivechat = () => {
|
||||||
const { dispatch, rid } = this.props;
|
const { rid, livechatRequestComment, showActionSheet, hideActionSheet, isMasterDetail } = this.props;
|
||||||
dispatch(closeRoom(rid));
|
|
||||||
|
hideActionSheet();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!livechatRequestComment) {
|
||||||
|
const comment = i18n.t('Chat_closed_by_agent');
|
||||||
|
return closeLivechatService({ rid, isMasterDetail, comment });
|
||||||
|
}
|
||||||
|
|
||||||
|
showActionSheet({
|
||||||
|
children: (
|
||||||
|
<CloseLivechatSheet
|
||||||
|
onSubmit={(comment: string) => {
|
||||||
|
hideActionSheet();
|
||||||
|
closeLivechatService({ rid, isMasterDetail, comment });
|
||||||
|
}}
|
||||||
|
onCancel={() => hideActionSheet()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
headerHeight: 225
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
};
|
};
|
||||||
|
|
||||||
showMoreActions = () => {
|
showMoreActions = () => {
|
||||||
|
@ -335,7 +357,8 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
const mapStateToProps = (state: IApplicationState) => ({
|
||||||
userId: getUserSelector(state).id,
|
userId: getUserSelector(state).id,
|
||||||
threadsEnabled: state.settings.Threads_enabled as boolean,
|
threadsEnabled: state.settings.Threads_enabled as boolean,
|
||||||
isMasterDetail: state.app.isMasterDetail
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
|
livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withActionSheet(RightButtonsContainer));
|
export default connect(mapStateToProps)(withActionSheet(RightButtonsContainer));
|
||||||
|
|
|
@ -108,7 +108,6 @@
|
||||||
"react-native-platform-touchable": "1.1.1",
|
"react-native-platform-touchable": "1.1.1",
|
||||||
"react-native-popover-view": "4.0.1",
|
"react-native-popover-view": "4.0.1",
|
||||||
"react-native-progress": "5.0.0",
|
"react-native-progress": "5.0.0",
|
||||||
"react-native-prompt-android": "^1.1.0",
|
|
||||||
"react-native-reanimated": "2.2.2",
|
"react-native-reanimated": "2.2.2",
|
||||||
"react-native-restart": "0.0.22",
|
"react-native-restart": "0.0.22",
|
||||||
"react-native-safe-area-context": "3.2.0",
|
"react-native-safe-area-context": "3.2.0",
|
||||||
|
|
|
@ -15302,11 +15302,6 @@ react-native-progress@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
react-native-prompt-android@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-native-prompt-android/-/react-native-prompt-android-1.1.0.tgz#3c5168029075cb9f72549fd5f92403372fb234e9"
|
|
||||||
integrity sha512-4JoyEaT2ZnK9IH+tDFpbTiQBgva8UIFGQf4/Uw/tnEVWBERlVlzcs5B82T9BkeEhEqXhp89JaiSBnLWj30lciw==
|
|
||||||
|
|
||||||
react-native-reanimated@2.2.2:
|
react-native-reanimated@2.2.2:
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.2.2.tgz#8bc81c7ee93d599991507bb826050a5eeee1e7f2"
|
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.2.2.tgz#8bc81c7ee93d599991507bb826050a5eeee1e7f2"
|
||||||
|
|
Loading…
Reference in New Issue