[Refactoring] Infinite Scroll: Support absolute positioning

This commit is contained in:
Alexander Zinchuk 2022-02-02 22:49:10 +01:00
parent 5f6040b82c
commit 27d7f92756
3 changed files with 49 additions and 53 deletions

View File

@ -4,7 +4,6 @@ import React, {
} from '../../lib/teact/teact';
import { CHAT_HEIGHT_PX } from '../../config';
import { IS_ANDROID } from '../../util/environment';
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
import useLang from '../../hooks/useLang';
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
@ -105,31 +104,24 @@ const ChatOrUserPicker: FC<OwnProps> = ({
className="picker-list custom-scroll"
items={viewportIds}
onLoadMore={getMore}
noFastList
noScrollRestore
withAbsolutePositioning
maxHeight={chatOrUserIds!.length * CHAT_HEIGHT_PX}
onKeyDown={handleKeyDown}
>
<div
className="scroll-container"
// @ts-ignore
style={IS_ANDROID ? `height: ${chatOrUserIds!.length * CHAT_HEIGHT_PX}px` : undefined}
teactFastList
>
{viewportIds.map((id, i) => (
<ListItem
key={id}
className="chat-item-clickable force-rounded-corners"
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
onClick={() => onSelectChatOrUser(id)}
>
{isUserId(id) ? (
<PrivateChatInfo status={id === currentUserId ? lang('SavedMessagesInfo') : undefined} userId={id} />
) : (
<GroupChatInfo chatId={id} />
)}
</ListItem>
))}
</div>
{viewportIds.map((id, i) => (
<ListItem
key={id}
className="chat-item-clickable force-rounded-corners"
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
onClick={() => onSelectChatOrUser(id)}
>
{isUserId(id) ? (
<PrivateChatInfo status={id === currentUserId ? lang('SavedMessagesInfo') : undefined} userId={id} />
) : (
<GroupChatInfo chatId={id} />
)}
</ListItem>
))}
</InfiniteScroll>
) : viewportIds && !viewportIds.length ? (
<p className="no-results">{lang('lng_blocked_list_not_found')}</p>

View File

@ -13,7 +13,7 @@ import {
CHAT_HEIGHT_PX,
CHAT_LIST_SLICE,
} from '../../../config';
import { IS_ANDROID, IS_MAC_OS, IS_PWA } from '../../../util/environment';
import { IS_MAC_OS, IS_PWA } from '../../../util/environment';
import { mapValues } from '../../../util/iteratees';
import { getPinnedChatsCount } from '../../../util/folderManager';
import usePrevious from '../../../hooks/usePrevious';
@ -138,38 +138,29 @@ const ChatList: FC<OwnProps> = ({
const viewportOffset = orderedIds!.indexOf(viewportIds![0]);
const pinnedCount = getPinnedChatsCount(virtualFolderId) || 0;
return (
<div
className="scroll-container"
return viewportIds!.map((id, i) => (
<Chat
key={id}
teactOrderKey={i}
chatId={id}
isPinned={viewportOffset + i < pinnedCount}
folderId={folderId}
animationType={getAnimationType(id)}
orderDiff={orderDiffById[id]}
// @ts-ignore
style={IS_ANDROID ? `height: ${orderedIds!.length * CHAT_HEIGHT_PX}px` : undefined}
teactFastList
>
{viewportIds!.map((id, i) => (
<Chat
key={id}
teactOrderKey={i}
chatId={id}
isPinned={viewportOffset + i < pinnedCount}
folderId={folderId}
animationType={getAnimationType(id)}
orderDiff={orderDiffById[id]}
// @ts-ignore
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
/>
))}
</div>
);
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
/>
));
}
return (
<InfiniteScroll
className="chat-list custom-scroll"
items={viewportIds}
onLoadMore={getMore}
preloadBackwards={CHAT_LIST_SLICE}
noFastList
noScrollRestore
withAbsolutePositioning
maxHeight={(orderedIds?.length || 0) * CHAT_HEIGHT_PX}
onLoadMore={getMore}
>
{viewportIds?.length ? (
renderChats()

View File

@ -7,6 +7,7 @@ import React, {
import { debounce } from '../../util/schedulers';
import resetScroll from '../../util/resetScroll';
import { IS_ANDROID } from '../../util/environment';
type OwnProps = {
ref?: RefObject<HTMLDivElement>;
@ -18,6 +19,8 @@ type OwnProps = {
itemSelector?: string;
preloadBackwards?: number;
sensitiveArea?: number;
withAbsolutePositioning?: boolean;
maxHeight?: number;
noScrollRestore?: boolean;
noScrollRestoreOnTop?: boolean;
noFastList?: boolean;
@ -39,6 +42,8 @@ const InfiniteScroll: FC<OwnProps> = ({
itemSelector = DEFAULT_LIST_SELECTOR,
preloadBackwards = DEFAULT_PRELOAD_BACKWARDS,
sensitiveArea = DEFAULT_SENSITIVE_AREA,
withAbsolutePositioning,
maxHeight,
// Used to turn off restoring scroll position (e.g. for frequently re-ordered chat or user lists)
noScrollRestore = false,
noScrollRestoreOnTop = false,
@ -114,7 +119,7 @@ const InfiniteScroll: FC<OwnProps> = ({
}
}
if (noScrollRestore) {
if (withAbsolutePositioning || noScrollRestore) {
return;
}
@ -125,7 +130,7 @@ const InfiniteScroll: FC<OwnProps> = ({
resetScroll(container, newScrollTop);
state.isScrollTopJustUpdated = true;
}, [items, itemSelector, noScrollRestore, noScrollRestoreOnTop, cacheBuster]);
}, [items, itemSelector, noScrollRestore, noScrollRestoreOnTop, cacheBuster, withAbsolutePositioning]);
const handleScroll = useCallback((e: UIEvent<HTMLDivElement>) => {
if (loadMoreForwards && loadMoreBackwards) {
@ -214,10 +219,18 @@ const InfiniteScroll: FC<OwnProps> = ({
ref={containerRef}
className={className}
onScroll={handleScroll}
teactFastList={!noFastList}
teactFastList={!noFastList && !withAbsolutePositioning}
onKeyDown={onKeyDown}
>
{children}
{withAbsolutePositioning && items?.length ? (
<div
teactFastList={!noFastList}
// @ts-ignore
style={`position: relative;${IS_ANDROID ? ` height: ${maxHeight}px;` : undefined}`}
>
{children}
</div>
) : children}
</div>
);
};