mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-05 12:16:53 +02:00
Move to virtua
This commit is contained in:
parent
ce68db5c20
commit
9e65d4254d
@ -157,6 +157,7 @@
|
||||
"temporal-polyfill": "^0.3.0",
|
||||
"ua-parser-js": "^1.0.2",
|
||||
"uuid": "^11.0.0",
|
||||
"virtua": "^0.41.0",
|
||||
"what-input": "^5.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -7,7 +7,8 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { Form } from "@vector-im/compound-web";
|
||||
import React, { useCallback, useRef, type JSX } from "react";
|
||||
import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
||||
import { Virtualizer, VirtualizerHandle } from "virtua";
|
||||
// import { Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
||||
|
||||
import { Flex } from "../../../utils/Flex";
|
||||
import {
|
||||
@ -29,9 +30,9 @@ interface IProps {
|
||||
const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
const vm = useMemberListViewModel(props.roomId);
|
||||
const totalRows = vm.members.length;
|
||||
const ref = useRef<VirtuosoHandle | null>(null);
|
||||
const ref = useRef<VirtualizerHandle | null>(null);
|
||||
const scrollRef = useRef<HTMLDivElement | null>(null);
|
||||
const [focusedIndex, setFocusedIndex] = React.useState(-1);
|
||||
const listRef = useRef<HTMLButtonElement | null>(null);
|
||||
|
||||
const getRowComponent = (item: MemberWithSeparator, focused: boolean): JSX.Element => {
|
||||
if (item === SEPARATOR) {
|
||||
@ -39,19 +40,16 @@ const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
} else if (item.member) {
|
||||
return <RoomMemberTileView member={item.member} showPresence={vm.isPresenceEnabled} focused={focused} />;
|
||||
} else {
|
||||
return <ThreePidInviteTileView threePidInvite={item.threePidInvite} />;
|
||||
return <ThreePidInviteTileView threePidInvite={item.threePidInvite} focused={focused} />;
|
||||
}
|
||||
};
|
||||
|
||||
const scrollToIndex = useCallback(
|
||||
(index: number): void => {
|
||||
ref?.current?.scrollIntoView({
|
||||
index: index,
|
||||
behavior: "auto",
|
||||
done: () => {
|
||||
setFocusedIndex(index);
|
||||
},
|
||||
ref?.current?.scrollToIndex(index, {
|
||||
align: "nearest",
|
||||
});
|
||||
setFocusedIndex(index);
|
||||
},
|
||||
[ref],
|
||||
);
|
||||
@ -81,18 +79,6 @@ const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
[scrollToIndex, focusedIndex, setFocusedIndex, vm, totalRows],
|
||||
);
|
||||
|
||||
const scrollerRef = useCallback(
|
||||
(element: any) => {
|
||||
if (element) {
|
||||
element.addEventListener("keydown", keyDownCallback);
|
||||
listRef.current = element;
|
||||
} else {
|
||||
listRef?.current?.removeEventListener("keydown", keyDownCallback);
|
||||
}
|
||||
},
|
||||
[keyDownCallback],
|
||||
);
|
||||
|
||||
const onFocus = (e: React.FocusEvent): void => {
|
||||
const nextIndex = focusedIndex == -1 ? 0 : focusedIndex;
|
||||
scrollToIndex(nextIndex);
|
||||
@ -116,20 +102,24 @@ const MemberListView: React.FC<IProps> = (props: IProps) => {
|
||||
<Form.Root>
|
||||
<MemberListHeaderView vm={vm} />
|
||||
</Form.Root>
|
||||
<Virtuoso
|
||||
<div
|
||||
style={{
|
||||
overflowY: "auto",
|
||||
// opt out browser's scroll anchoring on header/footer because it will conflict to scroll anchoring of virtualizer
|
||||
overflowAnchor: "none",
|
||||
}}
|
||||
aria-label={_t("room_list|list_title")}
|
||||
role="grid"
|
||||
ref={ref}
|
||||
style={{ height: "100%" }}
|
||||
scrollerRef={scrollerRef}
|
||||
context={{ focusedIndex }}
|
||||
// Don't focus on the table as a whole go straight to the first item in the list
|
||||
tabIndex={undefined}
|
||||
data={vm.members}
|
||||
ref={scrollRef}
|
||||
onFocus={onFocus}
|
||||
itemContent={(index, member) => getRowComponent(member, index === focusedIndex)}
|
||||
components={{ Footer: () => footer() }}
|
||||
/>
|
||||
onKeyDown={keyDownCallback}
|
||||
tabIndex={0}
|
||||
>
|
||||
<Virtualizer ref={ref} scrollRef={scrollRef}>
|
||||
{vm.members.map((member, index) => getRowComponent(member, index === focusedIndex))}
|
||||
</Virtualizer>
|
||||
{footer()}
|
||||
</div>
|
||||
</Flex>
|
||||
</BaseCard>
|
||||
);
|
||||
|
||||
@ -3729,7 +3729,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@vector-im/matrix-wysiwyg/-/matrix-wysiwyg-2.38.3.tgz#cc54d8b3e9472bcd8e622126ba364ee31952cd8a"
|
||||
integrity sha512-fqo8P55Vc/t0vxpFar9RDJN5gKEjJmzrLo+O4piDbFda6VrRoqrWAtiu0Au0g6B4hRDPKIuFupk8v9Ja7q8Hvg==
|
||||
dependencies:
|
||||
"@vector-im/matrix-wysiwyg-wasm" "link:../../../.cache/yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.3-cc54d8b3e9472bcd8e622126ba364ee31952cd8a-integrity/node_modules/bindings/wysiwyg-wasm"
|
||||
"@vector-im/matrix-wysiwyg-wasm" "link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.3-cc54d8b3e9472bcd8e622126ba364ee31952cd8a-integrity/node_modules/bindings/wysiwyg-wasm"
|
||||
|
||||
"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1":
|
||||
version "1.14.1"
|
||||
@ -13020,6 +13020,11 @@ vaul@^1.0.0:
|
||||
dependencies:
|
||||
"@radix-ui/react-dialog" "^1.1.1"
|
||||
|
||||
virtua@^0.41.0:
|
||||
version "0.41.0"
|
||||
resolved "https://registry.yarnpkg.com/virtua/-/virtua-0.41.0.tgz#1e3c847baceb14c57e14be36272903f80a95f006"
|
||||
integrity sha512-P8XJhPAz3mNrxAjPc+NRvD8a8+JtInKgHXuvtucThXW93U1ztUKJ2TDCAMaCPRY0CQCR465mYcOf26yQkCHWEw==
|
||||
|
||||
vt-pbf@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user