[IMPROVE] Add emoji picker to iOS (#4366)

* [IMPROVE] Add emoji picker to iOS

* clean left and right buttons

* fix the redux in emojipicker

* fix behavior when emoji keyboard is openning

* added isIOS

* fix show reactions when emoji is open

* minor tweak

* add provider

* fix baseurl

* minor tweak

* create closeEmojiAndAction and added to record

* fix actionsheet for omnichannel

* fix action sheet

* fix close emoji when navigate to other screen

* added iactionsheetprovider to roomview

* clean variables

* fix theme

* close the emojikeyboard when click on message

* apoint package.json to new pr

* fix branch

* fix package.json
This commit is contained in:
Reinaldo Neto 2022-08-08 15:38:01 -03:00 committed by Diego Mello
parent 28bb6a045d
commit d19bb9c28a
16 changed files with 129 additions and 149 deletions

View File

@ -65,6 +65,7 @@ class EmojiCategory extends React.Component<IEmojiCategory> {
initialNumToRender={45} initialNumToRender={45}
removeClippedSubviews removeClippedSubviews
{...scrollPersistTaps} {...scrollPersistTaps}
keyboardDismissMode={'none'}
/> />
); );
} }

View File

@ -17,7 +17,7 @@ import protectedFunction from '../../lib/methods/helpers/protectedFunction';
import shortnameToUnicode from '../../lib/methods/helpers/shortnameToUnicode'; import shortnameToUnicode from '../../lib/methods/helpers/shortnameToUnicode';
import log from '../../lib/methods/helpers/log'; import log from '../../lib/methods/helpers/log';
import { themes } from '../../lib/constants'; import { themes } from '../../lib/constants';
import { TSupportedThemes, withTheme } from '../../theme'; import { TSupportedThemes } from '../../theme';
import { IEmoji, TGetCustomEmoji, IApplicationState, ICustomEmojis, TFrequentlyUsedEmojiModel } from '../../definitions'; import { IEmoji, TGetCustomEmoji, IApplicationState, ICustomEmojis, TFrequentlyUsedEmojiModel } from '../../definitions';
interface IEmojiPickerProps { interface IEmojiPickerProps {
@ -198,7 +198,8 @@ class EmojiPicker extends Component<IEmojiPickerProps, IEmojiPickerState> {
} }
const mapStateToProps = (state: IApplicationState) => ({ const mapStateToProps = (state: IApplicationState) => ({
customEmojis: state.customEmojis customEmojis: state.customEmojis,
baseUrl: state.share.server.server || state.server.server
}); });
export default connect(mapStateToProps)(withTheme(EmojiPicker)); export default connect(mapStateToProps)(EmojiPicker);

View File

@ -1,39 +1,28 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { KeyboardRegistry } from 'react-native-ui-lib/keyboard'; import { KeyboardRegistry } from 'react-native-ui-lib/keyboard';
import { Provider } from 'react-redux';
import { store } from '../../lib/store/auxStore'; import store from '../../lib/store';
import EmojiPicker from '../EmojiPicker'; import EmojiPicker from '../EmojiPicker';
import styles from './styles'; import styles from './styles';
import { themes } from '../../lib/constants'; import { themes } from '../../lib/constants';
import { TSupportedThemes, withTheme } from '../../theme'; import { TSupportedThemes } from '../../theme';
interface IMessageBoxEmojiKeyboard { const EmojiKeyboard = ({ theme }: { theme: TSupportedThemes }) => {
theme: TSupportedThemes; const onEmojiSelected = (emoji: string) => {
}
export default class EmojiKeyboard extends React.PureComponent<IMessageBoxEmojiKeyboard, any> {
private readonly baseUrl: string;
constructor(props: IMessageBoxEmojiKeyboard) {
super(props);
const state = store.getState();
this.baseUrl = state.share.server.server || state.server.server;
}
onEmojiSelected = (emoji: string) => {
KeyboardRegistry.onItemSelected('EmojiKeyboard', { emoji }); KeyboardRegistry.onItemSelected('EmojiKeyboard', { emoji });
}; };
render() {
const { theme } = this.props;
return ( return (
<Provider store={store}>
<View <View
style={[styles.emojiKeyboardContainer, { borderTopColor: themes[theme].borderColor }]} style={[styles.emojiKeyboardContainer, { borderTopColor: themes[theme].borderColor }]}
testID='messagebox-keyboard-emoji'> testID='messagebox-keyboard-emoji'>
<EmojiPicker onEmojiSelected={this.onEmojiSelected} baseUrl={this.baseUrl} theme={theme} /> <EmojiPicker onEmojiSelected={onEmojiSelected} theme={theme} />
</View> </View>
</Provider>
); );
} };
}
KeyboardRegistry.registerKeyboard('EmojiKeyboard', () => withTheme(EmojiKeyboard)); KeyboardRegistry.registerKeyboard('EmojiKeyboard', () => EmojiKeyboard);

View File

@ -1,24 +0,0 @@
import React from 'react';
import { View } from 'react-native';
import { ActionsButton, CancelEditingButton } from './buttons';
import styles from './styles';
interface IMessageBoxLeftButtons {
showMessageBoxActions(): void;
editing: boolean;
editCancel(): void;
isActionsEnabled: boolean;
}
const LeftButtons = React.memo(({ showMessageBoxActions, editing, editCancel, isActionsEnabled }: IMessageBoxLeftButtons) => {
if (editing) {
return <CancelEditingButton onPress={editCancel} />;
}
if (isActionsEnabled) {
return <ActionsButton onPress={showMessageBoxActions} />;
}
return <View style={styles.buttonsWhitespace} />;
});
export default LeftButtons;

View File

@ -17,6 +17,7 @@ interface IMessageBoxRecordAudioProps {
permissionToUpload: boolean; permissionToUpload: boolean;
recordingCallback: Function; recordingCallback: Function;
onFinish: Function; onFinish: Function;
onStart: Function;
} }
const RECORDING_EXTENSION = '.m4a'; const RECORDING_EXTENSION = '.m4a';
@ -116,6 +117,9 @@ export default class RecordAudio extends React.PureComponent<IMessageBoxRecordAu
}; };
startRecordingAudio = async () => { startRecordingAudio = async () => {
const { onStart } = this.props;
onStart();
logEvent(events.ROOM_AUDIO_RECORD); logEvent(events.ROOM_AUDIO_RECORD);
if (!this.isRecorderBusy) { if (!this.isRecorderBusy) {
this.isRecorderBusy = true; this.isRecorderBusy = true;

View File

@ -1,17 +0,0 @@
import React from 'react';
import { SendButton } from './buttons';
interface IMessageBoxRightButtons {
showSend: boolean;
submit(): void;
}
const RightButtons = ({ showSend, submit }: IMessageBoxRightButtons) => {
if (showSend) {
return <SendButton onPress={submit} />;
}
return null;
};
export default RightButtons;

View File

@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import { isIOS } from '../../lib/methods/helpers';
import { ActionsButton, SendButton } from './buttons'; import { ActionsButton, SendButton } from './buttons';
import styles from './styles'; import styles from './styles';
@ -18,7 +19,7 @@ const RightButtons = React.memo(({ showSend, submit, showMessageBoxActions, isAc
if (isActionsEnabled) { if (isActionsEnabled) {
return <ActionsButton onPress={showMessageBoxActions} />; return <ActionsButton onPress={showMessageBoxActions} />;
} }
return <View style={styles.buttonsWhitespace} />; return !isIOS ? <View style={styles.buttonsWhitespace} /> : null;
}); });
export default RightButtons; export default RightButtons;

View File

@ -4,3 +4,5 @@ export const MENTIONS_TRACKING_TYPE_COMMANDS = '/';
export const MENTIONS_TRACKING_TYPE_ROOMS = '#'; export const MENTIONS_TRACKING_TYPE_ROOMS = '#';
export const MENTIONS_TRACKING_TYPE_CANNED = '!'; export const MENTIONS_TRACKING_TYPE_CANNED = '!';
export const MENTIONS_COUNT_TO_DISPLAY = 4; export const MENTIONS_COUNT_TO_DISPLAY = 4;
export const TIMEOUT_CLOSE_EMOJI = 300;

View File

@ -19,11 +19,7 @@ import RecordAudio from './RecordAudio';
import I18n from '../../i18n'; import I18n from '../../i18n';
import ReplyPreview from './ReplyPreview'; import ReplyPreview from './ReplyPreview';
import { themes } from '../../lib/constants'; import { themes } from '../../lib/constants';
// @ts-ignore
// eslint-disable-next-line import/extensions,import/no-unresolved
import LeftButtons from './LeftButtons'; import LeftButtons from './LeftButtons';
// @ts-ignore
// eslint-disable-next-line import/extensions,import/no-unresolved
import RightButtons from './RightButtons'; import RightButtons from './RightButtons';
import { canUploadFile } from '../../lib/methods/helpers/media'; import { canUploadFile } from '../../lib/methods/helpers/media';
import EventEmiter from '../../lib/methods/helpers/events'; import EventEmiter from '../../lib/methods/helpers/events';
@ -37,12 +33,13 @@ import {
MENTIONS_TRACKING_TYPE_COMMANDS, MENTIONS_TRACKING_TYPE_COMMANDS,
MENTIONS_TRACKING_TYPE_EMOJIS, MENTIONS_TRACKING_TYPE_EMOJIS,
MENTIONS_TRACKING_TYPE_ROOMS, MENTIONS_TRACKING_TYPE_ROOMS,
MENTIONS_TRACKING_TYPE_USERS MENTIONS_TRACKING_TYPE_USERS,
TIMEOUT_CLOSE_EMOJI
} from './constants'; } from './constants';
import CommandsPreview from './CommandsPreview'; import CommandsPreview from './CommandsPreview';
import { getUserSelector } from '../../selectors/login'; import { getUserSelector } from '../../selectors/login';
import Navigation from '../../lib/navigation/appNavigation'; import Navigation from '../../lib/navigation/appNavigation';
import { withActionSheet } from '../ActionSheet'; import { TActionSheetOptionsItem, withActionSheet } from '../ActionSheet';
import { sanitizeLikeString } from '../../lib/database/utils'; import { sanitizeLikeString } from '../../lib/database/utils';
import { CustomIcon } from '../CustomIcon'; import { CustomIcon } from '../CustomIcon';
import { forceJpgExtension } from './forceJpgExtension'; import { forceJpgExtension } from './forceJpgExtension';
@ -58,14 +55,12 @@ import {
} from '../../definitions'; } from '../../definitions';
import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types'; import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types';
import { getPermalinkMessage, search, sendFileMessage } from '../../lib/methods'; import { getPermalinkMessage, search, sendFileMessage } from '../../lib/methods';
import { hasPermission, debounce, isAndroid, isTablet } from '../../lib/methods/helpers'; import { hasPermission, debounce, isAndroid, isIOS, isTablet } from '../../lib/methods/helpers';
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
import { TSupportedThemes } from '../../theme'; import { TSupportedThemes } from '../../theme';
import { ChatsStackParamList } from '../../stacks/types'; import { ChatsStackParamList } from '../../stacks/types';
if (isAndroid) { require('./EmojiKeyboard');
require('./EmojiKeyboard');
}
const imagePickerConfig = { const imagePickerConfig = {
cropping: true, cropping: true,
@ -270,6 +265,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
}, 500); }, 500);
}); });
this.unsubscribeBlur = navigation.addListener('blur', () => { this.unsubscribeBlur = navigation.addListener('blur', () => {
this.closeEmoji();
this.component?.blur(); this.component?.blur();
}); });
} }
@ -330,6 +326,9 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
if (nextProps.theme !== theme) { if (nextProps.theme !== theme) {
return true; return true;
} }
if (nextState.showEmojiKeyboard !== showEmojiKeyboard) {
return true;
}
if (!isFocused()) { if (!isFocused()) {
return false; return false;
} }
@ -342,9 +341,6 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
if (nextProps.editing !== editing) { if (nextProps.editing !== editing) {
return true; return true;
} }
if (nextState.showEmojiKeyboard !== showEmojiKeyboard) {
return true;
}
if (nextState.trackingType !== trackingType) { if (nextState.trackingType !== trackingType) {
return true; return true;
} }
@ -809,7 +805,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
const { permissionToUpload } = this.state; const { permissionToUpload } = this.state;
const { showActionSheet, goToCannedResponses } = this.props; const { showActionSheet, goToCannedResponses } = this.props;
const options = []; const options: TActionSheetOptionsItem[] = [];
if (goToCannedResponses) { if (goToCannedResponses) {
options.push({ options.push({
title: I18n.t('Canned_Responses'), title: I18n.t('Canned_Responses'),
@ -847,7 +843,8 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
icon: 'discussions', icon: 'discussions',
onPress: this.createDiscussion onPress: this.createDiscussion
}); });
showActionSheet({ options });
this.closeEmojiAndAction(showActionSheet, { options });
}; };
editCancel = () => { editCancel = () => {
@ -883,6 +880,13 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
this.setState({ showEmojiKeyboard: false }); this.setState({ showEmojiKeyboard: false });
}; };
closeEmojiAndAction = (action?: Function, params?: any) => {
const { showEmojiKeyboard } = this.state;
this.closeEmoji();
setTimeout(() => action && action(params), showEmojiKeyboard && isIOS ? TIMEOUT_CLOSE_EMOJI : null);
};
submit = async () => { submit = async () => {
const { tshow } = this.state; const { tshow } = this.state;
const { onSubmit, rid: roomId, tmid, showSend, sharing } = this.props; const { onSubmit, rid: roomId, tmid, showSend, sharing } = this.props;
@ -1089,6 +1093,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
recordingCallback={this.recordingCallback} recordingCallback={this.recordingCallback}
onFinish={this.finishAudioMessage} onFinish={this.finishAudioMessage}
permissionToUpload={permissionToUpload} permissionToUpload={permissionToUpload}
onStart={this.closeEmoji}
/> />
); );
@ -1112,14 +1117,11 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
const textInputAndButtons = !recording ? ( const textInputAndButtons = !recording ? (
<> <>
<LeftButtons <LeftButtons
theme={theme}
showEmojiKeyboard={showEmojiKeyboard} showEmojiKeyboard={showEmojiKeyboard}
editing={editing} editing={editing}
showMessageBoxActions={this.showMessageBoxActions}
editCancel={this.editCancel} editCancel={this.editCancel}
openEmoji={this.openEmoji} openEmoji={this.openEmoji}
closeEmoji={this.closeEmoji} closeEmoji={this.closeEmoji}
isActionsEnabled={isActionsEnabled}
/> />
<TextInput <TextInput
ref={component => (this.component = component)} ref={component => (this.component = component)}
@ -1138,7 +1140,6 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
{...isAndroidTablet} {...isAndroidTablet}
/> />
<RightButtons <RightButtons
theme={theme}
showSend={showSend} showSend={showSend}
submit={this.submit} submit={this.submit}
showMessageBoxActions={this.showMessageBoxActions} showMessageBoxActions={this.showMessageBoxActions}
@ -1187,6 +1188,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
renderContent={this.renderContent} renderContent={this.renderContent}
kbInputRef={this.component} kbInputRef={this.component}
kbComponent={showEmojiKeyboard ? 'EmojiKeyboard' : null} kbComponent={showEmojiKeyboard ? 'EmojiKeyboard' : null}
kbInitialProps={{ theme }}
onKeyboardResigned={this.onKeyboardResigned} onKeyboardResigned={this.onKeyboardResigned}
onItemSelected={this.onEmojiSelected} onItemSelected={this.onEmojiSelected}
trackInteractive trackInteractive

View File

@ -58,6 +58,7 @@ interface IMessageContainerProps {
jumpToMessage?: (link: string) => void; jumpToMessage?: (link: string) => void;
onPress?: () => void; onPress?: () => void;
theme: TSupportedThemes; theme: TSupportedThemes;
closeEmojiAndAction?: (action?: Function, params?: any) => void;
} }
interface IMessageContainerState { interface IMessageContainerState {
@ -114,6 +115,14 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
} }
} }
closeEmojiAndAction = () => {
const { closeEmojiAndAction } = this.props;
if (closeEmojiAndAction) {
closeEmojiAndAction(this.onPress);
}
};
onPress = debounce( onPress = debounce(
() => { () => {
const { onPress } = this.props; const { onPress } = this.props;
@ -373,7 +382,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
value={{ value={{
user, user,
baseUrl, baseUrl,
onPress: this.onPress, onPress: this.closeEmojiAndAction,
onLongPress: this.onLongPress, onLongPress: this.onLongPress,
reactionInit: this.reactionInit, reactionInit: this.reactionInit,
onErrorPress: this.onErrorPress, onErrorPress: this.onErrorPress,

View File

@ -14,7 +14,6 @@ const margin = isAndroid ? 40 : 20;
const maxSize = 400; const maxSize = 400;
interface IReactionPickerProps { interface IReactionPickerProps {
baseUrl: string;
message?: any; message?: any;
show: boolean; show: boolean;
isMasterDetail: boolean; isMasterDetail: boolean;
@ -42,7 +41,7 @@ class ReactionPicker extends React.Component<IReactionPickerProps> {
}; };
render() { render() {
const { width, height, show, baseUrl, reactionClose, isMasterDetail, theme } = this.props; const { width, height, show, reactionClose, isMasterDetail, theme } = this.props;
let widthStyle = width - margin; let widthStyle = width - margin;
let heightStyle = Math.min(width, height) - margin * 2; let heightStyle = Math.min(width, height) - margin * 2;
@ -70,7 +69,7 @@ class ReactionPicker extends React.Component<IReactionPickerProps> {
} }
]} ]}
testID='reaction-picker'> testID='reaction-picker'>
<EmojiPicker theme={theme} onEmojiSelected={this.onEmojiSelected} baseUrl={baseUrl} /> <EmojiPicker theme={theme} onEmojiSelected={this.onEmojiSelected} />
</View> </View>
</Modal> </Modal>
) : null; ) : null;
@ -78,7 +77,6 @@ class ReactionPicker extends React.Component<IReactionPickerProps> {
} }
const mapStateToProps = (state: IApplicationState) => ({ const mapStateToProps = (state: IApplicationState) => ({
baseUrl: state.server.server,
isMasterDetail: state.app.isMasterDetail isMasterDetail: state.app.isMasterDetail
}); });

View File

@ -13,7 +13,7 @@ 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 { IActionSheetProvider, TActionSheetOptionsItem, withActionSheet } from '../../containers/ActionSheet'; import { TActionSheetOptionsItem } 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 { onHoldLivechat, returnLivechat } from '../../lib/services/restApi'; import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi';
@ -21,10 +21,10 @@ import { closeLivechat as closeLivechatService } from '../../lib/methods/helpers
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment'; import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
interface IRightButtonsProps extends IActionSheetProvider { interface IRightButtonsProps {
userId?: string; userId?: string;
threadsEnabled: boolean; threadsEnabled: boolean;
rid: string; rid?: string;
t: string; t: string;
tmid?: string; tmid?: string;
teamId?: string; teamId?: string;
@ -34,7 +34,6 @@ interface IRightButtonsProps extends IActionSheetProvider {
status?: string; status?: string;
dispatch: Dispatch; dispatch: Dispatch;
encrypted?: boolean; encrypted?: boolean;
transferLivechatGuestPermission: boolean;
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>; navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
omnichannelPermissions: { omnichannelPermissions: {
canForwardGuest: boolean; canForwardGuest: boolean;
@ -42,6 +41,7 @@ interface IRightButtonsProps extends IActionSheetProvider {
canPlaceLivechatOnHold: boolean; canPlaceLivechatOnHold: boolean;
}; };
livechatRequestComment: boolean; livechatRequestComment: boolean;
showActionSheet: Function;
departmentId?: string; departmentId?: string;
} }
@ -187,6 +187,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
returnLivechat = () => { returnLivechat = () => {
const { rid } = this.props; const { rid } = this.props;
if (rid) {
showConfirmationAlert({ showConfirmationAlert({
message: i18n.t('Would_you_like_to_return_the_inquiry'), message: i18n.t('Would_you_like_to_return_the_inquiry'),
confirmationText: i18n.t('Yes'), confirmationText: i18n.t('Yes'),
@ -198,10 +199,12 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
} }
} }
}); });
}
}; };
placeOnHoldLivechat = () => { placeOnHoldLivechat = () => {
const { navigation, rid } = this.props; const { navigation, rid } = this.props;
if (rid) {
showConfirmationAlert({ showConfirmationAlert({
title: i18n.t('Are_you_sure_question_mark'), title: i18n.t('Are_you_sure_question_mark'),
message: i18n.t('Would_like_to_place_on_hold'), message: i18n.t('Would_like_to_place_on_hold'),
@ -215,6 +218,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
} }
} }
}); });
}
}; };
closeLivechat = async () => { closeLivechat = async () => {
@ -234,6 +238,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
tagsList = await Services.getTagsList(); tagsList = await Services.getTagsList();
} }
if (rid) {
if (!livechatRequestComment && !departmentInfo?.requestTagBeforeClosingChat) { if (!livechatRequestComment && !departmentInfo?.requestTagBeforeClosingChat) {
const comment = i18n.t('Chat_closed_by_agent'); const comment = i18n.t('Chat_closed_by_agent');
return closeLivechatService({ rid, isMasterDetail, comment }); return closeLivechatService({ rid, isMasterDetail, comment });
@ -247,6 +252,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
} else { } else {
navigation.navigate('CloseLivechatView', { rid, departmentId, departmentInfo, tagsList }); navigation.navigate('CloseLivechatView', { rid, departmentId, departmentInfo, tagsList });
} }
}
}; };
showMoreActions = () => { showMoreActions = () => {
@ -267,6 +273,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
title: i18n.t('Forward_Chat'), title: i18n.t('Forward_Chat'),
icon: 'chat-forward', icon: 'chat-forward',
onPress: () => { onPress: () => {
if (rid) {
if (isMasterDetail) { if (isMasterDetail) {
navigation.navigate('ModalStackNavigator', { navigation.navigate('ModalStackNavigator', {
screen: 'ForwardLivechatView', screen: 'ForwardLivechatView',
@ -276,6 +283,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
navigation.navigate('ForwardLivechatView', { rid }); navigation.navigate('ForwardLivechatView', { rid });
} }
} }
}
}); });
} }
@ -379,4 +387,4 @@ const mapStateToProps = (state: IApplicationState) => ({
livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean
}); });
export default connect(mapStateToProps)(withActionSheet(RightButtonsContainer)); export default connect(mapStateToProps)(RightButtonsContainer);

View File

@ -99,7 +99,7 @@ import {
hasPermission hasPermission
} from '../../lib/methods/helpers'; } from '../../lib/methods/helpers';
import { Services } from '../../lib/services'; import { Services } from '../../lib/services';
import { withActionSheet, TActionSheetOptions } from '../../containers/ActionSheet'; import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet';
type TStateAttrsUpdate = keyof IRoomViewState; type TStateAttrsUpdate = keyof IRoomViewState;
@ -150,7 +150,7 @@ const roomAttrsUpdate = [
't' 't'
] as TRoomUpdate[]; ] as TRoomUpdate[];
interface IRoomViewProps extends IBaseScreen<ChatsStackParamList, 'RoomView'> { interface IRoomViewProps extends IActionSheetProvider, IBaseScreen<ChatsStackParamList, 'RoomView'> {
user: Pick<ILoggedUser, 'id' | 'username' | 'token' | 'showMessageInMainThread'>; user: Pick<ILoggedUser, 'id' | 'username' | 'token' | 'showMessageInMainThread'>;
appState: string; appState: string;
useRealName?: boolean; useRealName?: boolean;
@ -170,7 +170,6 @@ interface IRoomViewProps extends IBaseScreen<ChatsStackParamList, 'RoomView'> {
transferLivechatGuestPermission?: string[]; // TODO: Check if its the correct type transferLivechatGuestPermission?: string[]; // TODO: Check if its the correct type
viewCannedResponsesPermission?: string[]; // TODO: Check if its the correct type viewCannedResponsesPermission?: string[]; // TODO: Check if its the correct type
livechatAllowManualOnHold?: boolean; livechatAllowManualOnHold?: boolean;
showActionSheet: (options: TActionSheetOptions) => void;
} }
interface IRoomViewState { interface IRoomViewState {
@ -185,7 +184,7 @@ interface IRoomViewState {
fname?: string; fname?: string;
prid?: string; prid?: string;
joinCodeRequired?: boolean; joinCodeRequired?: boolean;
status?: boolean; status?: string;
lastMessage?: ILastMessage; lastMessage?: ILastMessage;
sysMes?: boolean; sysMes?: boolean;
onHold?: boolean; onHold?: boolean;
@ -635,6 +634,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
encrypted={encrypted} encrypted={encrypted}
navigation={navigation} navigation={navigation}
toggleFollowThread={this.toggleFollowThread} toggleFollowThread={this.toggleFollowThread}
showActionSheet={this.showActionSheet}
departmentId={departmentId} departmentId={departmentId}
/> />
) )
@ -785,7 +785,12 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}; };
errorActionsShow = (message: TAnyMessageModel) => { errorActionsShow = (message: TAnyMessageModel) => {
this.messageErrorActions?.showMessageErrorActions(message); this.messagebox?.current?.closeEmojiAndAction(this.messageErrorActions?.showMessageErrorActions, message);
};
showActionSheet = (options: any) => {
const { showActionSheet } = this.props;
this.messagebox?.current?.closeEmojiAndAction(showActionSheet, options);
}; };
onEditInit = (message: TAnyMessageModel) => { onEditInit = (message: TAnyMessageModel) => {
@ -834,7 +839,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}; };
onMessageLongPress = (message: TAnyMessageModel) => { onMessageLongPress = (message: TAnyMessageModel) => {
this.messageActions?.showMessageActions(message); this.messagebox?.current?.closeEmojiAndAction(this.messageActions?.showMessageActions, message);
}; };
showAttachment = (attachment: IAttachment) => { showAttachment = (attachment: IAttachment) => {
@ -857,7 +862,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
this.setState({ selectedMessage: message }); this.setState({ selectedMessage: message });
const { showActionSheet, baseUrl, width } = this.props; const { showActionSheet, baseUrl, width } = this.props;
const { selectedMessage } = this.state; const { selectedMessage } = this.state;
showActionSheet({ this.messagebox?.current?.closeEmojiAndAction(showActionSheet, {
children: ( children: (
<ReactionsList <ReactionsList
reactions={selectedMessage?.reactions} reactions={selectedMessage?.reactions}
@ -1346,6 +1351,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
jumpToMessage={this.jumpToMessageByUrl} jumpToMessage={this.jumpToMessageByUrl}
highlighted={highlightedMessage === item.id} highlighted={highlightedMessage === item.id}
theme={theme} theme={theme}
closeEmojiAndAction={this.messagebox?.current?.closeEmojiAndAction}
/> />
); );
} }

View File

@ -117,7 +117,7 @@
"react-native-simple-crypto": "RocketChat/react-native-simple-crypto#0.5.0", "react-native-simple-crypto": "RocketChat/react-native-simple-crypto#0.5.0",
"react-native-slowlog": "^1.0.2", "react-native-slowlog": "^1.0.2",
"react-native-svg": "^12.3.0", "react-native-svg": "^12.3.0",
"react-native-ui-lib": "RocketChat/react-native-ui-lib#minor-improvements", "react-native-ui-lib": "RocketChat/react-native-ui-lib",
"react-native-unimodules": "^0.14.8", "react-native-unimodules": "^0.14.8",
"react-native-vector-icons": "9.1.0", "react-native-vector-icons": "9.1.0",
"react-native-webview": "10.3.2", "react-native-webview": "10.3.2",

View File

@ -15491,9 +15491,9 @@ react-native-text-size@4.0.0-rc.1:
resolved "https://registry.yarnpkg.com/react-native-text-size/-/react-native-text-size-4.0.0-rc.1.tgz#1e048d345dd6a5a8e1269e0585c1a5948c478da5" resolved "https://registry.yarnpkg.com/react-native-text-size/-/react-native-text-size-4.0.0-rc.1.tgz#1e048d345dd6a5a8e1269e0585c1a5948c478da5"
integrity sha512-CysqjU2jK6Yc+a+kEI222pUyTY2ywcU2HqbFqf1KHymW6OPTdvBBHqbEJKL0QiLhQaFYDbqicM+h990s9TP00g== integrity sha512-CysqjU2jK6Yc+a+kEI222pUyTY2ywcU2HqbFqf1KHymW6OPTdvBBHqbEJKL0QiLhQaFYDbqicM+h990s9TP00g==
react-native-ui-lib@RocketChat/react-native-ui-lib#minor-improvements: react-native-ui-lib@RocketChat/react-native-ui-lib:
version "4.2.1" version "4.2.0"
resolved "https://codeload.github.com/RocketChat/react-native-ui-lib/tar.gz/a80f38aaa947849736ce8643253991cdcb639414" resolved "https://codeload.github.com/RocketChat/react-native-ui-lib/tar.gz/d20c1bcd09b694fc5133fc2232fd510f5f4ba581"
dependencies: dependencies:
babel-plugin-transform-inline-environment-variables "^0.0.2" babel-plugin-transform-inline-environment-variables "^0.0.2"
color "^3.1.0" color "^3.1.0"