Merge pull request #2448 from matrix-org/bwindels/searchmakeover

Redesign: search makeover
This commit is contained in:
Bruno Windels 2019-01-17 12:12:26 +00:00 committed by GitHub
commit 89b576936b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 88 deletions

View file

@ -95,12 +95,10 @@ limitations under the License.
flex-direction: column; flex-direction: column;
} }
.mx_RoomView_body .mx_RoomView_messagePanel { .mx_RoomView_body {
order: 2; .mx_RoomView_messagePanel, .mx_RoomView_messagePanelSpinner, .mx_RoomView_messagePanelSearchSpinner{
} order: 2;
}
.mx_RoomView_body .mx_RoomView_messagePanelSpinner {
order: 2;
} }
.mx_RoomView_body .mx_RoomView_statusArea { .mx_RoomView_body .mx_RoomView_statusArea {
@ -116,6 +114,29 @@ limitations under the License.
overflow-y: auto; overflow-y: auto;
} }
.mx_RoomView_messagePanelSearchSpinner {
flex: 1;
background-image: url('../../img/typing-indicator-2x.gif');
background-position: center 367px;
background-size: 25px;
background-repeat: no-repeat;
position: relative;
}
.mx_RoomView_messagePanelSearchSpinner:before {
background-color: $greyed-fg-color;
mask: url('../../../img/feather-icons/search-input.svg');
mask-repeat: no-repeat;
mask-position: center;
mask-size: 50px;
content: '';
position: absolute;
top: 286px;
left: 0;
right: 0;
height: 50px;
}
.mx_RoomView_messageListWrapper { .mx_RoomView_messageListWrapper {
min-height: 100%; min-height: 100%;
@ -126,8 +147,15 @@ limitations under the License.
justify-content: flex-end; justify-content: flex-end;
} }
.mx_RoomView_searchResultsPanel .mx_RoomView_messageListWrapper { .mx_RoomView_searchResultsPanel {
justify-content: flex-start; .mx_RoomView_messageListWrapper {
justify-content: flex-start;
}
a {
text-decoration: none;
color: inherit;
}
} }
.mx_RoomView_empty { .mx_RoomView_empty {

View file

@ -98,6 +98,7 @@ limitations under the License.
font-size: 18px; font-size: 18px;
margin: 0 7px; margin: 0 7px;
border-bottom: 1px solid transparent; border-bottom: 1px solid transparent;
display: flex;
} }
.mx_RoomHeader_nametext { .mx_RoomHeader_nametext {
@ -111,7 +112,6 @@ limitations under the License.
} }
.mx_RoomHeader_searchStatus { .mx_RoomHeader_searchStatus {
display: inline-block;
font-weight: normal; font-weight: normal;
opacity: 0.6; opacity: 0.6;
} }

View file

@ -15,69 +15,52 @@ limitations under the License.
*/ */
.mx_SearchBar { .mx_SearchBar {
padding-top: 5px; height: 56px;
padding-bottom: 5px;
display: flex; display: flex;
align-items: center; align-items: center;
} border-bottom: 1px solid $primary-hairline-color;
.mx_SearchBar_input { .mx_SearchBar_input {
display: inline block; // border: 1px solid $input-border-color;
border-radius: 3px 0px 0px 3px; // font-size: 15px;
border: 1px solid $input-border-color; flex: 1 1 0;
font-size: 15px; margin-left: 22px;
padding: 9px; }
padding-left: 11px;
width: auto;
flex: 1 1 0;
}
.mx_SearchBar_searchButton { .mx_SearchBar_searchButton {
cursor: pointer; cursor: pointer;
margin-right: 10px; width: 37px;
width: 37px; height: 37px;
height: 37px; background-color: $accent-color;
border-radius: 0px 3px 3px 0px; mask: url('../../../img/feather-icons/search-input.svg');
background-color: $accent-color; mask-repeat: no-repeat;
} mask-position: center;
}
@keyframes pulsate { .mx_SearchBar_button {
0% { opacity: 1.0; } border: 0;
50% { opacity: 0.1; } margin: 0 0 0 22px;
100% { opacity: 1.0; } padding: 5px;
} font-size: 15px;
cursor: pointer;
color: $primary-fg-color;
border-bottom: 2px solid $accent-color;
font-weight: 600;
}
.mx_SearchBar_searching img { .mx_SearchBar_unselected {
animation: pulsate 0.5s ease-out; color: $input-darker-fg-color;
animation-iteration-count: infinite; border-color: transparent;
} }
.mx_SearchBar_button { .mx_SearchBar_cancel {
display: inline; background-color: $warning-color;
border: 0px; mask: url('../../../img/cancel.svg');
border-radius: 36px; mask-repeat: no-repeat;
font-weight: 400; mask-position: center;
font-size: 15px; mask-size: 14px;
color: $accent-fg-color; padding: 9px;
background-color: $accent-color; margin: 0 12px 0 3px;
width: auto; cursor: pointer;
margin: auto; }
margin-left: 7px;
padding-top: 6px;
padding-bottom: 4px;
padding-left: 24px;
padding-right: 24px;
cursor: pointer;
}
.mx_SearchBar_unselected {
background-color: $primary-bg-color;
color: $accent-color;
border: $accent-color 1px solid;
}
.mx_SearchBar_cancel {
padding-left: 14px;
padding-right: 14px;
cursor: pointer;
} }

View file

@ -1136,11 +1136,6 @@ module.exports = React.createClass({
// XXX: todo: merge overlapping results somehow? // XXX: todo: merge overlapping results somehow?
// XXX: why doesn't searching on name work? // XXX: why doesn't searching on name work?
if (this.state.searchResults.results === undefined) {
// awaiting results
return [];
}
const ret = []; const ret = [];
if (this.state.searchInProgress) { if (this.state.searchInProgress) {
@ -1197,7 +1192,7 @@ module.exports = React.createClass({
const roomName = room ? room.name : _t("Unknown room %(roomId)s", { roomId: roomId }); const roomName = room ? room.name : _t("Unknown room %(roomId)s", { roomId: roomId });
ret.push(<li key={mxEv.getId() + "-room"}> ret.push(<li key={mxEv.getId() + "-room"}>
<h1>{ _t("Room") }: { roomName }</h1> <h2>{ _t("Room") }: { roomName }</h2>
</li>); </li>);
lastRoomId = roomId; lastRoomId = roomId;
} }
@ -1817,16 +1812,21 @@ module.exports = React.createClass({
let hideMessagePanel = false; let hideMessagePanel = false;
if (this.state.searchResults) { if (this.state.searchResults) {
searchResultsPanel = ( // show searching spinner
<ScrollPanel ref="searchResultsPanel" if (this.state.searchResults.results === undefined) {
className="mx_RoomView_messagePanel mx_RoomView_searchResultsPanel" searchResultsPanel = (<div className="mx_RoomView_messagePanel mx_RoomView_messagePanelSearchSpinner" />);
onFillRequest={this.onSearchResultsFillRequest} } else {
onResize={this.onSearchResultsResize} searchResultsPanel = (
> <ScrollPanel ref="searchResultsPanel"
<li className={scrollheader_classes}></li> className="mx_RoomView_messagePanel mx_RoomView_searchResultsPanel"
{ this.getSearchResultTiles() } onFillRequest={this.onSearchResultsFillRequest}
</ScrollPanel> onResize={this.onSearchResultsResize}
); >
<li className={scrollheader_classes}></li>
{ this.getSearchResultTiles() }
</ScrollPanel>
);
}
hideMessagePanel = true; hideMessagePanel = true;
} }

View file

@ -33,11 +33,11 @@ module.exports = React.createClass({
}, },
onThisRoomClick: function() { onThisRoomClick: function() {
this.setState({ scope: 'Room' }); this.setState({ scope: 'Room' }, () => this._searchIfQuery());
}, },
onAllRoomsClick: function() { onAllRoomsClick: function() {
this.setState({ scope: 'All' }); this.setState({ scope: 'All' }, () => this._searchIfQuery());
}, },
onSearchChange: function(e) { onSearchChange: function(e) {
@ -49,6 +49,12 @@ module.exports = React.createClass({
} }
}, },
_searchIfQuery: function() {
if (this.refs.search_term.value) {
this.onSearch();
}
},
onSearch: function() { onSearch: function() {
this.props.onSearch(this.refs.search_term.value, this.state.scope); this.props.onSearch(this.refs.search_term.value, this.state.scope);
}, },
@ -60,11 +66,13 @@ module.exports = React.createClass({
return ( return (
<div className="mx_SearchBar"> <div className="mx_SearchBar">
<input ref="search_term" className="mx_SearchBar_input" type="text" autoFocus={true} placeholder={_t("Search…")} onKeyDown={this.onSearchChange} />
<AccessibleButton className={ searchButtonClasses } onClick={this.onSearch}><img src="img/search-button.svg" width="37" height="37" alt={_t("Search")} /></AccessibleButton>
<AccessibleButton className={ thisRoomClasses } onClick={this.onThisRoomClick}>{_t("This Room")}</AccessibleButton> <AccessibleButton className={ thisRoomClasses } onClick={this.onThisRoomClick}>{_t("This Room")}</AccessibleButton>
<AccessibleButton className={ allRoomsClasses } onClick={this.onAllRoomsClick}>{_t("All Rooms")}</AccessibleButton> <AccessibleButton className={ allRoomsClasses } onClick={this.onAllRoomsClick}>{_t("All Rooms")}</AccessibleButton>
<AccessibleButton className="mx_SearchBar_cancel" onClick={this.props.onCancelClick}><img src="img/cancel.svg" width="18" height="18" /></AccessibleButton> <div className="mx_SearchBar_input mx_textinput">
<input ref="search_term" type="text" autoFocus={true} placeholder={_t("Search…")} onKeyDown={this.onSearchChange} />
<AccessibleButton className={ searchButtonClasses } onClick={this.onSearch}></AccessibleButton>
</div>
<AccessibleButton className="mx_SearchBar_cancel" onClick={this.props.onCancelClick}></AccessibleButton>
</div> </div>
); );
}, },