diff --git a/cypress/integration/12-spotlight/spotlight.spec.ts b/cypress/integration/12-spotlight/spotlight.spec.ts index 3862dc638f..5c0018b499 100644 --- a/cypress/integration/12-spotlight/spotlight.spec.ts +++ b/cypress/integration/12-spotlight/spotlight.spec.ts @@ -125,7 +125,6 @@ describe("Spotlight", () => { let room2Id: string; beforeEach(() => { - cy.enableLabsFeature("feature_spotlight"); cy.startSynapse("default").then(data => { synapse = data; cy.initTestUser(synapse, "Jim").then(() => diff --git a/res/css/structures/_RoomSearch.scss b/res/css/structures/_RoomSearch.scss index b3679ca05b..4437480bc8 100644 --- a/res/css/structures/_RoomSearch.scss +++ b/res/css/structures/_RoomSearch.scss @@ -38,64 +38,11 @@ limitations under the License. margin-bottom: 2px; } - .mx_RoomSearch_input { - border: none !important; // !important to override default app-wide styles - flex: 1 !important; // !important to override default app-wide styles - color: $primary-content !important; // !important to override default app-wide styles - padding: 0; - height: 100%; - width: 100%; - - &:not(.mx_RoomSearch_inputExpanded)::placeholder { - color: $tertiary-content !important; // !important to override default app-wide styles - } - } - - .mx_RoomSearch_input, .mx_RoomSearch_spotlightTriggerText { font-size: $font-12px; line-height: $font-16px; } - &.mx_RoomSearch_hasQuery { - border-color: $secondary-content; - } - - &.mx_RoomSearch_focused { - box-shadow: 0 0 4px 4px rgba(0, 132, 255, 0.5); - border-color: transparent; - } - - &.mx_RoomSearch_focused, &.mx_RoomSearch_hasQuery { - background-color: $background; - - .mx_RoomSearch_clearButton { - width: 16px; - height: 16px; - margin-right: 8px; - background-color: $quinary-content; - border-radius: 50%; - position: relative; - - &::before { - content: ""; - position: absolute; - width: inherit; - height: inherit; - mask-image: url('$(res)/img/feather-customised/x.svg'); - mask-position: center; - mask-size: 12px; - mask-repeat: no-repeat; - background-color: $secondary-content; - } - } - } - - .mx_RoomSearch_clearButton { - width: 0; - height: 0; - } - &.mx_RoomSearch_minimized { height: 32px; min-height: 32px; diff --git a/res/css/views/dialogs/_SpotlightDialog.scss b/res/css/views/dialogs/_SpotlightDialog.scss index a803d3473b..ebd5324be1 100644 --- a/res/css/views/dialogs/_SpotlightDialog.scss +++ b/res/css/views/dialogs/_SpotlightDialog.scss @@ -465,12 +465,6 @@ limitations under the License. display: flex; border-top: 1px solid $quinary-content; - .mx_BetaCard_betaPill { - margin-right: 12px; - height: min-content; - align-self: center; - } - > span { align-self: center; diff --git a/res/img/betas/new_search_experience.gif b/res/img/betas/new_search_experience.gif deleted file mode 100644 index 6dc1e001f3..0000000000 Binary files a/res/img/betas/new_search_experience.gif and /dev/null differ diff --git a/src/accessibility/KeyboardShortcuts.ts b/src/accessibility/KeyboardShortcuts.ts index 50992eb299..022706f296 100644 --- a/src/accessibility/KeyboardShortcuts.ts +++ b/src/accessibility/KeyboardShortcuts.ts @@ -18,7 +18,6 @@ limitations under the License. import { _td } from "../languageHandler"; import { IS_MAC, Key } from "../Keyboard"; import { IBaseSetting } from "../settings/Settings"; -import IncompatibleController from "../settings/controllers/IncompatibleController"; import { KeyCombo } from "../KeyBindingsManager"; export enum KeyBindingAction { @@ -485,13 +484,6 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = { }, displayName: _td("Expand room list section"), }, - [KeyBindingAction.ClearRoomFilter]: { - default: { - key: Key.ESCAPE, - }, - displayName: _td("Clear room list filter field"), - controller: new IncompatibleController("feature_spotlight", { key: null }), - }, [KeyBindingAction.NextRoom]: { default: { key: Key.ARROW_DOWN, diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx index ed1f990c3f..b7cdec1434 100644 --- a/src/components/structures/LeftPanel.tsx +++ b/src/components/structures/LeftPanel.tsx @@ -31,7 +31,7 @@ import SpaceStore from "../../stores/spaces/SpaceStore"; import { MetaSpace, SpaceKey, UPDATE_SELECTED_SPACE } from "../../stores/spaces"; import { getKeyBindingsManager } from "../../KeyBindingsManager"; import UIStore from "../../stores/UIStore"; -import { findSiblingElement, IState as IRovingTabIndexState } from "../../accessibility/RovingTabIndex"; +import { IState as IRovingTabIndexState } from "../../accessibility/RovingTabIndex"; import RoomListHeader from "../views/rooms/RoomListHeader"; import RecentlyViewedButton from "../views/rooms/RecentlyViewedButton"; import { BreadcrumbsStore } from "../../stores/BreadcrumbsStore"; @@ -64,7 +64,6 @@ interface IState { export default class LeftPanel extends React.Component { private listContainerRef = createRef(); - private roomSearchRef = createRef(); private roomListRef = createRef(); private focusedElement = null; private isDoingStickyHeaders = false; @@ -302,32 +301,6 @@ export default class LeftPanel extends React.Component { this.roomListRef.current?.focus(); } break; - - case KeyBindingAction.PrevRoom: - if (state && state.activeRef === findSiblingElement(state.refs, 0)) { - ev.stopPropagation(); - ev.preventDefault(); - this.roomSearchRef.current?.focus(); - } - break; - } - }; - - private onRoomListKeydown = (ev: React.KeyboardEvent) => { - if (ev.altKey || ev.ctrlKey || ev.metaKey) return; - if (SettingsStore.getValue("feature_spotlight")) return; - - const action = getKeyBindingsManager().getAccessibilityAction(ev); - - // we cannot handle Space as that is an activation key for all focusable elements in this widget - if (ev.key.length === 1) { - ev.preventDefault(); - ev.stopPropagation(); - this.roomSearchRef.current?.appendChar(ev.key); - } else if (action === KeyBindingAction.Backspace) { - ev.preventDefault(); - ev.stopPropagation(); - this.roomSearchRef.current?.backspace(); } }; @@ -386,7 +359,6 @@ export default class LeftPanel extends React.Component { > @@ -436,7 +408,6 @@ export default class LeftPanel extends React.Component { // Firefox sometimes makes this element focusable due to // overflow:scroll;, so force it out of tab order. tabIndex={-1} - onKeyDown={this.onRoomListKeydown} > { roomList } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 072234b1ed..8e973d60db 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -93,7 +93,6 @@ import SecurityCustomisations from "../../customisations/Security"; import Spinner from "../views/elements/Spinner"; import QuestionDialog from "../views/dialogs/QuestionDialog"; import UserSettingsDialog from '../views/dialogs/UserSettingsDialog'; -import { UserTab } from "../views/dialogs/UserTab"; import CreateRoomDialog from '../views/dialogs/CreateRoomDialog'; import RoomDirectory from './RoomDirectory'; import KeySignatureUploadFailedDialog from "../views/dialogs/KeySignatureUploadFailedDialog"; @@ -118,7 +117,6 @@ import { showSpaceInvite } from "../../utils/space"; import AccessibleButton from "../views/elements/AccessibleButton"; import { ActionPayload } from "../../dispatcher/payloads"; import { SummarizedNotificationState } from "../../stores/notifications/SummarizedNotificationState"; -import GenericToast from '../views/toasts/GenericToast'; import Views from '../../Views'; import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; import { ViewHomePagePayload } from '../../dispatcher/payloads/ViewHomePagePayload'; @@ -738,9 +736,6 @@ export default class MatrixChat extends React.PureComponent { this.state.resizeNotifier.notifyLeftHandleResized(); }); break; - case 'focus_room_filter': // for CtrlOrCmd+K to work by expanding the left panel first - if (SettingsStore.getValue("feature_spotlight")) break; // don't expand if spotlight enabled - // fallthrough case 'show_left_panel': this.setState({ collapseLhs: false, @@ -1398,42 +1393,6 @@ export default class MatrixChat extends React.PureComponent { showNotificationsToast(false); } - if (!localStorage.getItem("mx_seen_feature_spotlight_toast")) { - setTimeout(() => { - // Skip the toast if the beta is already enabled or the user has changed the setting from default - if (SettingsStore.getValue("feature_spotlight") || - SettingsStore.getValue("feature_spotlight", null, true) !== null) { - return; - } - - const key = "BETA_SPOTLIGHT_TOAST"; - ToastStore.sharedInstance().addOrReplaceToast({ - key, - title: _t("New search beta available"), - props: { - description: _t("We're testing a new search to make finding what you want quicker.\n"), - acceptLabel: _t("Learn more"), - onAccept: () => { - dis.dispatch({ - action: Action.ViewUserSettings, - initialTabId: UserTab.Labs, - }); - localStorage.setItem("mx_seen_feature_spotlight_toast", "true"); - ToastStore.sharedInstance().dismissToast(key); - }, - rejectLabel: _t("Dismiss"), - onReject: () => { - localStorage.setItem("mx_seen_feature_spotlight_toast", "true"); - ToastStore.sharedInstance().dismissToast(key); - }, - }, - icon: "labs", - component: GenericToast, - priority: 9, - }); - }, 5 * 60 * 1000); // show after 5 minutes to not overload user with toasts on launch - } - dis.fire(Action.FocusSendMessageComposer); this.setState({ ready: true, diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 8e7286a205..9af39a5cc3 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -14,26 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as React from "react"; -import { createRef, RefObject } from "react"; import classNames from "classnames"; +import * as React from "react"; +import { ALTERNATE_KEY_NAME } from "../../accessibility/KeyboardShortcuts"; import defaultDispatcher from "../../dispatcher/dispatcher"; -import { _t } from "../../languageHandler"; import { ActionPayload } from "../../dispatcher/payloads"; -import AccessibleButton from "../views/elements/AccessibleButton"; -import { Action } from "../../dispatcher/actions"; -import RoomListStore from "../../stores/room-list/RoomListStore"; -import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition"; -import { getKeyBindingsManager } from "../../KeyBindingsManager"; -import SpaceStore from "../../stores/spaces/SpaceStore"; -import { UPDATE_SELECTED_SPACE } from "../../stores/spaces"; import { IS_MAC, Key } from "../../Keyboard"; -import SettingsStore from "../../settings/SettingsStore"; +import { _t } from "../../languageHandler"; import Modal from "../../Modal"; import SpotlightDialog from "../views/dialogs/spotlight/SpotlightDialog"; -import { ALTERNATE_KEY_NAME, KeyBindingAction } from "../../accessibility/KeyboardShortcuts"; -import ToastStore from "../../stores/ToastStore"; +import AccessibleButton from "../views/elements/AccessibleButton"; interface IProps { isMinimized: boolean; @@ -43,220 +34,49 @@ interface IProps { onSelectRoom(): boolean; } -interface IState { - query: string; - focused: boolean; - spotlightBetaEnabled: boolean; -} - -export default class RoomSearch extends React.PureComponent { +export default class RoomSearch extends React.PureComponent { private readonly dispatcherRef: string; - private readonly betaRef: string; - private elementRef: React.RefObject = createRef(); - private searchFilter: NameFilterCondition = new NameFilterCondition(); constructor(props: IProps) { super(props); - this.state = { - query: "", - focused: false, - spotlightBetaEnabled: SettingsStore.getValue("feature_spotlight"), - }; - this.dispatcherRef = defaultDispatcher.register(this.onAction); - // clear filter when changing spaces, in future we may wish to maintain a filter per-space - SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.clearInput); - this.betaRef = SettingsStore.watchSetting("feature_spotlight", null, this.onSpotlightChange); - } - - public componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { - if (prevState.query !== this.state.query) { - const hadSearch = !!this.searchFilter.search.trim(); - const haveSearch = !!this.state.query.trim(); - this.searchFilter.search = this.state.query; - if (!hadSearch && haveSearch) { - // started a new filter - add the condition - RoomListStore.instance.addFilter(this.searchFilter); - } else if (hadSearch && !haveSearch) { - // cleared a filter - remove the condition - RoomListStore.instance.removeFilter(this.searchFilter); - } // else the filter hasn't changed enough for us to care here - } } public componentWillUnmount() { defaultDispatcher.unregister(this.dispatcherRef); - SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.clearInput); - SettingsStore.unwatchSetting(this.betaRef); } - private onSpotlightChange = () => { - const spotlightBetaEnabled = SettingsStore.getValue("feature_spotlight"); - if (this.state.spotlightBetaEnabled !== spotlightBetaEnabled) { - this.setState({ - spotlightBetaEnabled, - query: "", - }); - } - // in case the user was in settings at the 5-minute mark, dismiss the toast - ToastStore.sharedInstance().dismissToast("BETA_SPOTLIGHT_TOAST"); - }; - private openSpotlight() { Modal.createDialog(SpotlightDialog, {}, "mx_SpotlightDialog_wrapper", false, true); } private onAction = (payload: ActionPayload) => { - if (payload.action === Action.ViewRoom && payload.clear_search) { - this.clearInput(); - } else if (payload.action === 'focus_room_filter') { - if (this.state.spotlightBetaEnabled) { - this.openSpotlight(); - } else { - this.focus(); - } - } - }; - - private clearInput = () => { - if (this.elementRef.current?.tagName !== "INPUT") return; - (this.elementRef.current as HTMLInputElement).value = ""; - this.onChange(); - }; - - private openSearch = () => { - if (this.state.spotlightBetaEnabled) { + if (payload.action === 'focus_room_filter') { this.openSpotlight(); - } else { - // dispatched as it needs handling by MatrixChat too - defaultDispatcher.dispatch({ action: "focus_room_filter" }); } }; - private onChange = () => { - if (this.elementRef.current?.tagName !== "INPUT") return; - this.setState({ query: (this.elementRef.current as HTMLInputElement).value }); - }; - - private onFocus = (ev: React.FocusEvent) => { - this.setState({ focused: true }); - ev.target.select(); - }; - - private onBlur = (ev: React.FocusEvent) => { - this.setState({ focused: false }); - }; - - private onKeyDown = (ev: React.KeyboardEvent) => { - const action = getKeyBindingsManager().getRoomListAction(ev); - switch (action) { - case KeyBindingAction.ClearRoomFilter: - this.clearInput(); - defaultDispatcher.fire(Action.FocusSendMessageComposer); - break; - case KeyBindingAction.SelectRoomInRoomList: { - const shouldClear = this.props.onSelectRoom(); - if (shouldClear) { - // wrap in set immediate to delay it so that we don't clear the filter & then change room - setImmediate(() => { - this.clearInput(); - }); - } - break; - } - } - }; - - public focus = (): void => { - this.elementRef.current?.focus(); - }; - public render(): React.ReactNode { const classes = classNames({ 'mx_RoomSearch': true, - 'mx_RoomSearch_hasQuery': this.state.query, - 'mx_RoomSearch_focused': this.state.focused, 'mx_RoomSearch_minimized': this.props.isMinimized, - 'mx_RoomSearch_spotlightTrigger': this.state.spotlightBetaEnabled, - }); - - const inputClasses = classNames({ - 'mx_RoomSearch_input': true, - 'mx_RoomSearch_inputExpanded': this.state.query || this.state.focused, - }); + }, 'mx_RoomSearch_spotlightTrigger'); const icon = (
); - let input = ( - } - className={inputClasses} - value={this.state.query} - onFocus={this.onFocus} - onBlur={this.onBlur} - onChange={this.onChange} - onKeyDown={this.onKeyDown} - placeholder={_t("Filter")} - autoComplete="off" - /> - ); - - let shortcutPrompt =
+ const shortcutPrompt =
{ IS_MAC ? "⌘ K" : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " K" }
; - if (this.props.isMinimized) { - input = null; - shortcutPrompt = null; - } - - if (this.state.spotlightBetaEnabled) { - return - { icon } - { input &&
- { _t("Search") } -
} - { shortcutPrompt } -
; - } else if (this.props.isMinimized) { - return - { icon } - ; - } - - return ( -
- { icon } - { input } - { shortcutPrompt } - -
- ); - } - - public appendChar(char: string): void { - this.setState({ - query: this.state.query + char, - }); - } - - public backspace(): void { - this.setState({ - query: this.state.query.substring(0, this.state.query.length - 1), - }); + return + { icon } + { (!this.props.isMinimized) &&
+ { _t("Search") } +
} + { shortcutPrompt } +
; } } diff --git a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx index 40188b9387..f55575833c 100644 --- a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx +++ b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx @@ -76,15 +76,13 @@ import { copyPlaintext } from "../../../../utils/strings"; import BaseAvatar from "../../avatars/BaseAvatar"; import DecoratedRoomAvatar from "../../avatars/DecoratedRoomAvatar"; import { SearchResultAvatar } from "../../avatars/SearchResultAvatar"; -import { BetaPill } from "../../beta/BetaCard"; import { NetworkDropdown } from "../../directory/NetworkDropdown"; import AccessibleButton from "../../elements/AccessibleButton"; import Spinner from "../../elements/Spinner"; import NotificationBadge from "../../rooms/NotificationBadge"; import BaseDialog from "../BaseDialog"; -import BetaFeedbackDialog from "../BetaFeedbackDialog"; +import FeedbackDialog from "../FeedbackDialog"; import { IDialogProps } from "../IDialogProps"; -import { UserTab } from "../UserTab"; import { Option } from "./Option"; import { PublicRoomResultDetails } from "./PublicRoomResultDetails"; import { RoomResultDetails } from "./RoomResultDetails"; @@ -988,9 +986,7 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n }; const openFeedback = SdkConfig.get().bug_report_endpoint_url ? () => { - Modal.createDialog(BetaFeedbackDialog, { - featureId: "feature_spotlight", - }); + Modal.createDialog(FeedbackDialog); } : null; const activeDescendant = rovingContext.state.activeRef?.current?.id; @@ -1062,13 +1058,6 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n
- { - defaultDispatcher.dispatch({ - action: Action.ViewUserSettings, - initialTabId: UserTab.Labs, - }); - onFinished(); - }} /> { openFeedback && _t("Results not as expected? Please give feedback.", {}, { a: sub => { sub } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6a7e3f77f3..8e40a870cb 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -881,13 +881,6 @@ "Show HTML representation of room topics": "Show HTML representation of room topics", "Show info about bridges in room settings": "Show info about bridges in room settings", "Use new room breadcrumbs": "Use new room breadcrumbs", - "New search experience": "New search experience", - "The new search": "The new search", - "A new, quick way to search spaces and rooms you're in.": "A new, quick way to search spaces and rooms you're in.", - "This feature is a work in progress, we'd love to hear your feedback.": "This feature is a work in progress, we'd love to hear your feedback.", - "How can I give feedback?": "How can I give feedback?", - "To feedback, join the beta, start a search and click on feedback.": "To feedback, join the beta, start a search and click on feedback.", - "To leave, just return to this page or click on the beta badge when you search.": "To leave, just return to this page or click on the beta badge when you search.", "Right panel stays open (defaults to room member list)": "Right panel stays open (defaults to room member list)", "Jump to date (adds /jumptodate and jump to date headers)": "Jump to date (adds /jumptodate and jump to date headers)", "Don't send read receipts": "Don't send read receipts", @@ -3062,8 +3055,6 @@ "Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s", "Unable to copy room link": "Unable to copy room link", "Unable to copy a link to the room to the clipboard.": "Unable to copy a link to the room to the clipboard.", - "New search beta available": "New search beta available", - "We're testing a new search to make finding what you want quicker.\n": "We're testing a new search to make finding what you want quicker.\n", "Signed Out": "Signed Out", "For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.", "Terms and Conditions": "Terms and Conditions", @@ -3091,9 +3082,6 @@ "Find a room…": "Find a room…", "Find a room… (e.g. %(exampleRoom)s)": "Find a room… (e.g. %(exampleRoom)s)", "If you can't find the room you're looking for, ask for an invite or create a new room.": "If you can't find the room you're looking for, ask for an invite or create a new room.", - "Filter": "Filter", - "Filter rooms and people": "Filter rooms and people", - "Clear filter": "Clear filter", "You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.", "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.", "Your message wasn't sent because this homeserver has been blocked by its administrator. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has been blocked by its administrator. Please contact your service administrator to continue using the service.", @@ -3402,7 +3390,6 @@ "Select room from the room list": "Select room from the room list", "Collapse room list section": "Collapse room list section", "Expand room list section": "Expand room list section", - "Clear room list filter field": "Clear room list filter field", "Navigate down in the room list": "Navigate down in the room list", "Navigate up in the room list": "Navigate up in the room list", "Toggle the top left menu": "Toggle the top left menu", diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 000b832cb0..596398cab0 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -383,32 +383,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: _td("Use new room breadcrumbs"), default: false, }, - "feature_spotlight": { - isFeature: true, - labsGroup: LabGroup.Rooms, - supportedLevels: LEVELS_FEATURE, - displayName: _td("New search experience"), - default: false, - betaInfo: { - title: _td("The new search"), - caption: () => <> -

{ _t("A new, quick way to search spaces and rooms you're in.") }

-

{ _t("This feature is a work in progress, we'd love to hear your feedback.") }

- , - faq: () => <> - { SdkConfig.get().bug_report_endpoint_url && <> -

{ _t("How can I give feedback?") }

-

{ _t("To feedback, join the beta, start a search and click on feedback.") }

- } -

{ _t("How can I leave the beta?") }

-

{ _t("To leave, just return to this page or click on the beta badge when you search.") }

- , - feedbackLabel: "spotlight-feedback", - feedbackSubheading: _td("Thank you for trying the beta, " + - "please go into as much detail as you can so we can improve it."), - image: require("../../res/img/betas/new_search_experience.gif"), - }, - }, "feature_right_panel_default_open": { isFeature: true, labsGroup: LabGroup.Rooms,