diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 1e3adcb518..a4338e832a 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -60,7 +60,7 @@ import ScrollPanel from "./ScrollPanel"; import TimelinePanel from "./TimelinePanel"; import ErrorBoundary from "../views/elements/ErrorBoundary"; import RoomPreviewBar from "../views/rooms/RoomPreviewBar"; -import SearchBar from "../views/rooms/SearchBar"; +import SearchBar, { SearchScope } from "../views/rooms/SearchBar"; import RoomUpgradeWarningBar from "../views/rooms/RoomUpgradeWarningBar"; import AuxPanel from "../views/rooms/AuxPanel"; import RoomHeader from "../views/rooms/RoomHeader"; @@ -139,7 +139,7 @@ export interface IState { draggingFile: boolean; searching: boolean; searchTerm?: string; - searchScope?: "All" | "Room"; + searchScope?: SearchScope; searchResults?: XOR<{}, { count: number; highlights: string[]; @@ -1267,7 +1267,7 @@ export default class RoomView extends React.Component { }); } - private onSearch = (term: string, scope) => { + private onSearch = (term: string, scope: SearchScope) => { this.setState({ searchTerm: term, searchScope: scope, @@ -1288,7 +1288,7 @@ export default class RoomView extends React.Component { this.searchId = new Date().getTime(); let roomId; - if (scope === "Room") roomId = this.state.room.roomId; + if (scope === SearchScope.Room) roomId = this.state.room.roomId; debuglog("sending search request"); const searchPromise = eventSearch(term, roomId); diff --git a/src/components/views/elements/DesktopBuildsNotice.tsx b/src/components/views/elements/DesktopBuildsNotice.tsx index fd1c7848aa..426554f31e 100644 --- a/src/components/views/elements/DesktopBuildsNotice.tsx +++ b/src/components/views/elements/DesktopBuildsNotice.tsx @@ -14,10 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ +import React from "react"; import EventIndexPeg from "../../../indexing/EventIndexPeg"; import { _t } from "../../../languageHandler"; import SdkConfig from "../../../SdkConfig"; -import React from "react"; +import dis from "../../../dispatcher/dispatcher"; +import { Action } from "../../../dispatcher/actions"; +import { UserTab } from "../dialogs/UserSettingsDialog"; + export enum WarningKind { Files, @@ -33,6 +37,22 @@ export default function DesktopBuildsNotice({isRoomEncrypted, kind}: IProps) { if (!isRoomEncrypted) return null; if (EventIndexPeg.get()) return null; + if (EventIndexPeg.error) { + return <> + {_t("Message search initialisation failed, check your settings for more information", {}, { + a: sub => ( { + evt.preventDefault(); + dis.dispatch({ + action: Action.ViewUserSettings, + initialTabId: UserTab.Security, + }); + }}> + {sub} + ), + })} + ; + } + const {desktopBuilds, brand} = SdkConfig.get(); let text = null; diff --git a/src/components/views/rooms/SearchBar.js b/src/components/views/rooms/SearchBar.js deleted file mode 100644 index 029516c932..0000000000 --- a/src/components/views/rooms/SearchBar.js +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 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 React, {createRef} from 'react'; -import AccessibleButton from "../elements/AccessibleButton"; -import classNames from "classnames"; -import { _t } from '../../../languageHandler'; -import {Key} from "../../../Keyboard"; -import DesktopBuildsNotice, {WarningKind} from "../elements/DesktopBuildsNotice"; -import {replaceableComponent} from "../../../utils/replaceableComponent"; - -@replaceableComponent("views.rooms.SearchBar") -export default class SearchBar extends React.Component { - constructor(props) { - super(props); - - this._search_term = createRef(); - - this.state = { - scope: 'Room', - }; - } - - onThisRoomClick = () => { - this.setState({ scope: 'Room' }, () => this._searchIfQuery()); - }; - - onAllRoomsClick = () => { - this.setState({ scope: 'All' }, () => this._searchIfQuery()); - }; - - onSearchChange = (e) => { - switch (e.key) { - case Key.ENTER: - this.onSearch(); - break; - case Key.ESCAPE: - this.props.onCancelClick(); - break; - } - }; - - _searchIfQuery() { - if (this._search_term.current.value) { - this.onSearch(); - } - } - - onSearch = () => { - this.props.onSearch(this._search_term.current.value, this.state.scope); - }; - - render() { - const searchButtonClasses = classNames("mx_SearchBar_searchButton", { - mx_SearchBar_searching: this.props.searchInProgress, - }); - const thisRoomClasses = classNames("mx_SearchBar_button", { - mx_SearchBar_unselected: this.state.scope !== 'Room', - }); - const allRoomsClasses = classNames("mx_SearchBar_button", { - mx_SearchBar_unselected: this.state.scope !== 'All', - }); - - return ( - <> -
-
- - {_t("This Room")} - - - {_t("All Rooms")} - -
-
- - -
- -
- - - ); - } -} diff --git a/src/components/views/rooms/SearchBar.tsx b/src/components/views/rooms/SearchBar.tsx new file mode 100644 index 0000000000..d71bb8da73 --- /dev/null +++ b/src/components/views/rooms/SearchBar.tsx @@ -0,0 +1,130 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 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 React, { createRef, RefObject } from 'react'; +import AccessibleButton from "../elements/AccessibleButton"; +import classNames from "classnames"; +import { _t } from '../../../languageHandler'; +import { Key } from "../../../Keyboard"; +import DesktopBuildsNotice, { WarningKind } from "../elements/DesktopBuildsNotice"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; + +interface IProps { + onCancelClick: () => void; + onSearch: (query: string, scope: string) => void; + searchInProgress?: boolean; + isRoomEncrypted?: boolean; +} + +interface IState { + scope: SearchScope; +} + +export enum SearchScope { + Room = "Room", + All = "All", +} + +@replaceableComponent("views.rooms.SearchBar") +export default class SearchBar extends React.Component { + private searchTerm: RefObject = createRef(); + + constructor(props: IProps) { + super(props); + this.state = { + scope: SearchScope.Room, + }; + } + + private onThisRoomClick = () => { + this.setState({ scope: SearchScope.Room }, () => this.searchIfQuery()); + }; + + private onAllRoomsClick = () => { + this.setState({ scope: SearchScope.All }, () => this.searchIfQuery()); + }; + + private onSearchChange = (e: React.KeyboardEvent) => { + switch (e.key) { + case Key.ENTER: + this.onSearch(); + break; + case Key.ESCAPE: + this.props.onCancelClick(); + break; + } + }; + + private searchIfQuery(): void { + if (this.searchTerm.current.value) { + this.onSearch(); + } + } + + private onSearch = (): void => { + this.props.onSearch(this.searchTerm.current.value, this.state.scope); + }; + + public render() { + const searchButtonClasses = classNames("mx_SearchBar_searchButton", { + mx_SearchBar_searching: this.props.searchInProgress, + }); + const thisRoomClasses = classNames("mx_SearchBar_button", { + mx_SearchBar_unselected: this.state.scope !== SearchScope.Room, + }); + const allRoomsClasses = classNames("mx_SearchBar_button", { + mx_SearchBar_unselected: this.state.scope !== SearchScope.All, + }); + + return ( + <> +
+
+ + {_t("This Room")} + + + {_t("All Rooms")} + +
+
+ + +
+ +
+ + + ); + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3f05559851..0c2bf1ca57 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1933,6 +1933,7 @@ "Error loading Widget": "Error loading Widget", "Error - Mixed content": "Error - Mixed content", "Popout widget": "Popout widget", + "Message search initialisation failed, check your settings for more information": "Message search initialisation failed, check your settings for more information", "Use the Desktop app to see all encrypted files": "Use the Desktop app to see all encrypted files", "Use the Desktop app to search encrypted messages": "Use the Desktop app to search encrypted messages", "This version of %(brand)s does not support viewing some encrypted files": "This version of %(brand)s does not support viewing some encrypted files",