Skip to content

Commit

Permalink
feat: ComposerSelectMessages
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris committed Dec 3, 2024
1 parent a7be02f commit 115ba85
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,18 @@ export const useToggleSelect = (mid: string): (() => void) => {
}, [mid, selectedMessageStore]);
};

export const useToggleSelectAll = (mids: string[]): (() => void) => {
export const useToggleSelectAll = (): (() => void) => {
const { selectedMessageStore } = useContext(SelectedMessageContext);
return useCallback(() => {
selectedMessageStore.toggleAll(mids);
}, [mids, selectedMessageStore]);
selectedMessageStore.toggleAll(Array.from(selectedMessageStore.availableMessages));
}, [selectedMessageStore]);
};

export const useClearSelection = (): (() => void) => {
const { selectedMessageStore } = useContext(SelectedMessageContext);
return useCallback(() => {
selectedMessageStore.clearStore();
}, [selectedMessageStore]);
};

export const useCountSelected = (): number => {
Expand Down
7 changes: 7 additions & 0 deletions apps/meteor/client/views/room/composer/ComposerContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import type { ComposerMessageProps } from './ComposerMessage';
import ComposerMessage from './ComposerMessage';
import ComposerOmnichannel from './ComposerOmnichannel';
import ComposerReadOnly from './ComposerReadOnly';
import ComposerSelectMessages from './ComposerSelectMessages';
import ComposerVoIP from './ComposerVoIP';
import { useRoom } from '../contexts/RoomContext';
import { useMessageComposerIsAnonymous } from './hooks/useMessageComposerIsAnonymous';
import { useMessageComposerIsArchived } from './hooks/useMessageComposerIsArchived';
import { useMessageComposerIsBlocked } from './hooks/useMessageComposerIsBlocked';
import { useMessageComposerIsReadOnly } from './hooks/useMessageComposerIsReadOnly';
import { useAirGappedRestriction } from '../../../hooks/useAirGappedRestriction';
import { useIsSelecting } from '../MessageList/contexts/SelectedMessagesContext';

const ComposerContainer = ({ children, ...props }: ComposerMessageProps): ReactElement => {
const room = useRoom();
Expand All @@ -28,6 +30,7 @@ const ComposerContainer = ({ children, ...props }: ComposerMessageProps): ReactE
const mustJoinWithCode = !props.subscription && room.joinCodeRequired && !canJoinWithoutCode;

const isAnonymous = useMessageComposerIsAnonymous();
const isSelectingMessages = useIsSelecting();
const isBlockedOrBlocker = useMessageComposerIsBlocked({ subscription: props.subscription });
const isArchived = useMessageComposerIsArchived(room._id, props.subscription);
const isReadOnly = useMessageComposerIsReadOnly(room._id);
Expand Down Expand Up @@ -74,6 +77,10 @@ const ComposerContainer = ({ children, ...props }: ComposerMessageProps): ReactE
return <ComposerBlocked />;
}

if (isSelectingMessages) {
return <ComposerSelectMessages {...props} />;
}

return (
<>
{children}
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/client/views/room/composer/ComposerMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type ComposerMessageProps = {
onNavigateToNextMessage?: () => void;
onNavigateToPreviousMessage?: () => void;
onUploadFiles?: (files: readonly File[]) => void;
onGetMore?: () => void;
};

const ComposerMessage = ({ tmid, onSend, ...props }: ComposerMessageProps): ReactElement => {
Expand Down
36 changes: 36 additions & 0 deletions apps/meteor/client/views/room/composer/ComposerSelectMessages.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Button, ButtonGroup } from '@rocket.chat/fuselage';
import { MessageFooterCallout, MessageFooterCalloutContent } from '@rocket.chat/ui-composer';
import type { ReactElement } from 'react';
import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next';

import type { ComposerMessageProps } from './ComposerMessage';
import { useCountSelected, useClearSelection, SelectedMessageContext } from '../MessageList/contexts/SelectedMessagesContext';

const ComposerSelectMessages = ({ onGetMore }: ComposerMessageProps): ReactElement => {
const { t } = useTranslation();

const { selectedMessageStore } = useContext(SelectedMessageContext);
const clearSelection = useClearSelection();
const countSelected = useCountSelected();
const countAvailable = selectedMessageStore.availableMessages.size;
const noMessagesAvailable = countAvailable <= countSelected;

return (
<MessageFooterCallout>
<MessageFooterCalloutContent>
<div>{countSelected} messages selected</div>
</MessageFooterCalloutContent>
<ButtonGroup>
<Button small disabled={countSelected === 0} onClick={clearSelection}>
{t('Clear_selection')}
</Button>
<Button small primary disabled={noMessagesAvailable} onClick={onGetMore}>
{t(`Batch select ${countAvailable - countSelected} available`)}
</Button>
</ButtonGroup>
</MessageFooterCallout>
);
};

export default ComposerSelectMessages;
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Emitter } from '@rocket.chat/emitter';
import type { ReactNode } from 'react';
import React, { useMemo } from 'react';
import React, { useEffect, useMemo } from 'react';

import { SelectedMessageContext } from '../MessageList/contexts/SelectedMessagesContext';
import { useMessages } from '../MessageList/hooks/useMessages';
import { useRoom } from '../contexts/RoomContext';

// data-qa-select

Expand All @@ -14,6 +16,8 @@ export const selectedMessageStore = new (class SelectMessageStore extends Emitte
> {
store = new Set<string>();

availableMessages = new Set<string>();

isSelecting = false;

setIsSelecting(isSelecting: boolean): void {
Expand Down Expand Up @@ -82,6 +86,13 @@ type SelectedMessagesProviderProps = {
};

export const SelectedMessagesProvider = ({ children }: SelectedMessagesProviderProps) => {
const room = useRoom();
const messages = useMessages({ rid: room._id });

useEffect(() => {
selectedMessageStore.availableMessages = new Set(messages.map((message) => message._id));
}, [messages]);

const value = useMemo(
() => ({
selectedMessageStore,
Expand Down

0 comments on commit 115ba85

Please sign in to comment.