Skip to content

Commit

Permalink
Regression: Show messages instead of the composer when there is no ac…
Browse files Browse the repository at this point in the history
…tion available on federated rooms (#28093)

Co-authored-by: Guilherme Gazzo <5263975+ggazzo@users.noreply.github.com>
Co-authored-by: Douglas Fabris <27704687+dougfabris@users.noreply.github.com>
  • Loading branch information
3 people committed Feb 28, 2023
1 parent b032dd6 commit b3e656a
Show file tree
Hide file tree
Showing 15 changed files with 122 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useMutation } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React from 'react';

export const ComposerAnonymous = (): ReactElement => {
const ComposerAnonymous = (): ReactElement => {
const isAnonymousWriteEnabled = useSetting('Accounts_AllowAnonymousWrite');

const dispatch = useToastMessageDispatch();
Expand Down Expand Up @@ -54,3 +54,5 @@ export const ComposerAnonymous = (): ReactElement => {
</ButtonGroup>
);
};

export default ComposerAnonymous;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React from 'react';

export const ComposerBlocked = (): ReactElement => {
const ComposerBlocked = (): ReactElement => {
const t = useTranslation();
return <MessageFooterCallout>{t('room_is_blocked')}</MessageFooterCallout>;
};

export default ComposerBlocked;
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { isOmnichannelRoom, isVoipRoom } from '@rocket.chat/core-typings';
import { isOmnichannelRoom, isRoomFederated, isVoipRoom } from '@rocket.chat/core-typings';
import type { ReactElement } from 'react';
import React, { memo } from 'react';

import { useRoom } from '../../../contexts/RoomContext';
import { ComposerAnonymous } from './ComposerAnonymous';
import { ComposerBlocked } from './ComposerBlocked';
import { ComposerJoinWithPassword } from './ComposerJoinWithPassword';
import ComposerAnonymous from './ComposerAnonymous';
import ComposerBlocked from './ComposerBlocked';
import ComposerFederation from './ComposerFederation';
import ComposerJoinWithPassword from './ComposerJoinWithPassword';
import type { ComposerMessageProps } from './ComposerMessage';
import ComposerMessage from './ComposerMessage';
import ComposerOmnichannel from './ComposerOmnichannel/ComposerOmnichannel';
import { ComposerReadOnly } from './ComposerReadOnly';
import ComposerReadOnly from './ComposerReadOnly';
import ComposerVoIP from './ComposerVoIP';
import { useMessageComposerIsAnonymous } from './hooks/useMessageComposerIsAnonymous';
import { useMessageComposerIsBlocked } from './hooks/useMessageComposerIsBlocked';
Expand All @@ -28,6 +29,8 @@ const ComposerContainer = ({ children, ...props }: ComposerMessageProps): ReactE

const isOmnichannel = isOmnichannelRoom(room);

const isFederation = isRoomFederated(room);

const isVoip = isVoipRoom(room);

if (isOmnichannel) {
Expand All @@ -38,6 +41,10 @@ const ComposerContainer = ({ children, ...props }: ComposerMessageProps): ReactE
return <ComposerVoIP />;
}

if (isFederation) {
return <ComposerFederation room={room} {...props} />;
}

if (isAnonymous) {
return (
<footer className='rc-message-box footer'>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { useSetting } from '@rocket.chat/ui-contexts';
import React from 'react';
import type { ReactElement } from 'react';

import { useHasLicenseModule } from '../../../../../../../ee/client/hooks/useHasLicenseModule';
import type { ComposerMessageProps } from '../ComposerMessage';
import ComposerMessage from '../ComposerMessage';
import ComposerFederationDisabled from './ComposerFederationDisabled';
import ComposerFederationJoinRoomDisabled from './ComposerFederationJoinRoomDisabled';

const ComposerFederation = ({ room, subscription, children, ...props }: ComposerMessageProps & { room: IRoom }): ReactElement => {
const federationEnabled = useSetting('Federation_Matrix_enabled') === true;
const federationModuleEnabled = useHasLicenseModule('federation') === true;

if (!federationEnabled) {
return (
<footer className='rc-message-box footer'>
<ComposerFederationDisabled />
</footer>
);
}

if (!subscription && !federationModuleEnabled) {
return (
<footer className='rc-message-box footer'>
<ComposerFederationJoinRoomDisabled />
</footer>
);
}

return (
<footer className='rc-message-box footer'>
{children}
<ComposerMessage readOnly={room.ro} {...props} />
</footer>
);
};

export default ComposerFederation;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { MessageFooterCallout } from '@rocket.chat/ui-composer';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React from 'react';

const ComposerFederationDisabled = (): ReactElement => {
const t = useTranslation();

return <MessageFooterCallout>{t('Federation_Matrix_Federated_Description_disabled')}</MessageFooterCallout>;
};

export default ComposerFederationDisabled;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { MessageFooterCallout } from '@rocket.chat/ui-composer';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React from 'react';

const ComposerFederationJoinRoomDisabled = (): ReactElement => {
const t = useTranslation();

return <MessageFooterCallout>{t('Federation_Matrix_join_public_rooms_is_enterprise')}</MessageFooterCallout>;
};

export default ComposerFederationJoinRoomDisabled;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ComposerFederation';
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, { useCallback, useState } from 'react';

import { useRoom } from '../../../contexts/RoomContext';

export const ComposerJoinWithPassword = (): ReactElement => {
const ComposerJoinWithPassword = (): ReactElement => {
const room = useRoom();
const [joinCode, setJoinPassword] = useState<string>('');

Expand Down Expand Up @@ -53,3 +53,5 @@ export const ComposerJoinWithPassword = (): ReactElement => {
</MessageFooterCallout>
);
};

export default ComposerJoinWithPassword;
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React from 'react';
import { dispatchToastMessage } from '../../../../../lib/toast';
import { useRoom, useUserIsSubscribed } from '../../../contexts/RoomContext';

export const ComposerReadOnly = (): ReactElement => {
const ComposerReadOnly = (): ReactElement => {
const t = useTranslation();
const room = useRoom();
const isSubscribed = useUserIsSubscribed();
Expand All @@ -33,3 +33,5 @@ export const ComposerReadOnly = (): ReactElement => {
</footer>
);
};

export default ComposerReadOnly;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable complexity */
import { isRoomFederated } from '@rocket.chat/core-typings';
import type { IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings';
import { Button, Tag, Box } from '@rocket.chat/fuselage';
import { useContentBoxSize, useMutableCallback } from '@rocket.chat/fuselage-hooks';
Expand All @@ -12,7 +11,7 @@ import {
MessageComposerActionsDivider,
MessageComposerToolbarSubmit,
} from '@rocket.chat/ui-composer';
import { useTranslation, useUserPreference, useLayout, useSetting } from '@rocket.chat/ui-contexts';
import { useTranslation, useUserPreference, useLayout } from '@rocket.chat/ui-contexts';
import { useMutation } from '@tanstack/react-query';
import type { MouseEventHandler, ReactElement, FormEvent, KeyboardEventHandler, KeyboardEvent, Ref, ClipboardEventHandler } from 'react';
import React, { memo, useRef, useReducer, useCallback } from 'react';
Expand All @@ -25,7 +24,6 @@ import { formattingButtons } from '../../../../../../../app/ui-message/client/me
import ComposerBoxPopup from '../../../../../../../app/ui-message/client/popup/ComposerBoxPopup';
import ComposerBoxPopupPreview from '../../../../../../../app/ui-message/client/popup/components/composerBoxPopupPreview/ComposerBoxPopupPreview';
import { useComposerBoxPopup } from '../../../../../../../app/ui-message/client/popup/hooks/useComposerBoxPopup';
import { useHasLicenseModule } from '../../../../../../../ee/client/hooks/useHasLicenseModule';
import { getImageExtensionFromMime } from '../../../../../../../lib/getImageExtensionFromMime';
import { useFormatDateAndTime } from '../../../../../../hooks/useFormatDateAndTime';
import { useReactiveValue } from '../../../../../../hooks/useReactiveValue';
Expand All @@ -36,7 +34,6 @@ import AudioMessageRecorder from '../../../../../composer/AudioMessageRecorder';
import VideoMessageRecorder from '../../../../../composer/VideoMessageRecorder';
import { useChat } from '../../../../contexts/ChatContext';
import { useComposerPopup } from '../../../../contexts/ComposerPopupContext';
import { useRoom } from '../../../../contexts/RoomContext';
import ComposerUserActionIndicator from '../ComposerUserActionIndicator';
import { useAutoGrow } from '../RoomComposer/hooks/useAutoGrow';
import { useMessageComposerMergedRefs } from '../hooks/useMessageComposerMergedRefs';
Expand Down Expand Up @@ -124,7 +121,6 @@ const MessageBox = ({
if (!chat) {
throw new Error('Chat context not found');
}
const room = useRoom();

const textareaRef = useRef<HTMLTextAreaElement>(null);
const messageComposerRef = useRef<HTMLElement>(null);
Expand Down Expand Up @@ -280,13 +276,8 @@ const MessageBox = ({

const { textAreaStyle, shadowStyle } = useAutoGrow(textareaRef, shadowRef, isRecordingAudio);

const federationModuleEnabled = useHasLicenseModule('federation') === true;
const federationEnabled = useSetting('Federation_Matrix_enabled') === true;

const canSend = useReactiveValue(useCallback(() => roomCoordinator.verifyCanSendMessage(rid), [rid]));

const canJoin = !isRoomFederated(room) || (isRoomFederated(room) && federationModuleEnabled && federationEnabled);

const sizes = useContentBoxSize(textareaRef);

const format = useFormatDateAndTime();
Expand Down Expand Up @@ -391,7 +382,7 @@ const MessageBox = ({
ref={mergedRefs as unknown as Ref<HTMLInputElement>}
aria-label={t('Message')}
name='msg'
disabled={isRecording || (!canJoin && !canSend)}
disabled={isRecording || !canSend}
onChange={setTyping}
style={textAreaStyle}
placeholder={t('Message')}
Expand All @@ -404,7 +395,7 @@ const MessageBox = ({
<MessageComposerToolbarActions aria-label={t('Message_composer_toolbox_primary_actions')}>
<MessageComposerAction
icon='emoji'
disabled={!useEmojis || isRecording || (!canJoin && !canSend)}
disabled={!useEmojis || isRecording || !canSend}
onClick={handleOpenEmojiPicker}
title={t('Emoji')}
/>
Expand All @@ -414,7 +405,7 @@ const MessageBox = ({
composer={chat.composer}
variant={sizes.inlineSize < 480 ? 'small' : 'large'}
items={formatters}
disabled={isRecording || (!canJoin && !canSend)}
disabled={isRecording || !canSend}
/>
)}
<MessageComposerActionsDivider />
Expand All @@ -423,14 +414,13 @@ const MessageBox = ({
isRecording={isRecording}
typing={typing}
canSend={canSend}
canJoin={canJoin}
rid={rid}
tmid={tmid}
isMicrophoneDenied={isMicrophoneDenied}
/>
</MessageComposerToolbarActions>
<MessageComposerToolbarSubmit>
{!canSend && canJoin && (
{!canSend && (
<Button small primary onClick={onJoin} disabled={joinMutation.isLoading}>
{t('Join')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type MessageBoxActionsToolbarProps = {
isRecording: boolean;
typing: boolean;
canSend: boolean;
canJoin: boolean;
rid: IRoom['_id'];
tmid?: IMessage['_id'];
isMicrophoneDenied?: boolean;
Expand All @@ -24,14 +23,13 @@ const MessageBoxActionsToolbar = ({
canSend,
rid,
tmid,
canJoin,
isMicrophoneDenied,
}: MessageBoxActionsToolbarProps) => {
const actions = [
<VideoMessageAction key='video' collapsed={variant === 'small'} disabled={(!canJoin && !canSend) || typing || isRecording} />,
<VideoMessageAction key='video' collapsed={variant === 'small'} disabled={!canSend || typing || isRecording} />,
<AudioMessageAction
key='audio'
disabled={(!canJoin && !canSend) || typing || isRecording || isMicrophoneDenied}
disabled={!canSend || typing || isRecording || isMicrophoneDenied}
isMicrophoneDenied={isMicrophoneDenied}
/>,
<FileUploadAction key='file' collapsed={variant === 'small'} disabled={!canSend || isRecording} />,
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2143,7 +2143,7 @@
"Federation_Matrix_Enabled_Alert": "<a target=\"_blank\" href=\"https://go.rocket.chat/i/matrix-federation\">More Information about Matrix Federation support can be found here</> (After any configuration, a restart is required to the changes take effect)",
"Federation_Matrix_Federated": "Federated",
"Federation_Matrix_Federated_Description": "By creating a federated room you'll not be able to enable encryption nor broadcast",
"Federation_Matrix_Federated_Description_disabled": "This feature is currently disabled in this workspace.",
"Federation_Matrix_Federated_Description_disabled": "Federation is currently disabled in this workspace.",
"Federation_Matrix_id": "AppService ID",
"Federation_Matrix_hs_token": "Homeserver Token",
"Federation_Matrix_as_token": "AppService Token",
Expand All @@ -2163,6 +2163,7 @@
"Federation_Matrix_losing_privileges_warning": "You won't be able to undo this action, as you're demoting yourself. If you're the last privileged user you won't be able to regain this privilege. Do you want to proceed still?",
"Federation_Matrix_not_allowed_to_change_moderator": "You are not allowed to change the moderator",
"Federation_Matrix_not_allowed_to_change_owner": "You are not allowed to change the owner",
"Federation_Matrix_join_public_rooms_is_enterprise": "Join federated rooms is an Enterprise Edition feature",
"Field": "Field",
"Field_removed": "Field removed",
"Field_required": "Field required",
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/messaging.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ test.describe.serial('Messaging', () => {
await poHomeChannel.sidenav.openChat(targetChannel);
const { page } = await createAuxContext(browser, Users.user2);
const auxContext = { page, poHomeChannel: new HomeChannel(page) };

await auxContext.poHomeChannel.sidenav.openChat(targetChannel);

await poHomeChannel.content.sendMessage('hello world');
Expand Down
22 changes: 22 additions & 0 deletions apps/meteor/tests/e2e/page-objects/fragments/home-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,34 @@ export class HomeContent {
return this.page.locator('.rcx-room-header button > i.rcx-icon--name-key');
}

get btnJoinRoom(): Locator {
return this.page.locator('//button[contains(text(), "Join")]');
}

async joinRoom(): Promise<void> {
await this.btnJoinRoom.click();
}

async joinRoomIfNeeded(): Promise<void> {
if (await this.inputMessage.isEnabled()) {
return;
}
if (!(await this.btnJoinRoom.isVisible())) {
return;
}
await this.joinRoom();
}

async sendMessage(text: string): Promise<void> {
await this.joinRoomIfNeeded();
await this.page.waitForSelector('[name="msg"]:not([disabled])');
await this.page.locator('[name="msg"]').type(text);
await this.page.keyboard.press('Enter');
}

async dispatchSlashCommand(text: string): Promise<void> {
await this.joinRoomIfNeeded();
await this.page.waitForSelector('[name="msg"]:not([disabled])');
await this.page.locator('[name="msg"]').type(text);
await this.page.keyboard.press('Enter');
await this.page.keyboard.press('Enter');
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/tests/e2e/permissions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ test.describe.serial('permissions', () => {

test('expect option(edit) not be visible', async ({ page }) => {
await poHomeChannel.sidenav.openChat(targetChannel);

await poHomeChannel.content.sendMessage('expect option(edit) not be visible');

await expect(page.locator('.rcx-message', { hasText: 'expect option(edit) not be visible' })).not.toHaveAttribute(
Expand Down

0 comments on commit b3e656a

Please sign in to comment.