diff --git a/src/RoomInvite.js b/src/RoomInvite.js index ed3fe1452e..b82cc0a8e7 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -67,15 +67,7 @@ export function showCommunityRoomInviteDialog(roomId, communityName) { } export function showCommunityInviteDialog(communityId) { - const rooms = GroupStore.getGroupRooms(communityId) - .map(r => MatrixClientPeg.get().getRoom(r.roomId)) - .filter(r => !!r); - let chat = rooms.find(r => { - const idState = r.currentState.getStateEvents("im.vector.general_chat", ""); - if (!idState || idState.getContent()['groupId'] !== communityId) return false; - return true; - }); - if (!chat) chat = rooms[0]; + const chat = CommunityPrototypeStore.instance.getGeneralChat(communityId); if (chat) { const name = CommunityPrototypeStore.instance.getCommunityName(communityId); showCommunityRoomInviteDialog(chat.roomId, name); diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index 8e62402141..a583af2603 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -46,6 +46,9 @@ import { CommunityPrototypeStore } from "../../stores/CommunityPrototypeStore"; import * as fbEmitter from "fbemitter"; import TagOrderStore from "../../stores/TagOrderStore"; import { showCommunityInviteDialog } from "../../RoomInvite"; +import dis from "../../dispatcher/dispatcher"; +import { RightPanelPhases } from "../../stores/RightPanelStorePhases"; +import ErrorDialog from "../views/dialogs/ErrorDialog"; interface IProps { isMinimized: boolean; @@ -211,7 +214,25 @@ export default class UserMenu extends React.Component { ev.preventDefault(); ev.stopPropagation(); - console.log("TODO@onCommunityMembersClick"); + // We'd ideally just pop open a right panel with the member list, but the current + // way the right panel is structured makes this exceedingly difficult. Instead, we'll + // switch to the general room and open the member list there as it should be in sync + // anyways. + const chat = CommunityPrototypeStore.instance.getGeneralChat(TagOrderStore.getSelectedPrototypeTag()); + if (chat) { + dis.dispatch({ + action: 'view_room', + room_id: chat.roomId, + }, true); + dis.dispatch({action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomMemberList}); + } else { + // "This should never happen" clauses go here for the prototype. + Modal.createTrackedDialog('Failed to find general chat', '', ErrorDialog, { + title: _t('Failed to find the general chat for this community'), + description: _t("Failed to find the general chat for this community"), + }); + } + this.setState({contextMenuPosition: null}); // also close the menu }; private onCommunityInviteClick = (ev: ButtonEvent) => { diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index e2d7e3f8e0..06ce8ddda8 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -27,6 +27,8 @@ import rate_limited_func from "../../../ratelimitedfunc"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import * as sdk from "../../../index"; import CallHandler from "../../../CallHandler"; +import TagOrderStore from "../../../stores/TagOrderStore"; +import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore"; const INITIAL_LOAD_NUM_MEMBERS = 30; const INITIAL_LOAD_NUM_INVITED = 5; @@ -464,10 +466,19 @@ export default createReactClass({ } } + let inviteButtonText = _t("Invite to this room"); + const communityId = TagOrderStore.getSelectedPrototypeTag(); + if (communityId) { + const chat = CommunityPrototypeStore.instance.getGeneralChat(communityId); + if (chat && chat.roomId === this.props.roomId) { + inviteButtonText = _t("Invite to this community"); + } + } + const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); inviteButton = - { _t('Invite to this room') } + { inviteButtonText } ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c798c8eff1..d8e159244f 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2121,6 +2121,7 @@ "Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others", "Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s", "Uploading %(filename)s and %(count)s others|one": "Uploading %(filename)s and %(count)s other", + "Failed to find the general chat for this community": "Failed to find the general chat for this community", "Notification settings": "Notification settings", "Security & privacy": "Security & privacy", "All settings": "All settings", diff --git a/src/stores/CommunityPrototypeStore.ts b/src/stores/CommunityPrototypeStore.ts index eec0a8aab8..1dfcbb766a 100644 --- a/src/stores/CommunityPrototypeStore.ts +++ b/src/stores/CommunityPrototypeStore.ts @@ -24,6 +24,8 @@ import * as utils from "matrix-js-sdk/src/utils"; import { UPDATE_EVENT } from "./AsyncStore"; import FlairStore from "./FlairStore"; import TagOrderStore from "./TagOrderStore"; +import { MatrixClientPeg } from "../MatrixClientPeg"; +import GroupStore from "./GroupStore"; interface IState { // nothing of value - we use account data @@ -54,6 +56,19 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient { return profile?.name || communityId; } + public getGeneralChat(communityId: string): Room { + const rooms = GroupStore.getGroupRooms(communityId) + .map(r => MatrixClientPeg.get().getRoom(r.roomId)) + .filter(r => !!r); + let chat = rooms.find(r => { + const idState = r.currentState.getStateEvents("im.vector.general_chat", ""); + if (!idState || idState.getContent()['groupId'] !== communityId) return false; + return true; + }); + if (!chat) chat = rooms[0]; + return chat; // can be null + } + protected async onAction(payload: ActionPayload): Promise { if (!this.matrixClient || !SettingsStore.getValue("feature_communities_v2_prototypes")) { return; diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 2eb35e6dc2..6651d207a1 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -168,6 +168,7 @@ class TagOrderStore extends Store { if (!allowMultiple && newTags.length === 1) { // We're in prototype behaviour: select the general chat for the community + // XXX: This is duplicated with the CommunityPrototypeStore as a cyclical reference const rooms = GroupStore.getGroupRooms(newTags[0]) .map(r => MatrixClientPeg.get().getRoom(r.roomId)) .filter(r => !!r);