Merge branch 'next-virtuoso' into 'next'
Next: ChatList: use Virtuoso See merge request soapbox-pub/soapbox-fe!1225
This commit is contained in:
commit
6f4ca2cf23
6 changed files with 69 additions and 38 deletions
Binary file not shown.
|
@ -1,12 +1,13 @@
|
|||
import { Map as ImmutableMap } from 'immutable';
|
||||
import { debounce } from 'lodash';
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { expandChats } from 'soapbox/actions/chats';
|
||||
import ScrollableList from 'soapbox/components/scrollable_list';
|
||||
import { fetchChats, expandChats } from 'soapbox/actions/chats';
|
||||
import PullToRefresh from 'soapbox/components/pull-to-refresh';
|
||||
import { Text } from 'soapbox/components/ui';
|
||||
import PlaceholderChat from 'soapbox/features/placeholder/components/placeholder_chat';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
|
@ -16,10 +17,6 @@ const messages = defineMessages({
|
|||
emptyMessage: { id: 'chat_panels.main_window.empty', defaultMessage: 'No chats found. To start a chat, visit a user\'s profile' },
|
||||
});
|
||||
|
||||
const handleLoadMore = debounce((dispatch) => {
|
||||
dispatch(expandChats());
|
||||
}, 300, { leading: true });
|
||||
|
||||
const getSortedChatIds = (chats: ImmutableMap<string, any>) => (
|
||||
chats
|
||||
.toList()
|
||||
|
@ -45,10 +42,10 @@ const sortedChatIdsSelector = createSelector(
|
|||
|
||||
interface IChatList {
|
||||
onClickChat: (chat: any) => void,
|
||||
onRefresh: () => void,
|
||||
useWindowScroll?: boolean,
|
||||
}
|
||||
|
||||
const ChatList: React.FC<IChatList> = ({ onClickChat, onRefresh }) => {
|
||||
const ChatList: React.FC<IChatList> = ({ onClickChat, useWindowScroll = false }) => {
|
||||
const dispatch = useDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
|
@ -56,28 +53,41 @@ const ChatList: React.FC<IChatList> = ({ onClickChat, onRefresh }) => {
|
|||
const hasMore = useAppSelector(state => !!state.chats.get('next'));
|
||||
const isLoading = useAppSelector(state => state.chats.get('isLoading'));
|
||||
|
||||
const handleLoadMore = useCallback(() => {
|
||||
if (hasMore && !isLoading) {
|
||||
dispatch(expandChats());
|
||||
}
|
||||
}, [dispatch, hasMore, isLoading]);
|
||||
|
||||
const handleRefresh = () => {
|
||||
return dispatch(fetchChats()) as any;
|
||||
};
|
||||
|
||||
return (
|
||||
<ScrollableList
|
||||
<PullToRefresh onRefresh={handleRefresh}>
|
||||
<Virtuoso
|
||||
className='chat-list'
|
||||
scrollKey='awaiting-approval'
|
||||
emptyMessage={intl.formatMessage(messages.emptyMessage)}
|
||||
hasMore={hasMore}
|
||||
isLoading={isLoading}
|
||||
showLoading={isLoading && chatIds.size === 0}
|
||||
onLoadMore={() => handleLoadMore(dispatch)}
|
||||
onRefresh={onRefresh}
|
||||
placeholderComponent={PlaceholderChat}
|
||||
placeholderCount={20}
|
||||
>
|
||||
{chatIds.map((chatId: string) => (
|
||||
<div key={chatId} className='chat-list-item'>
|
||||
<Chat
|
||||
chatId={chatId}
|
||||
onClick={onClickChat}
|
||||
useWindowScroll={useWindowScroll}
|
||||
data={chatIds.toArray()}
|
||||
endReached={handleLoadMore}
|
||||
itemContent={(_index, chatId) => (
|
||||
<Chat chatId={chatId} onClick={onClickChat} />
|
||||
)}
|
||||
components={{
|
||||
ScrollSeekPlaceholder: () => <PlaceholderChat />,
|
||||
Footer: () => hasMore ? <PlaceholderChat /> : null,
|
||||
EmptyPlaceholder: () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<>{Array(20).fill(<PlaceholderChat />)}</>
|
||||
);
|
||||
} else {
|
||||
return <Text>{intl.formatMessage(messages.emptyMessage)}</Text>;
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</ScrollableList>
|
||||
</PullToRefresh>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { fetchChats, launchChat } from 'soapbox/actions/chats';
|
||||
import { launchChat } from 'soapbox/actions/chats';
|
||||
import AccountSearch from 'soapbox/components/account_search';
|
||||
import AudioToggle from 'soapbox/features/chats/components/audio_toggle';
|
||||
|
||||
|
@ -29,10 +29,6 @@ const ChatIndex: React.FC = () => {
|
|||
history.push(`/chats/${chat.id}`);
|
||||
};
|
||||
|
||||
const handleRefresh = () => {
|
||||
return dispatch(fetchChats());
|
||||
};
|
||||
|
||||
return (
|
||||
<Column label={intl.formatMessage(messages.title)}>
|
||||
<div className='column__switch'>
|
||||
|
@ -46,7 +42,7 @@ const ChatIndex: React.FC = () => {
|
|||
|
||||
<ChatList
|
||||
onClickChat={handleClickChat}
|
||||
onRefresh={handleRefresh}
|
||||
useWindowScroll
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
|
|
|
@ -90,12 +90,16 @@
|
|||
&__content {
|
||||
@apply flex flex-1 flex-col overflow-hidden bg-white dark:bg-slate-800;
|
||||
|
||||
> div {
|
||||
@apply max-h-full;
|
||||
}
|
||||
|
||||
.chat-box {
|
||||
@apply flex flex-1 flex-col overflow-hidden;
|
||||
}
|
||||
|
||||
.chat-list {
|
||||
@apply overflow-y-auto;
|
||||
@apply overflow-y-auto max-h-full;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
"react-swipeable-views": "^0.14.0",
|
||||
"react-textarea-autosize": "^8.3.3",
|
||||
"react-toggle": "^4.0.1",
|
||||
"react-virtuoso": "^2.9.1",
|
||||
"redux": "^4.1.1",
|
||||
"redux-immutable": "^4.0.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -2388,6 +2388,18 @@
|
|||
"@typescript-eslint/types" "5.15.0"
|
||||
eslint-visitor-keys "^3.0.0"
|
||||
|
||||
"@virtuoso.dev/react-urx@^0.2.12":
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/@virtuoso.dev/react-urx/-/react-urx-0.2.13.tgz#e2cfc42d259d2a002695e7517d34cb97b64ee9c4"
|
||||
integrity sha512-MY0ugBDjFb5Xt8v2HY7MKcRGqw/3gTpMlLXId2EwQvYJoC8sP7nnXjAxcBtTB50KTZhO0SbzsFimaZ7pSdApwA==
|
||||
dependencies:
|
||||
"@virtuoso.dev/urx" "^0.2.13"
|
||||
|
||||
"@virtuoso.dev/urx@^0.2.12", "@virtuoso.dev/urx@^0.2.13":
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/@virtuoso.dev/urx/-/urx-0.2.13.tgz#a65e7e8d923cb03397ac876bfdd45c7f71c8edf1"
|
||||
integrity sha512-iirJNv92A1ZWxoOHHDYW/1KPoi83939o83iUBQHIim0i3tMeSKEh+bxhJdTHQ86Mr4uXx9xGUTq69cp52ZP8Xw==
|
||||
|
||||
"@webassemblyjs/ast@1.11.1":
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
|
||||
|
@ -8979,6 +8991,14 @@ react-transition-group@^2.2.1:
|
|||
prop-types "^15.6.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react-virtuoso@^2.9.1:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-2.9.1.tgz#9a4279824d07ea3e0ebd76be932f55f7244b10ad"
|
||||
integrity sha512-TtaCj0qGVCicti2o/ScN5Pqe7ARw6cAGQzd9vDcJcbS2ZpOWNe248Ifn+QP0lk92VP/ROgDwWajH1aEZz056Ow==
|
||||
dependencies:
|
||||
"@virtuoso.dev/react-urx" "^0.2.12"
|
||||
"@virtuoso.dev/urx" "^0.2.12"
|
||||
|
||||
react@^16.13.1:
|
||||
version "16.14.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
|
||||
|
|
Loading…
Reference in a new issue