From f03f79d710baeac1929fd05bf265aa510ef5a537 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Mon, 1 Feb 2021 22:44:17 -0300 Subject: [PATCH 1/5] use list hooks --- client/contexts/UserContext.ts | 4 +- client/lib/lists/FilesList.ts | 40 +++++++++++ .../room/contextualBar/RoomFiles/RoomFiles.js | 47 +++--------- .../RoomFiles/hooks/useFilesList.ts | 72 +++++++++++++++++++ 4 files changed, 124 insertions(+), 39 deletions(-) create mode 100644 client/lib/lists/FilesList.ts create mode 100644 client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts diff --git a/client/contexts/UserContext.ts b/client/contexts/UserContext.ts index c59596f9b5300..5c7ef3548781f 100644 --- a/client/contexts/UserContext.ts +++ b/client/contexts/UserContext.ts @@ -32,7 +32,7 @@ type UserContextValue = { loginWithPassword: (user: string | object, password: string) => Promise; queryPreference: (key: string | Mongo.ObjectID, defaultValue?: T) => Subscription; querySubscription: (query: FilterQuery, fields: Fields, sort?: Sort) => Subscription ; - queryRoom: (query: FilterQuery, fields: Fields, sort?: Sort) => Subscription ; + queryRoom: (query: FilterQuery, fields?: Fields, sort?: Sort) => Subscription ; querySubscriptions: (query: SubscriptionQuery, options?: FindOptions) => Subscription | []>; }; @@ -79,7 +79,7 @@ export const useUserSubscription = (rid: string, fields: Fields): ISubscription return useSubscription(subscription); }; -export const useUserRoom = (rid: string, fields: Fields): IRoom | undefined => { +export const useUserRoom = (rid: string, fields?: Fields): IRoom | undefined => { const { queryRoom } = useContext(UserContext); const subscription = useMemo(() => queryRoom({ _id: rid }, fields), [queryRoom, rid, fields]); return useSubscription(subscription); diff --git a/client/lib/lists/FilesList.ts b/client/lib/lists/FilesList.ts new file mode 100644 index 0000000000000..985fd2f6dae5f --- /dev/null +++ b/client/lib/lists/FilesList.ts @@ -0,0 +1,40 @@ +import { MessageList } from './MessageList'; +import type { IMessage } from '../../../definition/IMessage'; + +type FilesMessage = Omit & Required>; + +export type FilesListOptions = { + rid: IMessage['rid']; +}; + +const isFileMessageInRoom = (message: IMessage, rid: IMessage['rid']): message is FilesMessage => + message.rid === rid && 'rid' in message; + +export class FilesList extends MessageList { + public constructor(private _options: FilesListOptions) { + super(); + } + + public get options(): FilesListOptions { + return this._options; + } + + public updateFilters(options: FilesListOptions): void { + this._options = options; + this.clear(); + } + + protected filter(message: IMessage): boolean { + const { rid } = this._options; + + if (!isFileMessageInRoom(message, rid)) { + return false; + } + + return true; + } + + protected compare(a: IMessage, b: IMessage): number { + return (b.tlm ?? b.ts).getTime() - (a.tlm ?? a.ts).getTime(); + } +} diff --git a/client/views/room/contextualBar/RoomFiles/RoomFiles.js b/client/views/room/contextualBar/RoomFiles/RoomFiles.js index abbb4ac888647..66d1c5d766812 100644 --- a/client/views/room/contextualBar/RoomFiles/RoomFiles.js +++ b/client/views/room/contextualBar/RoomFiles/RoomFiles.js @@ -1,5 +1,5 @@ import React, { useState, useCallback, useMemo } from 'react'; -import { useMutableCallback, useLocalStorage, useDebouncedState, useUniqueId, useResizeObserver } from '@rocket.chat/fuselage-hooks'; +import { useMutableCallback, useLocalStorage, useUniqueId, useResizeObserver } from '@rocket.chat/fuselage-hooks'; import { Box, Icon, @@ -22,8 +22,9 @@ import { useTranslation } from '../../../../contexts/TranslationContext'; import VerticalBar from '../../../../components/VerticalBar'; import FileItem from './components/FileItem'; import ScrollableContentWrapper from '../../../../components/ScrollableContentWrapper'; -import { useFileList } from './hooks/useFileList'; -import { useComponentDidUpdate } from '../../../../hooks/useComponentDidUpdate'; +// import { useFileList } from './hooks/useFileList'; +import { useFilesList } from './hooks/useFilesList'; +import { useRecordList } from '../../../../hooks/lists/useRecordList'; import { useMessageDeletionIsAllowed } from './hooks/useMessageDeletionIsAllowed'; import { useTabBarClose } from '../../providers/ToolboxProvider'; @@ -116,7 +117,7 @@ export const RoomFiles = function RoomFiles({ {} : loadMoreItems} > {({ onItemsRendered, ref }) => ( { const uid = useUserId(); const onClickClose = useTabBarClose(); const room = useUserRoom(rid); - room.type = room.t; room.rid = rid; const setModal = useSetModal(); @@ -156,33 +156,12 @@ export default ({ rid }) => { const [type, setType] = useLocalStorage('file-list-type', 'all'); const [text, setText] = useState(''); - const [query, setQuery] = useDebouncedState({ - roomId: rid, - sort: JSON.stringify({ uploadedAt: -1 }), - count: 50, - query: JSON.stringify({ - ...type !== 'all' && { - typeGroup: type, - }, - }), - }, 500); - const handleTextChange = useCallback((event) => { setText(event.currentTarget.value); }, []); - useComponentDidUpdate(() => setQuery((params) => ({ - ...params, - roomId: rid, - query: JSON.stringify({ - name: { $regex: text || '', $options: 'i' }, - ...type !== 'all' && { - typeGroup: type, - }, - }), - })), [rid, text, type, setQuery]); - - const { value: data, phase: state, reload, more } = useFileList(room.type, query); + const { filesList, loadMoreItems } = useFilesList(room.t); + const { phase, items: filesItems, itemCount: totalItemCount } = useRecordList(filesList); const handleDelete = useMutableCallback((_id) => { const onConfirm = async () => { @@ -192,30 +171,24 @@ export default ({ rid }) => { dispatchToastMessage({ type: 'error', message: error }); } closeModal(); - reload(); }; setModal(); }, []); - const loadMoreItems = useCallback((start, end) => more((params) => ({ ...params, offset: start, count: end - start }), (prev, next) => ({ - total: next.total, - files: [...prev.files, ...next.files], - })), [more]); - const isDeletionAllowed = useMessageDeletionIsAllowed(rid, uid); return ( void; + } => { + const room = useUserRoom(rid); + const [filesList] = useState(() => new FilesList(options)); + + useEffect(() => { + if (filesList.options !== options) { + filesList.updateFilters(options); + } + }, [filesList, options]); + + const roomTypes = { + c: 'channels.files', + l: 'channels.files', + d: 'im.files', + p: 'groups.files', + }; + + const apiEndPoint = room && roomTypes[room.t]; + + const getFiles = useEndpoint('GET', apiEndPoint as string); + + const fetchMessages = useCallback( + async (start, end) => { + const { messages, total } = await getFiles({ + roomId: options.rid, + count: end - start, + }); + + return { + items: messages, + itemCount: total, + }; + }, + [getFiles, options.rid], + ); + + const { loadMoreItems, initialItemCount } = useScrollableMessageList( + filesList, + fetchMessages, + useMemo(() => { + const filesListSize = getConfig('discussionListSize'); + return filesListSize ? parseInt(filesListSize, 10) : undefined; + }, []), + ); + // useStreamUpdatesForMessageList(filesList, uid, options.rid); + + return { + filesList, + loadMoreItems, + initialItemCount, + }; +}; From b649bc7db595b00d0c7f9f60f5cd08f407d60230 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 2 Feb 2021 00:21:51 -0300 Subject: [PATCH 2/5] WIP - HELP Tiago --- .../room/contextualBar/RoomFiles/hooks/useFilesList.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts b/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts index b7c4dcc810c92..65f77d85a6255 100644 --- a/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts +++ b/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts @@ -8,20 +8,19 @@ import { useEndpoint } from '../../../../../contexts/ServerContext'; import { useUserRoom } from '../../../../../contexts/UserContext'; import { useScrollableMessageList } from '../../../../../hooks/lists/useScrollableMessageList'; // import { useStreamUpdatesForMessageList } from '../../../../../hooks/lists/useStreamUpdatesForMessageList'; -import { IRoom } from '../../../../../../definition/IRoom'; import { getConfig } from '../../../../../../app/ui-utils/client/config'; export const useFilesList = ( options: FilesListOptions, - rid: IRoom['_id'], ): { filesList: FilesList; initialItemCount: number; loadMoreItems: (start: number, end: number) => void; } => { - const room = useUserRoom(rid); const [filesList] = useState(() => new FilesList(options)); + const room = useUserRoom(options.rid); + useEffect(() => { if (filesList.options !== options) { filesList.updateFilters(options); @@ -41,13 +40,13 @@ export const useFilesList = ( const fetchMessages = useCallback( async (start, end) => { - const { messages, total } = await getFiles({ + const { files, total } = await getFiles({ roomId: options.rid, count: end - start, }); return { - items: messages, + items: files, itemCount: total, }; }, From 306bc5c9d108ac0fa827ca309ab7fbc15cf41218 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Tue, 2 Feb 2021 00:51:16 -0300 Subject: [PATCH 3/5] fix eslint error --- client/views/room/contextualBar/RoomFiles/RoomFiles.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/views/room/contextualBar/RoomFiles/RoomFiles.js b/client/views/room/contextualBar/RoomFiles/RoomFiles.js index f349b5b77aa1f..2f8fdafc8f8b7 100644 --- a/client/views/room/contextualBar/RoomFiles/RoomFiles.js +++ b/client/views/room/contextualBar/RoomFiles/RoomFiles.js @@ -11,7 +11,7 @@ import { import { Virtuoso } from 'react-virtuoso'; import memoize from 'memoize-one'; -import { useUserId, useUserRoom } from '../../../../contexts/UserContext'; +import { useUserId } from '../../../../contexts/UserContext'; import DeleteFileWarning from '../../../../components/DeleteFileWarning'; import { useToastMessageDispatch } from '../../../../contexts/ToastMessagesContext'; import { useSetModal } from '../../../../contexts/ModalContext'; From 67c8491cf1073b4f390e82bf25dd0f0a1ab303d4 Mon Sep 17 00:00:00 2001 From: Tiago Evangelista Pinto Date: Tue, 2 Feb 2021 01:27:47 -0300 Subject: [PATCH 4/5] add stream update and filter inputs --- client/lib/lists/FilesList.ts | 2 ++ .../room/contextualBar/RoomFiles/RoomFiles.js | 4 +--- .../RoomFiles/components/FileItem.js | 4 ++-- .../RoomFiles/hooks/useFilesList.ts | 16 ++++++++++++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/client/lib/lists/FilesList.ts b/client/lib/lists/FilesList.ts index 985fd2f6dae5f..1e0cb830f328e 100644 --- a/client/lib/lists/FilesList.ts +++ b/client/lib/lists/FilesList.ts @@ -5,6 +5,8 @@ type FilesMessage = Omit & Required>; export type FilesListOptions = { rid: IMessage['rid']; + type: string; + text: string; }; const isFileMessageInRoom = (message: IMessage, rid: IMessage['rid']): message is FilesMessage => diff --git a/client/views/room/contextualBar/RoomFiles/RoomFiles.js b/client/views/room/contextualBar/RoomFiles/RoomFiles.js index 2f8fdafc8f8b7..11c878ef5f0f4 100644 --- a/client/views/room/contextualBar/RoomFiles/RoomFiles.js +++ b/client/views/room/contextualBar/RoomFiles/RoomFiles.js @@ -132,8 +132,6 @@ RoomFiles.Item = FileItem; export default ({ rid }) => { const uid = useUserId(); const onClickClose = useTabBarClose(); - // const room = useUserRoom(rid); - // room.rid = rid; const setModal = useSetModal(); const closeModal = useMutableCallback(() => setModal()); @@ -147,7 +145,7 @@ export default ({ rid }) => { setText(event.currentTarget.value); }, []); - const { filesList, loadMoreItems } = useFilesList(useMemo(() => ({ rid }), [rid])); + const { filesList, loadMoreItems } = useFilesList(useMemo(() => ({ rid, type, text }), [rid, type, text])); const { phase, items: filesItems, itemCount: totalItemCount } = useRecordList(filesList); const handleDelete = useMutableCallback((_id) => { diff --git a/client/views/room/contextualBar/RoomFiles/components/FileItem.js b/client/views/room/contextualBar/RoomFiles/components/FileItem.js index c55f3ca0cbe64..0fd12419e56c5 100644 --- a/client/views/room/contextualBar/RoomFiles/components/FileItem.js +++ b/client/views/room/contextualBar/RoomFiles/components/FileItem.js @@ -44,12 +44,12 @@ export const FileItem = ({ _id, name, url, uploadedAt, ts, user, type, typeGroup { typeGroup === 'image' ? : } {name} - @{user.username} + @{user?.username} {format(uploadedAt)} - + ; }; diff --git a/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts b/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts index 65f77d85a6255..7e6b2a44fe5e0 100644 --- a/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts +++ b/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts @@ -5,9 +5,9 @@ import { FilesListOptions, } from '../../../../../lib/lists/FilesList'; import { useEndpoint } from '../../../../../contexts/ServerContext'; -import { useUserRoom } from '../../../../../contexts/UserContext'; +import { useUserRoom, useUserId } from '../../../../../contexts/UserContext'; import { useScrollableMessageList } from '../../../../../hooks/lists/useScrollableMessageList'; -// import { useStreamUpdatesForMessageList } from '../../../../../hooks/lists/useStreamUpdatesForMessageList'; +import { useStreamUpdatesForMessageList } from '../../../../../hooks/lists/useStreamUpdatesForMessageList'; import { getConfig } from '../../../../../../app/ui-utils/client/config'; export const useFilesList = ( @@ -20,6 +20,7 @@ export const useFilesList = ( const [filesList] = useState(() => new FilesList(options)); const room = useUserRoom(options.rid); + const uid = useUserId(); useEffect(() => { if (filesList.options !== options) { @@ -43,6 +44,13 @@ export const useFilesList = ( const { files, total } = await getFiles({ roomId: options.rid, count: end - start, + sort: JSON.stringify({ uploadedAt: -1 }), + query: JSON.stringify({ + name: { $regex: options.text || '', $options: 'i' }, + ...options.type !== 'all' && { + typeGroup: options.type, + }, + }), }); return { @@ -50,7 +58,7 @@ export const useFilesList = ( itemCount: total, }; }, - [getFiles, options.rid], + [getFiles, options.rid, options.type, options.text], ); const { loadMoreItems, initialItemCount } = useScrollableMessageList( @@ -61,7 +69,7 @@ export const useFilesList = ( return filesListSize ? parseInt(filesListSize, 10) : undefined; }, []), ); - // useStreamUpdatesForMessageList(filesList, uid, options.rid); + useStreamUpdatesForMessageList(filesList, uid, options.rid); return { filesList, From 9e2f47556e852a83ca1187d004d3ced716805f35 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 3 Feb 2021 23:25:40 -0300 Subject: [PATCH 5/5] Update RoomFiles.js --- client/views/room/contextualBar/RoomFiles/RoomFiles.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/views/room/contextualBar/RoomFiles/RoomFiles.js b/client/views/room/contextualBar/RoomFiles/RoomFiles.js index 11c878ef5f0f4..5e7c4eeb45cc7 100644 --- a/client/views/room/contextualBar/RoomFiles/RoomFiles.js +++ b/client/views/room/contextualBar/RoomFiles/RoomFiles.js @@ -79,8 +79,6 @@ export const RoomFiles = function RoomFiles({ const itemData = createItemData(onClickDelete, isDeletionAllowed); - // const lm = useMutableCallback((start) => loadMoreItems(start + 1, Math.min(50, start + 1 - filesItems.length))); - return ( <>