diff --git a/package.json b/package.json index b36807f7c3..9218cd28e8 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "@matrix-org/spec": "^1.7.0", "@sentry/browser": "^8.0.0", "@types/png-chunks-extract": "^1.0.2", - "@vector-im/compound-design-tokens": "^2.0.1", + "@vector-im/compound-design-tokens": "^2.1.0", "@vector-im/compound-web": "^7.5.0", "@vector-im/matrix-wysiwyg": "2.38.0", "@zxcvbn-ts/core": "^3.0.4", @@ -149,7 +149,9 @@ "temporal-polyfill": "^0.2.5", "ua-parser-js": "^1.0.2", "uuid": "^11.0.0", - "what-input": "^5.2.10" + "what-input": "^5.2.10", + "@types/react-virtualized": "^9.21.30", + "react-virtualized": "^9.22.5" }, "devDependencies": { "@action-validator/cli": "^0.6.0", @@ -301,4 +303,4 @@ "engines": { "node": ">=20.0.0" } -} +} \ No newline at end of file diff --git a/res/css/views/rooms/_MemberListView.pcss b/res/css/views/rooms/_MemberListView.pcss new file mode 100644 index 0000000000..162b8558b8 --- /dev/null +++ b/res/css/views/rooms/_MemberListView.pcss @@ -0,0 +1,17 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +.mx_MemberListView { + flex: 1; + display: flex; + flex-direction: column; + min-height: 0; + + .mx_MemberListView_container { + height: 100%; + } +} diff --git a/src/components/views/rooms/MemberList/MemberListView.tsx b/src/components/views/rooms/MemberList/MemberListView.tsx new file mode 100644 index 0000000000..549eda26dd --- /dev/null +++ b/src/components/views/rooms/MemberList/MemberListView.tsx @@ -0,0 +1,82 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import { Form } from "@vector-im/compound-web"; +import React from "react"; +import { List, ListRowProps } from "react-virtualized/dist/commonjs/List"; +import { AutoSizer } from "react-virtualized"; + +import { Flex } from "../../../utils/Flex"; +import { useMemberListViewModel } from "../../../viewmodels/memberlist/MemberListViewModel"; +import { RoomMemberTileView } from "./tiles/RoomMemberTileView"; +import { ThreePidInviteTileView } from "./tiles/ThreePidInviteTileView"; +import { MemberListHeaderView } from "./MemberListHeaderView"; +import BaseCard from "../../right_panel/BaseCard"; +import { _t } from "../../../../languageHandler"; + +interface IProps { + roomId: string; + onClose: () => void; +} + +const MemberListView: React.FC = (props: IProps) => { + const vm = useMemberListViewModel(props.roomId); + + const memberCount = vm.members.length; + + const rowRenderer = ({ key, index, style }: ListRowProps): React.JSX.Element => { + if (index === memberCount) { + // We've rendered all the members, + // now we render an empty div to add some space to the end of the list. + return
; + } + const item = vm.members[index]; + return ( +
+ {item.member ? ( + + ) : ( + + )} +
+ ); + }; + + return ( + + + + + + + {({ height, width }) => ( + (index === memberCount ? 32 : 56)} + // The +1 refers to the additional empty div that we render at the end of the list. + rowCount={memberCount + 1} + // Subtract the height of MemberlistHeaderView so that the parent div does not overflow. + height={height - 113} + width={width} + /> + )} + + + + ); +}; + +export default MemberListView; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 42cf08ae70..086dfec4dd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1579,9 +1579,14 @@ "toggle_attribution": "Toggle attribution" }, "member_list": { - "filter_placeholder": "Filter room members", + "count": { + "one": "%(count)s Member", + "other": "%(count)s Members" + }, + "filter_placeholder": "Search members...", "invite_button_no_perms_tooltip": "You do not have permission to invite users", - "invited_list_heading": "Invited", + "invited_label": "Invited", + "no_matches": "No matches", "power_label": "%(userName)s (power %(powerLevelNumber)s)" }, "member_list_back_action_label": "Room members", @@ -1734,7 +1739,6 @@ "custom_level": "Custom level", "default": "Default", "label": "Power level", - "mod": "Mod", "moderator": "Moderator", "restricted": "Restricted" }, @@ -2362,7 +2366,7 @@ "enable_element_call_no_permissions_tooltip": "You do not have sufficient permissions to change this." } }, - "room_summary_card_back_action_label": "Room information", + "room_summary_card_back_action_label": "Room info", "scalar": { "error_create": "Unable to create widget.", "error_membership": "You are not in this room.", @@ -3066,7 +3070,6 @@ "invite": "Invite people", "invite_description": "Invite with email or username", "invite_link": "Share invite link", - "invite_this_space": "Invite to this space", "joining_space": "Joining", "landing_welcome": "Welcome to ", "leave_dialog_action": "Leave space", diff --git a/yarn.lock b/yarn.lock index e72b11a5ed..7b026cc33f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1089,6 +1089,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.7.2": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.9.tgz#65884fd6dc255a775402cc1d9811082918f4bf00" + integrity sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.25.7", "@babel/template@^7.3.3": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" @@ -3166,6 +3173,14 @@ dependencies: "@types/react" "*" +"@types/react-virtualized@^9.21.30": + version "9.21.30" + resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.21.30.tgz#ba39821bcb2487512a8a2cdd9fbdb5e6fc87fedb" + integrity sha512-4l2TFLQ8BCjNDQlvH85tU6gctuZoEdgYzENQyZHpgTHU7hoLzYgPSOALMAeA58LOWua8AzC6wBivPj1lfl6JgQ== + dependencies: + "@types/prop-types" "*" + "@types/react" "*" + "@types/react@*", "@types/react@18.3.3": version "18.3.3" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" @@ -3369,10 +3384,10 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@vector-im/compound-design-tokens@^2.0.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@vector-im/compound-design-tokens/-/compound-design-tokens-2.1.1.tgz#d6175a99fe4b97688464126f255386990f3048d6" - integrity sha512-QnUi2K14D9KTXxcLQKUU3V75cforZLMwhaaJDNftT8F5mG86950hAM+qhgDNEpEU+pkTffQj0/g/5859YmqWzQ== +"@vector-im/compound-design-tokens@^2.1.0": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vector-im/compound-design-tokens/-/compound-design-tokens-2.1.3.tgz#8205ffb455a09d71a02d838f3dbb8503c4e6ec27" + integrity sha512-U4UF7MVguENf0lQnkU2a9p/3llTsLXzbzmFFOxi0h6ny2igNxZj/kROP/jXTxxV9xD4TNn3z098Bos4J/qJpBA== "@vector-im/compound-web@^7.5.0": version "7.5.0" @@ -3390,7 +3405,7 @@ ts-xor "^1.3.0" vaul "^1.0.0" -"@vector-im/matrix-wysiwyg-wasm@link:../../bindings/wysiwyg-wasm": +"@vector-im/matrix-wysiwyg-wasm@link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.0-af862ffd231dc0a6b8d6f2cb3601e68456c0ff24-integrity/node_modules/bindings/wysiwyg-wasm": version "0.0.0" uid "" @@ -3399,7 +3414,7 @@ resolved "https://registry.yarnpkg.com/@vector-im/matrix-wysiwyg/-/matrix-wysiwyg-2.38.0.tgz#af862ffd231dc0a6b8d6f2cb3601e68456c0ff24" integrity sha512-cMEVicFYVzFxuSyWON0aVGjAJMcgJZ+LxuLTEp8EGuu8cRacuh0RN5rapb11YVZygzFvE7X1cMedJ/fKd5vRLA== dependencies: - "@vector-im/matrix-wysiwyg-wasm" "link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.0-af862ffd231dc0a6b8d6f2cb3601e68456c0ff24-integrity/node_modules/bindings/wysiwyg-wasm" + "@vector-im/matrix-wysiwyg-wasm" "link:../../.cache/yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.0-af862ffd231dc0a6b8d6f2cb3601e68456c0ff24-integrity/node_modules/bindings/wysiwyg-wasm" "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" @@ -4413,6 +4428,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== +clsx@^1.0.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -5171,7 +5191,7 @@ dom-converter@^0.2.0: dependencies: utila "~0.4" -dom-helpers@^5.0.1: +dom-helpers@^5.0.1, dom-helpers@^5.1.3: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== @@ -8279,7 +8299,7 @@ matrix-web-i18n@^3.2.1: minimist "^1.2.8" walk "^2.3.15" -matrix-widget-api@^1.10.0: +matrix-widget-api@^1.10.0, matrix-widget-api@^1.8.2: version "1.10.0" resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-1.10.0.tgz#d31ea073a5871a1fb1a511ef900b0c125a37bf55" integrity sha512-rkAJ29briYV7TJnfBVLVSKtpeBrBju15JZFSDP6wj8YdbCu1bdmlplJayQ+vYaw1x4fzI49Q+Nz3E85s46sRDw== @@ -9966,6 +9986,11 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + react-redux@^7.2.0: version "7.2.9" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" @@ -10016,6 +10041,18 @@ react-transition-group@^4.4.1: loose-envify "^1.4.0" prop-types "^15.6.2" +react-virtualized@^9.22.5: + version "9.22.5" + resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.5.tgz#bfb96fed519de378b50d8c0064b92994b3b91620" + integrity sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ== + dependencies: + "@babel/runtime" "^7.7.2" + clsx "^1.0.4" + dom-helpers "^5.1.3" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-lifecycles-compat "^3.0.4" + react@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"