feat: display disabled actions on action sheet (#5356)

* improve: show the item disabled when the user doesn't have permission

* minor tweak changing from disabled to enabled param

* add the behavior at long press message

* minor tweak

* minor tweak

* remove the header notPermission and show toast

* tweak at auto translate e2e test

* minor tweak

* minor tweak translated

* minor tweak en.json

* minor tweak description
This commit is contained in:
Reinaldo Neto 2023-12-11 12:51:44 -03:00 committed by GitHub
parent 7c0a2692dc
commit 3a5173ffda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 91 additions and 70 deletions

View File

@ -1,11 +1,13 @@
import React from 'react'; import React from 'react';
import { Text, View } from 'react-native'; import { Text, View } from 'react-native';
import { themes } from '../../lib/constants';
import { CustomIcon } from '../CustomIcon'; import { CustomIcon } from '../CustomIcon';
import { useTheme } from '../../theme'; import { useTheme } from '../../theme';
import EventEmitter from '../../lib/methods/helpers/events';
import I18n from '../../i18n';
import { TActionSheetOptionsItem } from './Provider'; import { TActionSheetOptionsItem } from './Provider';
import styles from './styles'; import styles from './styles';
import { LISTENER } from '../Toast';
import Touch from '../Touch'; import Touch from '../Touch';
export interface IActionSheetItem { export interface IActionSheetItem {
@ -14,25 +16,30 @@ export interface IActionSheetItem {
} }
export const Item = React.memo(({ item, hide }: IActionSheetItem) => { export const Item = React.memo(({ item, hide }: IActionSheetItem) => {
const { theme } = useTheme(); const enabled = item?.enabled ?? true;
const { colors } = useTheme();
const onPress = () => { const onPress = () => {
if (enabled) {
hide(); hide();
item?.onPress(); item?.onPress();
} else {
EventEmitter.emit(LISTENER, { message: I18n.t('You_dont_have_permission_to_perform_this_action') });
}
}; };
let textColor = colors.bodyText;
if (item.danger) {
textColor = colors.dangerColor;
}
if (!enabled) {
textColor = colors.fontDisabled;
}
return ( return (
<Touch onPress={onPress} style={[styles.item, { backgroundColor: themes[theme].focusedBackground }]} testID={item.testID}> <Touch onPress={onPress} style={[styles.item, { backgroundColor: colors.focusedBackground }]} testID={item.testID}>
{item.icon ? ( {item.icon ? <CustomIcon name={item.icon} size={20} color={textColor} /> : null}
<CustomIcon name={item.icon} size={20} color={item.danger ? themes[theme].dangerColor : themes[theme].bodyText} />
) : null}
<View style={styles.titleContainer}> <View style={styles.titleContainer}>
<Text <Text numberOfLines={1} style={[styles.title, { color: textColor, marginLeft: item.icon ? 16 : 0 }]}>
numberOfLines={1}
style={[
styles.title,
{ color: item.danger ? themes[theme].dangerColor : themes[theme].bodyText, marginLeft: item.icon ? 16 : 0 }
]}
>
{item.title} {item.title}
</Text> </Text>
</View> </View>

View File

@ -11,6 +11,7 @@ export type TActionSheetOptionsItem = {
testID?: string; testID?: string;
onPress: () => void; onPress: () => void;
right?: () => React.ReactElement; right?: () => React.ReactElement;
enabled?: boolean;
}; };
export type TActionSheetOptions = { export type TActionSheetOptions = {

View File

@ -405,22 +405,22 @@ const MessageActions = React.memo(
} }
// Reply in DM // Reply in DM
if (room.t !== 'd' && room.t !== 'l' && permissions.hasCreateDirectMessagePermission && !videoConfBlock) { if (room.t !== 'd' && room.t !== 'l' && !videoConfBlock) {
options.push({ options.push({
title: I18n.t('Reply_in_direct_message'), title: I18n.t('Reply_in_direct_message'),
icon: 'arrow-back', icon: 'arrow-back',
onPress: () => handleReplyInDM(message) onPress: () => handleReplyInDM(message),
enabled: permissions.hasCreateDirectMessagePermission
}); });
} }
// Create Discussion // Create Discussion
if (permissions.hasCreateDiscussionOtherUserPermission) {
options.push({ options.push({
title: I18n.t('Start_a_Discussion'), title: I18n.t('Start_a_Discussion'),
icon: 'discussions', icon: 'discussions',
onPress: () => handleCreateDiscussion(message) onPress: () => handleCreateDiscussion(message),
enabled: permissions.hasCreateDiscussionOtherUserPermission
}); });
}
if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.2.0') && !videoConfBlock) { if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.2.0') && !videoConfBlock) {
options.push({ options.push({
@ -454,20 +454,22 @@ const MessageActions = React.memo(
}); });
// Edit // Edit
if (allowEdit(message) && !videoConfBlock) { if (!videoConfBlock) {
options.push({ options.push({
title: I18n.t('Edit'), title: I18n.t('Edit'),
icon: 'edit', icon: 'edit',
onPress: () => handleEdit(message) onPress: () => handleEdit(message),
enabled: allowEdit(message)
}); });
} }
// Pin // Pin
if (Message_AllowPinning && permissions?.hasPinPermission && !videoConfBlock) { if (Message_AllowPinning && !videoConfBlock) {
options.push({ options.push({
title: I18n.t(message.pinned ? 'Unpin' : 'Pin'), title: I18n.t(message.pinned ? 'Unpin' : 'Pin'),
icon: 'pin', icon: 'pin',
onPress: () => handlePin(message) onPress: () => handlePin(message),
enabled: permissions?.hasPinPermission
}); });
} }
@ -516,14 +518,13 @@ const MessageActions = React.memo(
}); });
// Delete // Delete
if (allowDelete(message)) {
options.push({ options.push({
title: I18n.t('Delete'), title: I18n.t('Delete'),
icon: 'delete', icon: 'delete',
danger: true, danger: true,
onPress: () => handleDelete(message) onPress: () => handleDelete(message),
enabled: allowDelete(message)
}); });
}
return options; return options;
}; };
@ -534,10 +535,13 @@ const MessageActions = React.memo(
showActionSheet({ showActionSheet({
options: getOptions(message), options: getOptions(message),
headerHeight: HEADER_HEIGHT, headerHeight: HEADER_HEIGHT,
customHeader: customHeader: (
!isReadOnly || room.reactWhenReadOnly ? ( <>
{!isReadOnly || room.reactWhenReadOnly ? (
<Header handleReaction={handleReaction} isMasterDetail={isMasterDetail} message={message} /> <Header handleReaction={handleReaction} isMasterDetail={isMasterDetail} message={message} />
) : null ) : null}
</>
)
}); });
}; };

View File

@ -904,40 +904,43 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
onPress: () => goToCannedResponses() onPress: () => goToCannedResponses()
}); });
} }
if (permissionToUpload) {
options.push( options.push(
{ {
title: I18n.t('Take_a_photo'), title: I18n.t('Take_a_photo'),
icon: 'camera-photo', icon: 'camera-photo',
onPress: this.takePhoto onPress: this.takePhoto,
enabled: permissionToUpload
}, },
{ {
title: I18n.t('Take_a_video'), title: I18n.t('Take_a_video'),
icon: 'camera', icon: 'camera',
onPress: this.takeVideo onPress: this.takeVideo,
enabled: permissionToUpload
}, },
{ {
title: I18n.t('Choose_from_library'), title: I18n.t('Choose_from_library'),
icon: 'image', icon: 'image',
onPress: this.chooseFromLibrary onPress: this.chooseFromLibrary,
enabled: permissionToUpload
}, },
{ {
title: I18n.t('Choose_file'), title: I18n.t('Choose_file'),
icon: 'attach', icon: 'attach',
onPress: this.chooseFile onPress: this.chooseFile,
} enabled: permissionToUpload
); },
} {
if (hasCreateDiscussionPermission) {
options.push({
title: I18n.t('Create_Discussion'), title: I18n.t('Create_Discussion'),
icon: 'discussions', icon: 'discussions',
onPress: this.createDiscussion onPress: this.createDiscussion,
}); enabled: hasCreateDiscussionPermission
} }
);
this.closeEmojiAndAction(showActionSheet, { options }); this.closeEmojiAndAction(showActionSheet, {
options
});
}; };
editCancel = () => { editCancel = () => {

View File

@ -761,6 +761,7 @@
"Enable_writing_in_room": "Enable writing in room", "Enable_writing_in_room": "Enable writing in room",
"Disable_writing_in_room": "Disable writing in room", "Disable_writing_in_room": "Disable writing in room",
"Pinned_a_message": "Pinned a message:", "Pinned_a_message": "Pinned a message:",
"You_dont_have_permission_to_perform_this_action": "You dont have permission to perform this action. Check with a workspace administrator.",
"Jump_to_message": "Jump to message", "Jump_to_message": "Jump to message",
"Missed_call": "Missed call" "Missed_call": "Missed call"
} }

View File

@ -757,5 +757,6 @@
"The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}", "The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}",
"Enable_writing_in_room": "Permitir escrita na sala", "Enable_writing_in_room": "Permitir escrita na sala",
"Disable_writing_in_room": "Desabilitar escrita na sala", "Disable_writing_in_room": "Desabilitar escrita na sala",
"You_dont_have_permission_to_perform_this_action": "Você não tem permissão para realizar esta ação. Verifique com um administrador do espaço de trabalho.",
"Missed_call": "Chamada perdida" "Missed_call": "Chamada perdida"
} }

View File

@ -112,6 +112,7 @@ export const colors = {
strokeExtraLight: '#EBECEF', strokeExtraLight: '#EBECEF',
strokeLight: '#CBCED1', strokeLight: '#CBCED1',
surfaceTint: '#F7F8FA', surfaceTint: '#F7F8FA',
fontDisabled: '#CBCED1',
...mentions, ...mentions,
...callButtons ...callButtons
}, },
@ -199,6 +200,7 @@ export const colors = {
strokeExtraLight: '#2F343D', strokeExtraLight: '#2F343D',
strokeLight: '#333842', strokeLight: '#333842',
surfaceTint: '#1F2329', surfaceTint: '#1F2329',
fontDisabled: '#60646C',
...mentions, ...mentions,
...callButtons ...callButtons
}, },
@ -286,6 +288,7 @@ export const colors = {
strokeExtraLight: '#2F343D', strokeExtraLight: '#2F343D',
strokeLight: '#333842', strokeLight: '#333842',
surfaceTint: '#1F2329', surfaceTint: '#1F2329',
fontDisabled: '#60646C',
...mentions, ...mentions,
...callButtons ...callButtons
} }

View File

@ -186,6 +186,7 @@ describe('Auto Translate', () => {
await waitForVisible('action-sheet-handle'); await waitForVisible('action-sheet-handle');
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Edit')).atIndex(0).swipe('up', 'fast', 0.5);
await waitForVisibleTextMatcher('View original', textMatcher); await waitForVisibleTextMatcher('View original', textMatcher);
await element(by[textMatcher]('View original')).atIndex(0).tap(); await element(by[textMatcher]('View original')).atIndex(0).tap();