[Refactoring] Infinite Scroll: Support absolute positioning
This commit is contained in:
parent
5f6040b82c
commit
27d7f92756
@ -4,7 +4,6 @@ import React, {
|
|||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { CHAT_HEIGHT_PX } from '../../config';
|
import { CHAT_HEIGHT_PX } from '../../config';
|
||||||
import { IS_ANDROID } from '../../util/environment';
|
|
||||||
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
|
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
|
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
|
||||||
@ -105,31 +104,24 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
className="picker-list custom-scroll"
|
className="picker-list custom-scroll"
|
||||||
items={viewportIds}
|
items={viewportIds}
|
||||||
onLoadMore={getMore}
|
onLoadMore={getMore}
|
||||||
noFastList
|
withAbsolutePositioning
|
||||||
noScrollRestore
|
maxHeight={chatOrUserIds!.length * CHAT_HEIGHT_PX}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
>
|
>
|
||||||
<div
|
{viewportIds.map((id, i) => (
|
||||||
className="scroll-container"
|
<ListItem
|
||||||
// @ts-ignore
|
key={id}
|
||||||
style={IS_ANDROID ? `height: ${chatOrUserIds!.length * CHAT_HEIGHT_PX}px` : undefined}
|
className="chat-item-clickable force-rounded-corners"
|
||||||
teactFastList
|
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
|
||||||
>
|
onClick={() => onSelectChatOrUser(id)}
|
||||||
{viewportIds.map((id, i) => (
|
>
|
||||||
<ListItem
|
{isUserId(id) ? (
|
||||||
key={id}
|
<PrivateChatInfo status={id === currentUserId ? lang('SavedMessagesInfo') : undefined} userId={id} />
|
||||||
className="chat-item-clickable force-rounded-corners"
|
) : (
|
||||||
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
|
<GroupChatInfo chatId={id} />
|
||||||
onClick={() => onSelectChatOrUser(id)}
|
)}
|
||||||
>
|
</ListItem>
|
||||||
{isUserId(id) ? (
|
))}
|
||||||
<PrivateChatInfo status={id === currentUserId ? lang('SavedMessagesInfo') : undefined} userId={id} />
|
|
||||||
) : (
|
|
||||||
<GroupChatInfo chatId={id} />
|
|
||||||
)}
|
|
||||||
</ListItem>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
) : viewportIds && !viewportIds.length ? (
|
) : viewportIds && !viewportIds.length ? (
|
||||||
<p className="no-results">{lang('lng_blocked_list_not_found')}</p>
|
<p className="no-results">{lang('lng_blocked_list_not_found')}</p>
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
CHAT_HEIGHT_PX,
|
CHAT_HEIGHT_PX,
|
||||||
CHAT_LIST_SLICE,
|
CHAT_LIST_SLICE,
|
||||||
} from '../../../config';
|
} 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 { mapValues } from '../../../util/iteratees';
|
||||||
import { getPinnedChatsCount } from '../../../util/folderManager';
|
import { getPinnedChatsCount } from '../../../util/folderManager';
|
||||||
import usePrevious from '../../../hooks/usePrevious';
|
import usePrevious from '../../../hooks/usePrevious';
|
||||||
@ -138,38 +138,29 @@ const ChatList: FC<OwnProps> = ({
|
|||||||
const viewportOffset = orderedIds!.indexOf(viewportIds![0]);
|
const viewportOffset = orderedIds!.indexOf(viewportIds![0]);
|
||||||
const pinnedCount = getPinnedChatsCount(virtualFolderId) || 0;
|
const pinnedCount = getPinnedChatsCount(virtualFolderId) || 0;
|
||||||
|
|
||||||
return (
|
return viewportIds!.map((id, i) => (
|
||||||
<div
|
<Chat
|
||||||
className="scroll-container"
|
key={id}
|
||||||
|
teactOrderKey={i}
|
||||||
|
chatId={id}
|
||||||
|
isPinned={viewportOffset + i < pinnedCount}
|
||||||
|
folderId={folderId}
|
||||||
|
animationType={getAnimationType(id)}
|
||||||
|
orderDiff={orderDiffById[id]}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
style={IS_ANDROID ? `height: ${orderedIds!.length * CHAT_HEIGHT_PX}px` : undefined}
|
style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}
|
||||||
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>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InfiniteScroll
|
<InfiniteScroll
|
||||||
className="chat-list custom-scroll"
|
className="chat-list custom-scroll"
|
||||||
items={viewportIds}
|
items={viewportIds}
|
||||||
onLoadMore={getMore}
|
|
||||||
preloadBackwards={CHAT_LIST_SLICE}
|
preloadBackwards={CHAT_LIST_SLICE}
|
||||||
noFastList
|
withAbsolutePositioning
|
||||||
noScrollRestore
|
maxHeight={(orderedIds?.length || 0) * CHAT_HEIGHT_PX}
|
||||||
|
onLoadMore={getMore}
|
||||||
>
|
>
|
||||||
{viewportIds?.length ? (
|
{viewportIds?.length ? (
|
||||||
renderChats()
|
renderChats()
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import React, {
|
|||||||
|
|
||||||
import { debounce } from '../../util/schedulers';
|
import { debounce } from '../../util/schedulers';
|
||||||
import resetScroll from '../../util/resetScroll';
|
import resetScroll from '../../util/resetScroll';
|
||||||
|
import { IS_ANDROID } from '../../util/environment';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
ref?: RefObject<HTMLDivElement>;
|
ref?: RefObject<HTMLDivElement>;
|
||||||
@ -18,6 +19,8 @@ type OwnProps = {
|
|||||||
itemSelector?: string;
|
itemSelector?: string;
|
||||||
preloadBackwards?: number;
|
preloadBackwards?: number;
|
||||||
sensitiveArea?: number;
|
sensitiveArea?: number;
|
||||||
|
withAbsolutePositioning?: boolean;
|
||||||
|
maxHeight?: number;
|
||||||
noScrollRestore?: boolean;
|
noScrollRestore?: boolean;
|
||||||
noScrollRestoreOnTop?: boolean;
|
noScrollRestoreOnTop?: boolean;
|
||||||
noFastList?: boolean;
|
noFastList?: boolean;
|
||||||
@ -39,6 +42,8 @@ const InfiniteScroll: FC<OwnProps> = ({
|
|||||||
itemSelector = DEFAULT_LIST_SELECTOR,
|
itemSelector = DEFAULT_LIST_SELECTOR,
|
||||||
preloadBackwards = DEFAULT_PRELOAD_BACKWARDS,
|
preloadBackwards = DEFAULT_PRELOAD_BACKWARDS,
|
||||||
sensitiveArea = DEFAULT_SENSITIVE_AREA,
|
sensitiveArea = DEFAULT_SENSITIVE_AREA,
|
||||||
|
withAbsolutePositioning,
|
||||||
|
maxHeight,
|
||||||
// Used to turn off restoring scroll position (e.g. for frequently re-ordered chat or user lists)
|
// Used to turn off restoring scroll position (e.g. for frequently re-ordered chat or user lists)
|
||||||
noScrollRestore = false,
|
noScrollRestore = false,
|
||||||
noScrollRestoreOnTop = false,
|
noScrollRestoreOnTop = false,
|
||||||
@ -114,7 +119,7 @@ const InfiniteScroll: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noScrollRestore) {
|
if (withAbsolutePositioning || noScrollRestore) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +130,7 @@ const InfiniteScroll: FC<OwnProps> = ({
|
|||||||
resetScroll(container, newScrollTop);
|
resetScroll(container, newScrollTop);
|
||||||
|
|
||||||
state.isScrollTopJustUpdated = true;
|
state.isScrollTopJustUpdated = true;
|
||||||
}, [items, itemSelector, noScrollRestore, noScrollRestoreOnTop, cacheBuster]);
|
}, [items, itemSelector, noScrollRestore, noScrollRestoreOnTop, cacheBuster, withAbsolutePositioning]);
|
||||||
|
|
||||||
const handleScroll = useCallback((e: UIEvent<HTMLDivElement>) => {
|
const handleScroll = useCallback((e: UIEvent<HTMLDivElement>) => {
|
||||||
if (loadMoreForwards && loadMoreBackwards) {
|
if (loadMoreForwards && loadMoreBackwards) {
|
||||||
@ -214,10 +219,18 @@ const InfiniteScroll: FC<OwnProps> = ({
|
|||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className={className}
|
className={className}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
teactFastList={!noFastList}
|
teactFastList={!noFastList && !withAbsolutePositioning}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
>
|
>
|
||||||
{children}
|
{withAbsolutePositioning && items?.length ? (
|
||||||
|
<div
|
||||||
|
teactFastList={!noFastList}
|
||||||
|
// @ts-ignore
|
||||||
|
style={`position: relative;${IS_ANDROID ? ` height: ${maxHeight}px;` : undefined}`}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
) : children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user