Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bf6e350
SelectMessages on MailExportForm
juliajforesti Mar 17, 2022
a9a96ef
fix types
juliajforesti Mar 17, 2022
a19ebaa
useCountSelected implemented
juliajforesti Mar 18, 2022
02b9d74
clear selection on tab close
juliajforesti Mar 18, 2022
06325f8
REVIEW
ggazzo Mar 18, 2022
9352eec
review
ggazzo Mar 21, 2022
1a3a93a
Add CheckBox on MailExport MessageSelect
juliajforesti Mar 21, 2022
e0c680a
Merge branch 'message-template-3' of https://github.com/RocketChat/Ro…
juliajforesti Mar 21, 2022
235b52c
Add reset and clearStore methods on SelectedMessagesProvider
juliajforesti Mar 21, 2022
d78b1ca
Remove jquery handlers
juliajforesti Mar 21, 2022
5ce6d7b
fix ci
ggazzo Mar 22, 2022
c617390
CI
ggazzo Mar 22, 2022
2d3c523
Convert MailExportForm to tsx
juliajforesti Mar 23, 2022
54b26f2
fix
juliajforesti Mar 23, 2022
1b7900d
Convert ExportMessages to tsx
juliajforesti Mar 23, 2022
0ca4241
Convert FileExport to tsx
juliajforesti Mar 23, 2022
1186590
Merge branch 'message-template-3' of https://github.com/RocketChat/Ro…
juliajforesti Mar 23, 2022
68df80b
Add selected style props on Message.tsx
juliajforesti Mar 25, 2022
26ef2e5
fix types
juliajforesti Mar 25, 2022
6e6d68c
Add isEditing prop to MessageTemplate
juliajforesti Mar 28, 2022
536e9bf
Merge branch 'message-template-2' of https://github.com/RocketChat/Ro…
juliajforesti Mar 28, 2022
778f549
review changes
juliajforesti Apr 1, 2022
27fc576
Merge remote-tracking branch 'origin/message-template-2' into message…
ggazzo Apr 1, 2022
05b524e
Merge branch 'message-template-2' into message-template-3
ggazzo Apr 1, 2022
be025d9
update fuselage next version
juliajforesti Apr 1, 2022
c1b0ef0
fix chat.react
ggazzo Apr 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/theme/client/imports/general/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@
--message-box-container-border-color: var(--color-gray-medium);
--message-box-container-border-width: var(--border);
--message-box-container-border-radius: var(--border-radius);
--message-box-editing-color: #fff5df;
--message-box-editing-color: #fff6d6;
--message-box-popover-title-text-color: var(--color-gray);
--message-box-popover-title-text-size: 0.75rem;

Expand Down
97 changes: 50 additions & 47 deletions client/views/room/MessageList/MessageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTranslation } from '../../../contexts/TranslationContext';
import { useUserSubscription } from '../../../contexts/UserContext';
import { useFormatDate } from '../../../hooks/useFormatDate';
import { MessageProvider } from '../providers/MessageProvider';
import { SelectedMessagesProvider } from '../providers/SelectedMessagesProvider';
import Message from './components/Message';
import MessageSystem from './components/MessageSystem';
import { ThreadMessagePreview } from './components/ThreadMessagePreview';
Expand All @@ -31,61 +32,63 @@ export const MessageList: FC<{ rid: IRoom['_id'] }> = ({ rid }) => {
return (
<MessageListProvider rid={rid}>
<MessageProvider rid={rid} broadcast={isBroadcast}>
<MessageHighlightProvider>
{messages.map((message, index, arr) => {
const previous = arr[index - 1];
<SelectedMessagesProvider>
<MessageHighlightProvider>
{messages.map((message, index, arr) => {
const previous = arr[index - 1];

const isSequential = isMessageSequential(message, previous, messageGroupingPeriod);
const isSequential = isMessageSequential(message, previous, messageGroupingPeriod);

const isNewDay = isMessageNewDay(message, previous);
const isFirstUnread = isMessageFirstUnread(subscription, message, previous);
const isUserOwnMessage = isOwnUserMessage(message, subscription);
const shouldShowDivider = isNewDay || isFirstUnread;
const isNewDay = isMessageNewDay(message, previous);
const isFirstUnread = isMessageFirstUnread(subscription, message, previous);
const isUserOwnMessage = isOwnUserMessage(message, subscription);
const shouldShowDivider = isNewDay || isFirstUnread;

const shouldShowAsSequential = isSequential && !isNewDay;
const shouldShowAsSequential = isSequential && !isNewDay;

const isSystemMessage = MessageTypes.isSystemMessage(message);
const shouldShowMessage = !isThreadMessage(message) && !isSystemMessage;
const isSystemMessage = MessageTypes.isSystemMessage(message);
const shouldShowMessage = !isThreadMessage(message) && !isSystemMessage;

return (
<Fragment key={message._id}>
{shouldShowDivider && (
<MessageDivider unreadLabel={isFirstUnread ? t('Unread_Messages').toLowerCase() : undefined}>
{isNewDay && format(message.ts)}
</MessageDivider>
)}
return (
<Fragment key={message._id}>
{shouldShowDivider && (
<MessageDivider unreadLabel={isFirstUnread ? t('Unread_Messages').toLowerCase() : undefined}>
{isNewDay && format(message.ts)}
</MessageDivider>
)}

{shouldShowMessage && (
<Message
id={message._id}
data-id={message._id}
data-system-message={Boolean(message.t)}
data-mid={message._id}
data-unread={isFirstUnread}
data-sequential={isSequential}
data-own={isUserOwnMessage}
sequential={shouldShowAsSequential}
message={message}
subscription={subscription}
/>
)}
{shouldShowMessage && (
<Message
id={message._id}
data-id={message._id}
data-system-message={Boolean(message.t)}
data-mid={message._id}
data-unread={isFirstUnread}
data-sequential={isSequential}
data-own={isUserOwnMessage}
sequential={shouldShowAsSequential}
message={message}
subscription={subscription}
/>
)}

{isThreadMessage(message) && (
<ThreadMessagePreview
data-system-message={Boolean(message.t)}
data-mid={message._id}
data-unread={isFirstUnread}
data-sequential={isSequential}
sequential={shouldShowAsSequential}
message={message as IThreadMessage}
/>
)}
{isThreadMessage(message) && (
<ThreadMessagePreview
data-system-message={Boolean(message.t)}
data-mid={message._id}
data-unread={isFirstUnread}
data-sequential={isSequential}
sequential={shouldShowAsSequential}
message={message as IThreadMessage}
/>
)}

{isSystemMessage && <MessageSystem message={message} />}
</Fragment>
);
})}
</MessageHighlightProvider>
{isSystemMessage && <MessageSystem message={message} />}
</Fragment>
);
})}
</MessageHighlightProvider>
</SelectedMessagesProvider>
</MessageProvider>
</MessageListProvider>
);
Expand Down
24 changes: 18 additions & 6 deletions client/views/room/MessageList/components/Message.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
/* eslint-disable complexity */
import { Message as MessageTemplate, MessageLeftContainer, MessageContainer, MessageBody } from '@rocket.chat/fuselage';
import { Message as MessageTemplate, MessageLeftContainer, MessageContainer, MessageBody, CheckBox } from '@rocket.chat/fuselage';
import { useToggle } from '@rocket.chat/fuselage-hooks';
import React, { FC, memo } from 'react';

import { IMessage } from '../../../../../definition/IMessage';
import { ISubscription } from '../../../../../definition/ISubscription';
import UserAvatar from '../../../../components/avatar/UserAvatar';
import { useIsMessageHighlight } from '../contexts/MessageHighlightContext';
import { useIsSelecting, useToggleSelect, useIsSelectedMessage, useCountSelected } from '../contexts/SelectedMessagesContext';
import MessageContent from './MessageContent';
import MessageContentIgnored from './MessageContentIgnored';
import MessageHeader from './MessageHeader';
import { MessageIndicators } from './MessageIndicators';
import Toolbox from './Toolbox';

const style = { backgroundColor: 'var(--message-box-editing-color)' };

const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubscription; id: IMessage['_id'] }> = ({
message,
sequential,
Expand All @@ -24,18 +23,31 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs
const isMessageHighlight = useIsMessageHighlight(message._id);
const [isMessageIgnored, toggleMessageIgnored] = useToggle(message.ignored);

const isSelecting = useIsSelecting();
const toggleSelected = useToggleSelect(message._id);
const isSelected = useIsSelectedMessage(message._id);
useCountSelected();

return (
<MessageTemplate {...props} style={isMessageHighlight ? style : undefined}>
<MessageTemplate
{...props}
onClick={isSelecting ? toggleSelected : undefined}
isSelected={isSelected}
isEditing={isMessageHighlight}
// highlight={isMessageHighlight}
data-qa-editing={isMessageHighlight}
data-qa-selected={isSelected}
>
<MessageLeftContainer>
{!sequential && message.u.username && <UserAvatar username={message.u.username} size={'x36'} />}
{!sequential && message.u.username && !isSelecting && <UserAvatar username={message.u.username} size={'x36'} />}
{isSelecting && <CheckBox checked={isSelected} onChange={toggleSelected} />}
{sequential && <MessageIndicators message={message} />}
</MessageLeftContainer>

<MessageContainer>
{!sequential && <MessageHeader message={message} />}

{!isMessageIgnored && <MessageContent id={message._id} message={message} subscription={subscription} sequential={sequential} />}

{isMessageIgnored && (
<MessageBody>
<MessageContentIgnored onShowMessageIgnored={toggleMessageIgnored} />
Expand Down
7 changes: 7 additions & 0 deletions client/views/room/MessageList/components/Toolbox/Toolbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useSettings } from '../../../../../contexts/SettingsContext';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { useUser, useUserRoom, useUserSubscription } from '../../../../../contexts/UserContext';
import { getTabBarContext } from '../../../lib/Toolbox/ToolboxContext';
import { useIsSelecting } from '../../contexts/SelectedMessagesContext';
import { MessageActionMenu } from './MessageActionMenu';

export const Toolbox: FC<{ message: IMessage }> = ({ message }) => {
Expand All @@ -31,6 +32,12 @@ export const Toolbox: FC<{ message: IMessage }> = ({ message }) => {

const tabbar = getTabBarContext(message.rid);

const isSelecting = useIsSelecting();

if (isSelecting) {
return null;
}

return (
<MessageToolbox>
{messageActions.map((action) => (
Expand Down
60 changes: 60 additions & 0 deletions client/views/room/MessageList/contexts/SelectedMessagesContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { OffCallbackHandler } from '@rocket.chat/emitter';
import { createContext, useCallback, useContext, useMemo } from 'react';
import { useSubscription } from 'use-subscription';

import { selectedMessageStore } from '../../providers/SelectedMessagesProvider';

type SelectMessageContextValue = {
selectedMessageStore: typeof selectedMessageStore;
};

export const SelectedMessageContext = createContext({
selectedMessageStore,
} as SelectMessageContextValue);

export const useIsSelectedMessage = (mid: string): boolean => {
const { selectedMessageStore } = useContext(SelectedMessageContext);
const subscription = useMemo(
() => ({
getCurrentValue: (): boolean => selectedMessageStore.isSelected(mid),
subscribe: (callback: () => void): OffCallbackHandler => selectedMessageStore.on(mid, callback),
}),
[mid, selectedMessageStore],
);
return useSubscription(subscription);
};

export const useIsSelecting = (): boolean => {
const { selectedMessageStore } = useContext(SelectedMessageContext);

return useSubscription(
useMemo(
() => ({
getCurrentValue: (): boolean => selectedMessageStore.getIsSelecting(),
subscribe: (callback: () => void): OffCallbackHandler => selectedMessageStore.on('toggleIsSelecting', callback),
}),
[selectedMessageStore],
),
);
};

export const useToggleSelect = (mid: string): (() => void) => {
const { selectedMessageStore } = useContext(SelectedMessageContext);
return useCallback(() => {
selectedMessageStore.toggle(mid);
}, [mid, selectedMessageStore]);
};

export const useCountSelected = (): number => {
const { selectedMessageStore } = useContext(SelectedMessageContext);

return useSubscription(
useMemo(
() => ({
getCurrentValue: (): number => selectedMessageStore.count(),
subscribe: (callback: () => void): OffCallbackHandler => selectedMessageStore.on('change', callback),
}),
[selectedMessageStore],
),
);
};
39 changes: 22 additions & 17 deletions client/views/room/Room/Room.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import VerticalBarOldActions from '../components/VerticalBarOldActions';
import { useRoom } from '../contexts/RoomContext';
import AppsContextualBar from '../contextualBar/Apps';
import { useAppsContextualBar } from '../hooks/useAppsContextualBar';
import { SelectedMessagesProvider } from '../providers/SelectedMessagesProvider';
import { useTab, useTabBarOpen, useTabBarClose, useTabBarOpenUserInfo } from '../providers/ToolboxProvider';
import LazyComponent from './LazyComponent';

Expand Down Expand Up @@ -44,27 +45,31 @@ export const Room: FC<{}> = () => {
{tab && (
<RoomTemplate.Aside data-qa-tabbar-name={tab.id}>
<ErrorBoundary>
{typeof tab.template === 'string' && (
<VerticalBarOldActions {...tab} name={tab.template} tabBar={tabBar} rid={room._id} _id={room._id} />
)}
{typeof tab.template !== 'string' && (
<LazyComponent template={tab.template} tabBar={tabBar} rid={room._id} teamId={room.teamId} _id={room._id} />
)}
<SelectedMessagesProvider>
{typeof tab.template === 'string' && (
<VerticalBarOldActions {...tab} name={tab.template} tabBar={tabBar} rid={room._id} _id={room._id} />
)}
{typeof tab.template !== 'string' && (
<LazyComponent template={tab.template} tabBar={tabBar} rid={room._id} teamId={room.teamId} _id={room._id} />
)}
</SelectedMessagesProvider>
</ErrorBoundary>
</RoomTemplate.Aside>
)}
{appsContextualBarContext && (
<RoomTemplate.Aside data-qa-tabbar-name={appsContextualBarContext.viewId}>
<ErrorBoundary>
<LazyComponent
template={AppsContextualBar}
viewId={appsContextualBarContext.viewId}
roomId={appsContextualBarContext.roomId}
payload={appsContextualBarContext.payload}
appInfo={appsContextualBarContext.appInfo}
/>
</ErrorBoundary>
</RoomTemplate.Aside>
<SelectedMessagesProvider>
<RoomTemplate.Aside data-qa-tabbar-name={appsContextualBarContext.viewId}>
<ErrorBoundary>
<LazyComponent
template={AppsContextualBar}
viewId={appsContextualBarContext.viewId}
roomId={appsContextualBarContext.roomId}
payload={appsContextualBarContext.payload}
appInfo={appsContextualBarContext.appInfo}
/>
</ErrorBoundary>
</RoomTemplate.Aside>
</SelectedMessagesProvider>
)}
</RoomTemplate>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { Field, Select, FieldGroup } from '@rocket.chat/fuselage';
import React, { useState, useMemo } from 'react';
import { Field, Select, FieldGroup, SelectOption } from '@rocket.chat/fuselage';
import React, { useState, useMemo, FC } from 'react';

import { IRoom } from '../../../../../definition/IRoom';
import VerticalBar from '../../../../components/VerticalBar';
import { useTranslation } from '../../../../contexts/TranslationContext';
import { useTabBarClose } from '../../providers/ToolboxProvider';
import FileExport from './FileExport';
import MailExportForm from './MailExportForm';

function ExportMessages({ rid }) {
type ExportMessagesProps = {
rid: IRoom['_id'];
};
const ExportMessages: FC<ExportMessagesProps> = ({ rid }) => {
const t = useTranslation();
const close = useTabBarClose();

const [type, setType] = useState('email');

const exportOptions = useMemo(
const exportOptions = useMemo<SelectOption[]>(
() => [
['email', t('Send_via_email')],
['file', t('Export_as_file')],
Expand All @@ -32,7 +36,7 @@ function ExportMessages({ rid }) {
<Field>
<Field.Label>{t('Method')}</Field.Label>
<Field.Row>
<Select value={type} onChange={(value) => setType(value)} placeholder={t('Type')} options={exportOptions} />
<Select value={type} onChange={(value): void => setType(value)} placeholder={t('Type')} options={exportOptions} />
</Field.Row>
</Field>
</FieldGroup>
Expand All @@ -41,6 +45,6 @@ function ExportMessages({ rid }) {
</VerticalBar.ScrollableContent>
</>
);
}
};

export default ExportMessages;
Loading