From 4d7b7c4cc8027a6991295e063f10f7c1bdc9ee1f Mon Sep 17 00:00:00 2001 From: Travis Ralston <travisr@matrix.org> Date: Fri, 6 May 2022 12:29:17 -0600 Subject: [PATCH 1/3] Remove feature_dnd Rationale: it's a poor implementation and will conflict with proper feature development. --- src/Notifier.ts | 4 -- src/components/structures/UserMenu.tsx | 54 -------------------------- src/i18n/strings/en_EN.json | 2 - src/settings/Settings.tsx | 12 ------ 4 files changed, 72 deletions(-) diff --git a/src/Notifier.ts b/src/Notifier.ts index 62e2f09370..892d5bc19c 100644 --- a/src/Notifier.ts +++ b/src/Notifier.ts @@ -408,10 +408,6 @@ export const Notifier = { // don't bother notifying as user was recently active in this room return; } - if (SettingsStore.getValue("doNotDisturb")) { - // Don't bother the user if they didn't ask to be bothered - return; - } if (this.isEnabled()) { this._displayPopupNotification(ev, room); diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index 78f1e29d00..b389632499 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -44,7 +44,6 @@ import { UPDATE_EVENT } from "../../stores/AsyncStore"; import BaseAvatar from '../views/avatars/BaseAvatar'; import { SettingLevel } from "../../settings/SettingLevel"; import IconizedContextMenu, { - IconizedContextMenuCheckbox, IconizedContextMenuOption, IconizedContextMenuOptionList, } from "../views/context_menus/IconizedContextMenu"; @@ -53,7 +52,6 @@ import HostSignupAction from "./HostSignupAction"; import SpaceStore from "../../stores/spaces/SpaceStore"; import { UPDATE_SELECTED_SPACE } from "../../stores/spaces"; import MatrixClientContext from "../../contexts/MatrixClientContext"; -import { SettingUpdatedPayload } from "../../dispatcher/payloads/SettingUpdatedPayload"; import UserIdentifierCustomisations from "../../customisations/UserIdentifier"; import PosthogTrackers from "../../PosthogTrackers"; import { ViewHomePagePayload } from "../../dispatcher/payloads/ViewHomePagePayload"; @@ -122,7 +120,6 @@ interface IState { isDarkTheme: boolean; isHighContrast: boolean; selectedSpace?: Room; - dndEnabled: boolean; } const toRightOf = (rect: PartialDOMRect) => { @@ -154,19 +151,11 @@ export default class UserMenu extends React.Component<IProps, IState> { contextMenuPosition: null, isDarkTheme: this.isUserOnDarkTheme(), isHighContrast: this.isUserOnHighContrastTheme(), - dndEnabled: this.doNotDisturb, selectedSpace: SpaceStore.instance.activeSpaceRoom, }; OwnProfileStore.instance.on(UPDATE_EVENT, this.onProfileUpdate); SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.onSelectedSpaceUpdate); - - SettingsStore.monitorSetting("feature_dnd", null); - SettingsStore.monitorSetting("doNotDisturb", null); - } - - private get doNotDisturb(): boolean { - return SettingsStore.getValue("doNotDisturb"); } private get hasHomePage(): boolean { @@ -239,20 +228,6 @@ export default class UserMenu extends React.Component<IProps, IState> { if (this.buttonRef.current) this.buttonRef.current.click(); } break; - - case Action.SettingUpdated: { - const settingUpdatedPayload = payload as SettingUpdatedPayload; - switch (settingUpdatedPayload.settingName) { - case "feature_dnd": - case "doNotDisturb": { - const dndEnabled = this.doNotDisturb; - if (this.state.dndEnabled !== dndEnabled) { - this.setState({ dndEnabled }); - } - break; - } - } - } } }; @@ -348,12 +323,6 @@ export default class UserMenu extends React.Component<IProps, IState> { this.setState({ contextMenuPosition: null }); // also close the menu }; - private onDndToggle = (ev: ButtonEvent) => { - ev.stopPropagation(); - const current = SettingsStore.getValue("doNotDisturb"); - SettingsStore.setValue("doNotDisturb", null, SettingLevel.DEVICE, !current); - }; - private renderContextMenu = (): React.ReactNode => { if (!this.state.contextMenuPosition) return null; @@ -405,19 +374,6 @@ export default class UserMenu extends React.Component<IProps, IState> { customStatusSection = <CustomStatusSection />; } - let dndButton: JSX.Element; - if (SettingsStore.getValue("feature_dnd")) { - dndButton = ( - <IconizedContextMenuCheckbox - iconClassName={this.state.dndEnabled ? "mx_UserMenu_iconDnd" : "mx_UserMenu_iconDndOff"} - label={_t("Do not disturb")} - onClick={this.onDndToggle} - active={this.state.dndEnabled} - words - /> - ); - } - let feedbackButton; if (SettingsStore.getValue(UIFeature.Feedback)) { feedbackButton = <IconizedContextMenuOption @@ -430,7 +386,6 @@ export default class UserMenu extends React.Component<IProps, IState> { let primaryOptionList = ( <IconizedContextMenuOptionList> { homeButton } - { dndButton } <IconizedContextMenuOption iconClassName="mx_UserMenu_iconBell" label={_t("Notifications")} @@ -515,11 +470,6 @@ export default class UserMenu extends React.Component<IProps, IState> { const displayName = OwnProfileStore.instance.displayName || userId; const avatarUrl = OwnProfileStore.instance.getHttpAvatarUrl(avatarSize); - let badge: JSX.Element; - if (this.state.dndEnabled) { - badge = <div className="mx_UserMenu_dndBadge" />; - } - let name: JSX.Element; if (!this.props.isPanelCollapsed) { name = <div className="mx_UserMenu_name"> @@ -534,9 +484,6 @@ export default class UserMenu extends React.Component<IProps, IState> { label={_t("User menu")} isExpanded={!!this.state.contextMenuPosition} onContextMenu={this.onContextMenu} - className={classNames({ - mx_UserMenu_cutout: badge, - })} > <div className="mx_UserMenu_userAvatar"> <BaseAvatar @@ -548,7 +495,6 @@ export default class UserMenu extends React.Component<IProps, IState> { resizeMethod="crop" className="mx_UserMenu_userAvatar_BaseAvatar" /> - { badge } </div> { name } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a37af4d26c..6262cd86e2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -869,7 +869,6 @@ "Developer": "Developer", "Let moderators hide messages pending moderation.": "Let moderators hide messages pending moderation.", "Report to moderators prototype. In rooms that support moderation, the `report` button will let you report abuse to room moderators": "Report to moderators prototype. In rooms that support moderation, the `report` button will let you report abuse to room moderators", - "Show options to enable 'Do not disturb' mode": "Show options to enable 'Do not disturb' mode", "Render LaTeX maths in messages": "Render LaTeX maths in messages", "Message Pinning": "Message Pinning", "Threaded messaging": "Threaded messaging", @@ -3177,7 +3176,6 @@ "Set a new status": "Set a new status", "Got an account? <a>Sign in</a>": "Got an account? <a>Sign in</a>", "New here? <a>Create an account</a>": "New here? <a>Create an account</a>", - "Do not disturb": "Do not disturb", "Switch to light mode": "Switch to light mode", "Switch to dark mode": "Switch to dark mode", "Switch theme": "Switch theme", diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index ae30d58d4b..b7fce4aef1 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -201,13 +201,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { supportedLevels: LEVELS_FEATURE, default: false, }, - "feature_dnd": { - isFeature: true, - labsGroup: LabGroup.Profile, - displayName: _td("Show options to enable 'Do not disturb' mode"), - supportedLevels: LEVELS_FEATURE, - default: false, - }, "feature_latex_maths": { isFeature: true, labsGroup: LabGroup.Messaging, @@ -344,11 +337,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: _td("Show current avatar and name for users in message history"), default: false, }, - "doNotDisturb": { - supportedLevels: [SettingLevel.DEVICE], - default: false, - controller: new IncompatibleController("feature_dnd", false, false), - }, "mjolnirRooms": { supportedLevels: [SettingLevel.ACCOUNT], default: [], From aa664b88a473c0af184c91a7878df0eef552a364 Mon Sep 17 00:00:00 2001 From: Travis Ralston <travisr@matrix.org> Date: Fri, 6 May 2022 12:39:03 -0600 Subject: [PATCH 2/3] Remove feature_custom_status Rationale: It's legacy and wrong in so many ways. --- src/components/structures/UserMenu.tsx | 65 +------------------ src/components/views/right_panel/UserInfo.tsx | 8 --- src/components/views/rooms/MemberTile.tsx | 37 ----------- src/hooks/useUserStatusMessage.ts | 39 ----------- src/i18n/strings/en_EN.json | 5 -- src/settings/Settings.tsx | 9 --- .../controllers/CustomStatusController.ts | 29 --------- .../algorithms/tag-sorting/RecentAlgorithm.ts | 3 - 8 files changed, 1 insertion(+), 194 deletions(-) delete mode 100644 src/hooks/useUserStatusMessage.ts delete mode 100644 src/settings/controllers/CustomStatusController.ts diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index b389632499..a9f072b21f 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -14,9 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { createRef, useContext, useRef, useState } from "react"; +import React, { createRef } from "react"; import { Room } from "matrix-js-sdk/src/models/room"; -import classNames from "classnames"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import defaultDispatcher from "../../dispatcher/dispatcher"; @@ -32,9 +31,7 @@ import LogoutDialog from "../views/dialogs/LogoutDialog"; import SettingsStore from "../../settings/SettingsStore"; import { findHighContrastTheme, getCustomTheme, isHighContrastTheme } from "../../theme"; import { - RovingAccessibleButton, RovingAccessibleTooltipButton, - useRovingTabIndex, } from "../../accessibility/RovingTabIndex"; import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton"; import SdkConfig from "../../SdkConfig"; @@ -51,64 +48,10 @@ import { UIFeature } from "../../settings/UIFeature"; import HostSignupAction from "./HostSignupAction"; import SpaceStore from "../../stores/spaces/SpaceStore"; import { UPDATE_SELECTED_SPACE } from "../../stores/spaces"; -import MatrixClientContext from "../../contexts/MatrixClientContext"; import UserIdentifierCustomisations from "../../customisations/UserIdentifier"; import PosthogTrackers from "../../PosthogTrackers"; import { ViewHomePagePayload } from "../../dispatcher/payloads/ViewHomePagePayload"; -const CustomStatusSection = () => { - const cli = useContext(MatrixClientContext); - const setStatus = cli.getUser(cli.getUserId()).unstable_statusMessage || ""; - const [value, setValue] = useState(setStatus); - - const ref = useRef<HTMLInputElement>(null); - const [onFocus, isActive] = useRovingTabIndex(ref); - - const classes = classNames({ - 'mx_UserMenu_CustomStatusSection_field': true, - 'mx_UserMenu_CustomStatusSection_field_hasQuery': value, - }); - - let details: JSX.Element; - if (value !== setStatus) { - details = <> - <p>{ _t("Your status will be shown to people you have a DM with.") }</p> - - <RovingAccessibleButton - onClick={() => cli._unstable_setStatusMessage(value)} - kind="primary_outline" - > - { value ? _t("Set status") : _t("Clear status") } - </RovingAccessibleButton> - </>; - } - - return <form className="mx_UserMenu_CustomStatusSection"> - <div className={classes}> - <input - type="text" - value={value} - className="mx_UserMenu_CustomStatusSection_input" - onChange={e => setValue(e.target.value)} - placeholder={_t("Set a new status")} - autoComplete="off" - onFocus={onFocus} - ref={ref} - tabIndex={isActive ? 0 : -1} - /> - <AccessibleButton - // The clear button is only for mouse users - tabIndex={-1} - title={_t("Clear")} - className="mx_UserMenu_CustomStatusSection_clear" - onClick={() => setValue("")} - /> - </div> - - { details } - </form>; -}; - interface IProps { isPanelCollapsed: boolean; } @@ -369,11 +312,6 @@ export default class UserMenu extends React.Component<IProps, IState> { ); } - let customStatusSection: JSX.Element; - if (SettingsStore.getValue("feature_custom_status")) { - customStatusSection = <CustomStatusSection />; - } - let feedbackButton; if (SettingsStore.getValue(UIFeature.Feedback)) { feedbackButton = <IconizedContextMenuOption @@ -457,7 +395,6 @@ export default class UserMenu extends React.Component<IProps, IState> { /> </RovingAccessibleTooltipButton> </div> - { customStatusSection } { topSection } { primaryOptionList } </IconizedContextMenu>; diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index 9d17c5237d..7b45746c77 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -75,7 +75,6 @@ import { UIComponent } from "../../../settings/UIFeature"; import { TimelineRenderingType } from "../../../contexts/RoomContext"; import RightPanelStore from '../../../stores/right-panel/RightPanelStore'; import { IRightPanelCardState } from '../../../stores/right-panel/RightPanelStoreIPanelState'; -import { useUserStatusMessage } from "../../../hooks/useUserStatusMessage"; import UserIdentifierCustomisations from '../../../customisations/UserIdentifier'; import PosthogTrackers from "../../../PosthogTrackers"; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; @@ -1411,7 +1410,6 @@ const UserInfoHeader: React.FC<{ roomId?: string; }> = ({ member, e2eStatus, roomId }) => { const cli = useContext(MatrixClientContext); - const statusMessage = useUserStatusMessage(member); const onMemberAvatarClick = useCallback(() => { const avatarUrl = (member as RoomMember).getMxcAvatarUrl @@ -1472,11 +1470,6 @@ const UserInfoHeader: React.FC<{ ); } - let statusLabel = null; - if (statusMessage) { - statusLabel = <span className="mx_UserInfo_statusMessage">{ statusMessage }</span>; - } - let e2eIcon; if (e2eStatus) { e2eIcon = <E2EIcon size={18} status={e2eStatus} isUser={true} />; @@ -1499,7 +1492,6 @@ const UserInfoHeader: React.FC<{ <div>{ UserIdentifierCustomisations.getDisplayUserIdentifier(member.userId, { roomId, withDisplayName: true }) }</div> <div className="mx_UserInfo_profileStatus"> { presenceLabel } - { statusLabel } </div> </div> </div> diff --git a/src/components/views/rooms/MemberTile.tsx b/src/components/views/rooms/MemberTile.tsx index b652771a43..f292ec3b58 100644 --- a/src/components/views/rooms/MemberTile.tsx +++ b/src/components/views/rooms/MemberTile.tsx @@ -20,12 +20,10 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { EventType } from "matrix-js-sdk/src/@types/event"; import { DeviceInfo } from "matrix-js-sdk/src/crypto/deviceinfo"; -import { UserEvent } from "matrix-js-sdk/src/models/user"; import { CryptoEvent } from "matrix-js-sdk/src/crypto"; import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state"; import { UserTrustLevel } from 'matrix-js-sdk/src/crypto/CrossSigning'; -import SettingsStore from "../../../settings/SettingsStore"; import dis from "../../../dispatcher/dispatcher"; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from "../../../MatrixClientPeg"; @@ -41,7 +39,6 @@ interface IProps { } interface IState { - statusMessage: string; isRoomEncrypted: boolean; e2eStatus: string; } @@ -58,7 +55,6 @@ export default class MemberTile extends React.Component<IProps, IState> { super(props); this.state = { - statusMessage: this.getStatusMessage(), isRoomEncrypted: false, e2eStatus: null, }; @@ -67,13 +63,6 @@ export default class MemberTile extends React.Component<IProps, IState> { componentDidMount() { const cli = MatrixClientPeg.get(); - if (SettingsStore.getValue("feature_custom_status")) { - const { user } = this.props.member; - if (user) { - user.on(UserEvent._UnstableStatusMessage, this.onStatusMessageCommitted); - } - } - const { roomId } = this.props.member; if (roomId) { const isRoomEncrypted = cli.isRoomEncrypted(roomId); @@ -94,11 +83,6 @@ export default class MemberTile extends React.Component<IProps, IState> { componentWillUnmount() { const cli = MatrixClientPeg.get(); - const { user } = this.props.member; - if (user) { - user.removeListener(UserEvent._UnstableStatusMessage, this.onStatusMessageCommitted); - } - if (cli) { cli.removeListener(RoomStateEvent.Events, this.onRoomStateEvents); cli.removeListener(CryptoEvent.UserTrustStatusChanged, this.onUserTrustStatusChanged); @@ -158,21 +142,6 @@ export default class MemberTile extends React.Component<IProps, IState> { }); } - private getStatusMessage(): string { - const { user } = this.props.member; - if (!user) { - return ""; - } - return user.unstable_statusMessage; - } - - private onStatusMessageCommitted = (): void => { - // The `User` object has observed a status message change. - this.setState({ - statusMessage: this.getStatusMessage(), - }); - }; - shouldComponentUpdate(nextProps: IProps, nextState: IState): boolean { if ( this.memberLastModifiedTime === undefined || @@ -222,11 +191,6 @@ export default class MemberTile extends React.Component<IProps, IState> { const name = this.getDisplayName(); const presenceState = member.user ? member.user.presence : null; - let statusMessage = null; - if (member.user && SettingsStore.getValue("feature_custom_status")) { - statusMessage = this.state.statusMessage; - } - const av = ( <MemberAvatar member={member} width={36} height={36} aria-hidden="true" /> ); @@ -277,7 +241,6 @@ export default class MemberTile extends React.Component<IProps, IState> { nameJSX={nameJSX} powerStatus={powerStatus} showPresence={this.props.showPresence} - subtextLabel={statusMessage} e2eStatus={e2eStatus} onClick={this.onClick} /> diff --git a/src/hooks/useUserStatusMessage.ts b/src/hooks/useUserStatusMessage.ts deleted file mode 100644 index 74b6c1dbf2..0000000000 --- a/src/hooks/useUserStatusMessage.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { MatrixClient } from "matrix-js-sdk/src/client"; -import { User, UserEvent } from "matrix-js-sdk/src/models/user"; -import { useContext } from "react"; - -import MatrixClientContext from "../contexts/MatrixClientContext"; -import { useTypedEventEmitterState } from "./useEventEmitter"; -import { Member } from "../components/views/right_panel/UserInfo"; -import { useFeatureEnabled } from "./useSettings"; - -const getUser = (cli: MatrixClient, user: Member): User => cli.getUser(user?.userId); -const getStatusMessage = (cli: MatrixClient, user: Member): string => { - return getUser(cli, user)?.unstable_statusMessage; -}; - -// Hook to simplify handling Matrix User status -export const useUserStatusMessage = (member?: Member): string => { - const cli = useContext(MatrixClientContext); - const enabled = useFeatureEnabled("feature_custom_status"); - const user = enabled ? getUser(cli, member) : undefined; - return useTypedEventEmitterState(user, UserEvent._UnstableStatusMessage, () => { - return getStatusMessage(cli, user); - }); -}; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6262cd86e2..99fee9afc9 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -881,7 +881,6 @@ "To leave, return to this page and use the “%(leaveTheBeta)s” button.": "To leave, return to this page and use the “%(leaveTheBeta)s” button.", "Leave the beta": "Leave the beta", "Thank you for trying the beta, please go into as much detail as you can so we can improve it.": "Thank you for trying the beta, please go into as much detail as you can so we can improve it.", - "Custom user status messages": "Custom user status messages", "Video rooms (under active development)": "Video rooms (under active development)", "Render simple counters in room header": "Render simple counters in room header", "Multiple integration managers (requires manual setup)": "Multiple integration managers (requires manual setup)", @@ -3170,10 +3169,6 @@ "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", - "Your status will be shown to people you have a DM with.": "Your status will be shown to people you have a DM with.", - "Set status": "Set status", - "Clear status": "Clear status", - "Set a new status": "Set a new status", "Got an account? <a>Sign in</a>": "Got an account? <a>Sign in</a>", "New here? <a>Create an account</a>": "New here? <a>Create an account</a>", "Switch to light mode": "Switch to light mode", diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index b7fce4aef1..dc04194dd5 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -23,7 +23,6 @@ import { NotificationBodyEnabledController, NotificationsEnabledController, } from "./controllers/NotificationControllers"; -import CustomStatusController from "./controllers/CustomStatusController"; import ThemeController from './controllers/ThemeController'; import PushToMatrixClientController from './controllers/PushToMatrixClientController'; import ReloadOnChangeController from "./controllers/ReloadOnChangeController"; @@ -255,14 +254,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { }, }, - "feature_custom_status": { - isFeature: true, - labsGroup: LabGroup.Profile, - displayName: _td("Custom user status messages"), - supportedLevels: LEVELS_FEATURE, - default: false, - controller: new CustomStatusController(), - }, "feature_video_rooms": { isFeature: true, labsGroup: LabGroup.Rooms, diff --git a/src/settings/controllers/CustomStatusController.ts b/src/settings/controllers/CustomStatusController.ts deleted file mode 100644 index c7dfad0b3b..0000000000 --- a/src/settings/controllers/CustomStatusController.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2019, 2020 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import SettingController from "./SettingController"; -import dis from "../../dispatcher/dispatcher"; -import { SettingLevel } from "../SettingLevel"; - -export default class CustomStatusController extends SettingController { - public onChange(level: SettingLevel, roomId: string, newValue: any) { - // Dispatch setting change so that some components that are still visible when the - // Settings page is open (such as RoomTiles) can reflect the change. - dis.dispatch({ - action: "feature_custom_status_changed", - }); - } -} diff --git a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts index af937e92af..77dc8d2437 100644 --- a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts +++ b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts @@ -32,9 +32,6 @@ export function shouldCauseReorder(event: MatrixEvent): boolean { // Never ignore membership changes if (type === EventType.RoomMember && prevContent.membership !== content.membership) return true; - // Ignore status changes - // XXX: This should be an enum - if (type === "im.vector.user_status") return false; // Ignore display name changes if (type === EventType.RoomMember && prevContent.displayname !== content.displayname) return false; // Ignore avatar changes From 2aec1973543ec5ba9b274a754746ab11edd33c99 Mon Sep 17 00:00:00 2001 From: Travis Ralston <travisr@matrix.org> Date: Fri, 6 May 2022 12:46:26 -0600 Subject: [PATCH 3/3] Remove feature_many_integration_managers Rationale: If we want this feature, design will do it properly. --- res/css/_components.scss | 1 - .../_TabbedIntegrationManagerDialog.scss | 62 ------ .../TabbedIntegrationManagerDialog.tsx | 176 ------------------ .../views/right_panel/RoomSummaryCard.tsx | 7 +- src/components/views/rooms/Stickerpicker.tsx | 21 +-- src/dispatcher/actions.ts | 6 - ...enTabbedIntegrationManagerDialogPayload.ts | 29 --- src/i18n/strings/en_EN.json | 1 - src/integrations/IntegrationManagers.ts | 24 --- src/settings/Settings.tsx | 7 - src/stores/widgets/StopGapWidget.ts | 20 +- src/utils/DialogOpener.ts | 12 -- src/utils/WidgetUtils.ts | 8 +- 13 files changed, 16 insertions(+), 358 deletions(-) delete mode 100644 res/css/views/dialogs/_TabbedIntegrationManagerDialog.scss delete mode 100644 src/components/views/dialogs/TabbedIntegrationManagerDialog.tsx delete mode 100644 src/dispatcher/payloads/OpenTabbedIntegrationManagerDialogPayload.ts diff --git a/res/css/_components.scss b/res/css/_components.scss index 0d04789f31..6988c01789 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -126,7 +126,6 @@ @import "./views/dialogs/_SpacePreferencesDialog.scss"; @import "./views/dialogs/_SpaceSettingsDialog.scss"; @import "./views/dialogs/_SpotlightDialog.scss"; -@import "./views/dialogs/_TabbedIntegrationManagerDialog.scss"; @import "./views/dialogs/_TermsDialog.scss"; @import "./views/dialogs/_UntrustedDeviceDialog.scss"; @import "./views/dialogs/_UploadConfirmDialog.scss"; diff --git a/res/css/views/dialogs/_TabbedIntegrationManagerDialog.scss b/res/css/views/dialogs/_TabbedIntegrationManagerDialog.scss deleted file mode 100644 index 6385dd76f5..0000000000 --- a/res/css/views/dialogs/_TabbedIntegrationManagerDialog.scss +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2019 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -.mx_TabbedIntegrationManagerDialog .mx_Dialog { - width: 60%; - height: 70%; - overflow: hidden; - padding: 0; - max-width: initial; - max-height: initial; - position: relative; -} - -.mx_TabbedIntegrationManagerDialog_container { - // Full size of the dialog, whatever it is - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - - .mx_TabbedIntegrationManagerDialog_currentManager { - width: 100%; - height: 100%; - border-top: 1px solid $accent; - - iframe { - background-color: #fff; - border: 0; - width: 100%; - height: 100%; - } - } -} - -.mx_TabbedIntegrationManagerDialog_tab { - display: inline-block; - border: 1px solid $accent; - border-bottom: 0; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - padding: 10px 8px; - margin-right: 5px; -} - -.mx_TabbedIntegrationManagerDialog_currentTab { - background-color: $accent; - color: $accent-fg-color; -} diff --git a/src/components/views/dialogs/TabbedIntegrationManagerDialog.tsx b/src/components/views/dialogs/TabbedIntegrationManagerDialog.tsx deleted file mode 100644 index 5a5d6e3822..0000000000 --- a/src/components/views/dialogs/TabbedIntegrationManagerDialog.tsx +++ /dev/null @@ -1,176 +0,0 @@ -/* -Copyright 2019 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from 'react'; -import { Room } from "matrix-js-sdk/src/models/room"; -import classNames from 'classnames'; -import { logger } from "matrix-js-sdk/src/logger"; - -import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; -import { dialogTermsInteractionCallback, TermsNotSignedError } from "../../../Terms"; -import * as ScalarMessaging from "../../../ScalarMessaging"; -import { IntegrationManagerInstance } from "../../../integrations/IntegrationManagerInstance"; -import ScalarAuthClient from "../../../ScalarAuthClient"; -import AccessibleButton from "../elements/AccessibleButton"; -import IntegrationManager from "../settings/IntegrationManager"; -import { IDialogProps } from "./IDialogProps"; - -interface IProps extends IDialogProps { - /** - * Optional room where the integration manager should be open to - */ - room?: Room; - - /** - * Optional screen to open on the integration manager - */ - screen?: string; - - /** - * Optional integration ID to open in the integration manager - */ - integrationId?: string; -} - -interface IState { - managers: IntegrationManagerInstance[]; - busy: boolean; - currentIndex: number; - currentConnected: boolean; - currentLoading: boolean; - currentScalarClient: ScalarAuthClient; -} - -export default class TabbedIntegrationManagerDialog extends React.Component<IProps, IState> { - constructor(props: IProps) { - super(props); - - this.state = { - managers: IntegrationManagers.sharedInstance().getOrderedManagers(), - busy: true, - currentIndex: 0, - currentConnected: false, - currentLoading: true, - currentScalarClient: null, - }; - } - - public componentDidMount(): void { - this.openManager(0, true); - } - - private openManager = async (i: number, force = false): Promise<void> => { - if (i === this.state.currentIndex && !force) return; - - const manager = this.state.managers[i]; - const client = manager.getScalarClient(); - this.setState({ - busy: true, - currentIndex: i, - currentLoading: true, - currentConnected: false, - currentScalarClient: client, - }); - - ScalarMessaging.setOpenManagerUrl(manager.uiUrl); - - client.setTermsInteractionCallback((policyInfo, agreedUrls) => { - // To avoid visual glitching of two modals stacking briefly, we customise the - // terms dialog sizing when it will appear for the integration manager so that - // it gets the same basic size as the IM's own modal. - return dialogTermsInteractionCallback( - policyInfo, agreedUrls, 'mx_TermsDialog_forIntegrationManager', - ); - }); - - try { - await client.connect(); - if (!client.hasCredentials()) { - this.setState({ - busy: false, - currentLoading: false, - currentConnected: false, - }); - } else { - this.setState({ - busy: false, - currentLoading: false, - currentConnected: true, - }); - } - } catch (e) { - if (e instanceof TermsNotSignedError) { - return; - } - - logger.error(e); - this.setState({ - busy: false, - currentLoading: false, - currentConnected: false, - }); - } - }; - - private renderTabs(): JSX.Element[] { - return this.state.managers.map((m, i) => { - const classes = classNames({ - 'mx_TabbedIntegrationManagerDialog_tab': true, - 'mx_TabbedIntegrationManagerDialog_currentTab': this.state.currentIndex === i, - }); - return ( - <AccessibleButton - className={classes} - onClick={() => this.openManager(i)} - key={`tab_${i}`} - disabled={this.state.busy} - > - { m.name } - </AccessibleButton> - ); - }); - } - - public renderTab(): JSX.Element { - let uiUrl = null; - if (this.state.currentScalarClient) { - uiUrl = this.state.currentScalarClient.getScalarInterfaceUrlForRoom( - this.props.room, - this.props.screen, - this.props.integrationId, - ); - } - return <IntegrationManager - loading={this.state.currentLoading} - connected={this.state.currentConnected} - url={uiUrl} - onFinished={() => {/* no-op */}} - />; - } - - public render(): JSX.Element { - return ( - <div className='mx_TabbedIntegrationManagerDialog_container'> - <div className='mx_TabbedIntegrationManagerDialog_tabs'> - { this.renderTabs() } - </div> - <div className='mx_TabbedIntegrationManagerDialog_currentManager'> - { this.renderTab() } - </div> - </div> - ); - } -} diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index 018d2c6927..fd69f46ef9 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -207,11 +207,8 @@ const AppsSection: React.FC<IAppsSectionProps> = ({ room }) => { if (!managers.hasManager()) { managers.openNoManagerDialog(); } else { - if (SettingsStore.getValue("feature_many_integration_managers")) { - managers.openAll(room); - } else { - managers.getPrimaryManager().open(room); - } + // noinspection JSIgnoredPromiseFromCall + managers.getPrimaryManager().open(room); } }; diff --git a/src/components/views/rooms/Stickerpicker.tsx b/src/components/views/rooms/Stickerpicker.tsx index d6595e61fb..c4c1eba2d4 100644 --- a/src/components/views/rooms/Stickerpicker.tsx +++ b/src/components/views/rooms/Stickerpicker.tsx @@ -26,7 +26,6 @@ import AccessibleButton from '../elements/AccessibleButton'; import WidgetUtils, { IWidgetEvent } from '../../../utils/WidgetUtils'; import PersistedElement from "../elements/PersistedElement"; import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; -import SettingsStore from "../../../settings/SettingsStore"; import ContextMenu, { ChevronFace } from "../../structures/ContextMenu"; import { WidgetType } from "../../../widgets/WidgetType"; import { WidgetMessagingStore } from "../../../stores/widgets/WidgetMessagingStore"; @@ -339,20 +338,12 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> { * Launch the integration manager on the stickers integration page */ private launchManageIntegrations = (): void => { - // TODO: Open the right integration manager for the widget - if (SettingsStore.getValue("feature_many_integration_managers")) { - IntegrationManagers.sharedInstance().openAll( - this.props.room, - `type_${WidgetType.STICKERPICKER.preferred}`, - this.state.widgetId, - ); - } else { - IntegrationManagers.sharedInstance().getPrimaryManager().open( - this.props.room, - `type_${WidgetType.STICKERPICKER.preferred}`, - this.state.widgetId, - ); - } + // noinspection JSIgnoredPromiseFromCall + IntegrationManagers.sharedInstance().getPrimaryManager().open( + this.props.room, + `type_${WidgetType.STICKERPICKER.preferred}`, + this.state.widgetId, + ); }; public render(): JSX.Element { diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 3fdbccb71b..fd07b1641d 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -278,12 +278,6 @@ export enum Action { */ OpenReportEventDialog = "open_report_event_dialog", - /** - * Fired when the tabbed integration manager dialog needs to be opened. - * Payload: OpenTabbedIntegrationManagerDialogPayload - */ - OpenTabbedIntegrationManagerDialog = "open_tabbed_imanager_dialog", - /** * Fired when something within the application has determined that a logout, * or logout-like behaviour, needs to happen. Specifically meant to target diff --git a/src/dispatcher/payloads/OpenTabbedIntegrationManagerDialogPayload.ts b/src/dispatcher/payloads/OpenTabbedIntegrationManagerDialogPayload.ts deleted file mode 100644 index 891d126169..0000000000 --- a/src/dispatcher/payloads/OpenTabbedIntegrationManagerDialogPayload.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { Room } from "matrix-js-sdk/src/models/room"; -import { Optional } from "matrix-events-sdk"; - -import { ActionPayload } from "../payloads"; -import { Action } from "../actions"; - -export interface OpenTabbedIntegrationManagerDialogPayload extends ActionPayload { - action: Action.OpenTabbedIntegrationManagerDialog; - - room: Optional<Room>; - screen: Optional<string>; - integrationId: Optional<string>; -} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 99fee9afc9..d1a7e9a5d5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -883,7 +883,6 @@ "Thank you for trying the beta, please go into as much detail as you can so we can improve it.": "Thank you for trying the beta, please go into as much detail as you can so we can improve it.", "Video rooms (under active development)": "Video rooms (under active development)", "Render simple counters in room header": "Render simple counters in room header", - "Multiple integration managers (requires manual setup)": "Multiple integration managers (requires manual setup)", "Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)", "Support adding custom themes": "Support adding custom themes", "Show message previews for reactions in DMs": "Show message previews for reactions in DMs", diff --git a/src/integrations/IntegrationManagers.ts b/src/integrations/IntegrationManagers.ts index 32bb224f74..448b71d8ad 100644 --- a/src/integrations/IntegrationManagers.ts +++ b/src/integrations/IntegrationManagers.ts @@ -19,7 +19,6 @@ import { logger } from "matrix-js-sdk/src/logger"; import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/client"; import type { MatrixEvent } from "matrix-js-sdk/src/models/event"; -import type { Room } from "matrix-js-sdk/src/models/room"; import SdkConfig from '../SdkConfig'; import Modal from '../Modal'; import { IntegrationManagerInstance, Kind } from "./IntegrationManagerInstance"; @@ -27,13 +26,7 @@ import IntegrationsImpossibleDialog from "../components/views/dialogs/Integratio import IntegrationsDisabledDialog from "../components/views/dialogs/IntegrationsDisabledDialog"; import WidgetUtils from "../utils/WidgetUtils"; import { MatrixClientPeg } from "../MatrixClientPeg"; -import SettingsStore from "../settings/SettingsStore"; import { compare } from "../utils/strings"; -import defaultDispatcher from "../dispatcher/dispatcher"; -import { - OpenTabbedIntegrationManagerDialogPayload, -} from "../dispatcher/payloads/OpenTabbedIntegrationManagerDialogPayload"; -import { Action } from "../dispatcher/actions"; const KIND_PREFERENCE = [ // Ordered: first is most preferred, last is least preferred. @@ -181,23 +174,6 @@ export class IntegrationManagers { Modal.createTrackedDialog('Integrations impossible', '', IntegrationsImpossibleDialog); } - openAll(room: Room = null, screen: string = null, integrationId: string = null): void { - if (!SettingsStore.getValue("integrationProvisioning")) { - return this.showDisabledDialog(); - } - - if (this.managers.length === 0) { - return this.openNoManagerDialog(); - } - - defaultDispatcher.dispatch(<OpenTabbedIntegrationManagerDialogPayload>{ - action: Action.OpenTabbedIntegrationManagerDialog, - room, - screen, - integrationId, - }); - } - showDisabledDialog(): void { Modal.createTrackedDialog('Integrations disabled', '', IntegrationsDisabledDialog); } diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index dc04194dd5..910fb65ab6 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -270,13 +270,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { supportedLevels: LEVELS_FEATURE, default: false, }, - "feature_many_integration_managers": { - isFeature: true, - labsGroup: LabGroup.Experimental, - displayName: _td("Multiple integration managers (requires manual setup)"), - supportedLevels: LEVELS_FEATURE, - default: false, - }, "feature_mjolnir": { isFeature: true, labsGroup: LabGroup.Moderation, diff --git a/src/stores/widgets/StopGapWidget.ts b/src/stores/widgets/StopGapWidget.ts index 0d9a0bc66e..33395b7942 100644 --- a/src/stores/widgets/StopGapWidget.ts +++ b/src/stores/widgets/StopGapWidget.ts @@ -358,20 +358,12 @@ export class StopGapWidget extends EventEmitter { const integType = data?.integType; const integId = <string>data?.integId; - // TODO: Open the right integration manager for the widget - if (SettingsStore.getValue("feature_many_integration_managers")) { - IntegrationManagers.sharedInstance().openAll( - MatrixClientPeg.get().getRoom(RoomViewStore.instance.getRoomId()), - `type_${integType}`, - integId, - ); - } else { - IntegrationManagers.sharedInstance().getPrimaryManager().open( - MatrixClientPeg.get().getRoom(RoomViewStore.instance.getRoomId()), - `type_${integType}`, - integId, - ); - } + // noinspection JSIgnoredPromiseFromCall + IntegrationManagers.sharedInstance().getPrimaryManager().open( + MatrixClientPeg.get().getRoom(RoomViewStore.instance.getRoomId()), + `type_${integType}`, + integId, + ); }, ); } diff --git a/src/utils/DialogOpener.ts b/src/utils/DialogOpener.ts index dadce60ef6..8c5c9c374b 100644 --- a/src/utils/DialogOpener.ts +++ b/src/utils/DialogOpener.ts @@ -23,7 +23,6 @@ import ForwardDialog from "../components/views/dialogs/ForwardDialog"; import { MatrixClientPeg } from "../MatrixClientPeg"; import { Action } from "../dispatcher/actions"; import ReportEventDialog from "../components/views/dialogs/ReportEventDialog"; -import TabbedIntegrationManagerDialog from "../components/views/dialogs/TabbedIntegrationManagerDialog"; import SpacePreferencesDialog from "../components/views/dialogs/SpacePreferencesDialog"; import SpaceSettingsDialog from "../components/views/dialogs/SpaceSettingsDialog"; import InviteDialog from "../components/views/dialogs/InviteDialog"; @@ -73,17 +72,6 @@ export class DialogOpener { mxEvent: payload.event, }, 'mx_Dialog_reportEvent'); break; - case Action.OpenTabbedIntegrationManagerDialog: - Modal.createTrackedDialog( - 'Tabbed Integration Manager', '', TabbedIntegrationManagerDialog, - { - room: payload.room, - screen: payload.screen, - integrationId: payload.integrationId, - }, - 'mx_TabbedIntegrationManagerDialog', - ); - break; case Action.OpenSpacePreferences: Modal.createTrackedDialog("Space preferences", "", SpacePreferencesDialog, { initialTabId: payload.initalTabId, diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index 8537e03583..048b610cdd 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -560,12 +560,8 @@ export default class WidgetUtils { } static editWidget(room: Room, app: IApp): void { - // TODO: Open the right manager for the widget - if (SettingsStore.getValue("feature_many_integration_managers")) { - IntegrationManagers.sharedInstance().openAll(room, 'type_' + app.type, app.id); - } else { - IntegrationManagers.sharedInstance().getPrimaryManager().open(room, 'type_' + app.type, app.id); - } + // noinspection JSIgnoredPromiseFromCall + IntegrationManagers.sharedInstance().getPrimaryManager().open(room, 'type_' + app.type, app.id); } static isManagedByManager(app) {