From 0c80db882027708350fb9d47f8d17091781c1a44 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Aug 2020 19:44:59 -0600 Subject: [PATCH 1/5] Add feature flag for prototypes --- src/i18n/strings/en_EN.json | 1 + src/settings/Settings.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 4c0557ac70..3ffc11b5b8 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -444,6 +444,7 @@ "%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s", "%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s", "Change notification settings": "Change notification settings", + "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.", "New spinner design": "New spinner design", "Message Pinning": "Message Pinning", "Custom user status messages": "Custom user status messages", diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 3d18c14e16..838df51ea3 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -109,6 +109,12 @@ export interface ISetting { } export const SETTINGS: {[setting: string]: ISetting} = { + "feature_communities_v2_prototypes": { + isFeature: true, + displayName: _td("Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution."), + supportedLevels: LEVELS_FEATURE, + default: false, + }, "feature_new_spinner": { isFeature: true, displayName: _td("New spinner design"), From beb5c2627c6ebe7da5f05765b66e7455b5f78658 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Aug 2020 19:45:22 -0600 Subject: [PATCH 2/5] Disable CTRL+Click and SHIFT+Click actions on tag panel --- src/stores/TagOrderStore.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 2acf531d86..3cd3f796cc 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -115,9 +115,11 @@ class TagOrderStore extends Store { break; } case 'select_tag': { + const allowMultiple = !SettingsStore.getValue("feature_communities_v2_prototypes") + let newTags = []; // Shift-click semantics - if (payload.shiftKey) { + if (payload.shiftKey && allowMultiple) { // Select range of tags let start = this._state.orderedTags.indexOf(this._state.anchorTag); let end = this._state.orderedTags.indexOf(payload.tag); @@ -135,7 +137,7 @@ class TagOrderStore extends Store { this._state.orderedTags.slice(start, end + 1).concat(newTags), )]; } else { - if (payload.ctrlOrCmdKey) { + if (payload.ctrlOrCmdKey && allowMultiple) { // Toggle individual tag if (this._state.selectedTags.includes(payload.tag)) { newTags = this._state.selectedTags.filter((t) => t !== payload.tag); From 81a7be29aaaafb798ad0ecfab4b84a70af65790d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Aug 2020 19:45:54 -0600 Subject: [PATCH 3/5] Show the selected community in the top left menu --- src/components/structures/UserMenu.tsx | 50 +++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index e782618872..839d4bccda 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -42,6 +42,9 @@ import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../views/context_menus/IconizedContextMenu"; +import TagOrderStore from "../../stores/TagOrderStore"; +import * as fbEmitter from "fbemitter"; +import FlairStore from "../../stores/FlairStore"; interface IProps { isMinimized: boolean; @@ -52,11 +55,16 @@ type PartialDOMRect = Pick; interface IState { contextMenuPosition: PartialDOMRect; isDarkTheme: boolean; + selectedCommunityProfile: { + displayName: string; + avatarMxc: string; + }; } export default class UserMenu extends React.Component { private dispatcherRef: string; private themeWatcherRef: string; + private tagStoreRef: fbEmitter.EventSubscription; private buttonRef: React.RefObject = createRef(); constructor(props: IProps) { @@ -65,6 +73,7 @@ export default class UserMenu extends React.Component { this.state = { contextMenuPosition: null, isDarkTheme: this.isUserOnDarkTheme(), + selectedCommunityProfile: null, }; OwnProfileStore.instance.on(UPDATE_EVENT, this.onProfileUpdate); @@ -77,6 +86,7 @@ export default class UserMenu extends React.Component { public componentDidMount() { this.dispatcherRef = defaultDispatcher.register(this.onAction); this.themeWatcherRef = SettingsStore.watchSetting("theme", null, this.onThemeChanged); + this.tagStoreRef = TagOrderStore.addListener(this.onTagStoreUpdate); } public componentWillUnmount() { @@ -93,6 +103,25 @@ export default class UserMenu extends React.Component { return theme === "dark"; } + private onTagStoreUpdate = async () => { + if (!SettingsStore.getValue("feature_communities_v2_prototypes")) { + return; + } + + const selectedId = TagOrderStore.getSelectedTags()[0]; + if (!selectedId) { + this.setState({selectedCommunityProfile: null}); + return; + } + + // For some reason the group's profile info isn't on the js-sdk Group object but + // is in the flair store, so get it from there. + const profile = await FlairStore.getGroupProfileCached(MatrixClientPeg.get(), selectedId); + const displayName = profile.name || selectedId; + const avatarMxc = profile.avatarUrl; + this.setState({selectedCommunityProfile: {displayName, avatarMxc}}); + }; + private onProfileUpdate = async () => { // the store triggered an update, so force a layout update. We don't // have any state to store here for that to magically happen. @@ -295,7 +324,20 @@ export default class UserMenu extends React.Component { public render() { const avatarSize = 32; // should match border-radius of the avatar - let name = {OwnProfileStore.instance.displayName}; + let displayName = OwnProfileStore.instance.displayName || MatrixClientPeg.get().getUserId(); + let avatarUrl = OwnProfileStore.instance.getHttpAvatarUrl(avatarSize); + + if (this.state.selectedCommunityProfile) { + displayName = this.state.selectedCommunityProfile.displayName + const mxc = this.state.selectedCommunityProfile.avatarMxc; + if (mxc) { + avatarUrl = MatrixClientPeg.get().mxcUrlToHttp(mxc, avatarSize, avatarSize); + } else { + avatarUrl = null; + } + } + + let name = {displayName}; let buttons = ( {/* masked image in CSS */} @@ -324,9 +366,9 @@ export default class UserMenu extends React.Component {
Date: Thu, 20 Aug 2020 19:54:09 -0600 Subject: [PATCH 4/5] Disable context menu for v2 communities --- src/components/views/elements/TagTile.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index c59aaeefa4..6a12c87024 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -30,6 +30,7 @@ import GroupStore from '../../../stores/GroupStore'; import TagOrderStore from '../../../stores/TagOrderStore'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import AccessibleButton from "./AccessibleButton"; +import SettingsStore from "../../../settings/SettingsStore"; // A class for a child of TagPanel (possibly wrapped in a DNDTagTile) that represents // a thing to click on for the user to filter the visible rooms in the RoomList to: @@ -112,6 +113,7 @@ export default createReactClass({ }, onMouseOver: function() { + if (SettingsStore.getValue("feature_communities_v2_prototypes")) return; this.setState({ hover: true }); }, @@ -123,6 +125,7 @@ export default createReactClass({ // Prevent the TagTile onClick event firing as well e.stopPropagation(); e.preventDefault(); + if (SettingsStore.getValue("feature_communities_v2_prototypes")) return; this.setState({ hover: false }); this.props.openMenu(); }, From ae04c5ce9d1d28f96eb0919d455a43c7f9417513 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 20 Aug 2020 19:59:44 -0600 Subject: [PATCH 5/5] Appease the linter --- src/settings/Settings.ts | 5 ++++- src/stores/TagOrderStore.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 838df51ea3..95861e11df 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -111,7 +111,10 @@ export interface ISetting { export const SETTINGS: {[setting: string]: ISetting} = { "feature_communities_v2_prototypes": { isFeature: true, - displayName: _td("Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution."), + displayName: _td( + "Communities v2 prototypes. Requires compatible homeserver. " + + "Highly experimental - use with caution.", + ), supportedLevels: LEVELS_FEATURE, default: false, }, diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js index 3cd3f796cc..2b72a963b0 100644 --- a/src/stores/TagOrderStore.js +++ b/src/stores/TagOrderStore.js @@ -115,7 +115,7 @@ class TagOrderStore extends Store { break; } case 'select_tag': { - const allowMultiple = !SettingsStore.getValue("feature_communities_v2_prototypes") + const allowMultiple = !SettingsStore.getValue("feature_communities_v2_prototypes"); let newTags = []; // Shift-click semantics