summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
authorSaturnino Abril <saturnino.abril@gmail.com>2017-03-24 18:05:43 +0900
committerGeorge Goldberg <george@gberg.me>2017-03-24 09:05:43 +0000
commit1167b391854957a5d58ed569c1dc2f80e9ccc599 (patch)
tree071e2e2217dee77fee5b310620aa946d4f68a69d /webapp
parent98baf1536eb1b47d8258e188e1c80393182c6525 (diff)
downloadchat-1167b391854957a5d58ed569c1dc2f80e9ccc599.tar.gz
chat-1167b391854957a5d58ed569c1dc2f80e9ccc599.tar.bz2
chat-1167b391854957a5d58ed569c1dc2f80e9ccc599.zip
Fixed mobile search focus - keyboard collapse/focus (#5766)
Diffstat (limited to 'webapp')
-rw-r--r--webapp/components/rhs_thread.jsx120
-rw-r--r--webapp/components/search_bar.jsx37
-rw-r--r--webapp/components/search_results.jsx37
-rw-r--r--webapp/components/sidebar_right.jsx53
-rw-r--r--webapp/components/suggestion/suggestion_box.jsx5
5 files changed, 132 insertions, 120 deletions
diff --git a/webapp/components/rhs_thread.jsx b/webapp/components/rhs_thread.jsx
index 2c1d03901..8e26fb347 100644
--- a/webapp/components/rhs_thread.jsx
+++ b/webapp/components/rhs_thread.jsx
@@ -1,12 +1,10 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import SearchBox from './search_bar.jsx';
import CreateComment from './create_comment.jsx';
import RhsHeaderPost from './rhs_header_post.jsx';
import RootPost from './rhs_root_post.jsx';
import Comment from './rhs_comment.jsx';
-import FileUploadOverlay from './file_upload_overlay.jsx';
import FloatingTimestamp from './post_view/components/floating_timestamp.jsx';
import DateSeparator from './post_view/components/date_separator.jsx';
@@ -334,12 +332,6 @@ export default class RhsThread extends React.Component {
);
}
- var currentId = UserStore.getCurrentId();
- var searchForm;
- if (currentId != null) {
- searchForm = <SearchBox isCommentsPage={true}/>;
- }
-
let profile;
if (UserStore.getCurrentId() === selected.user_id) {
profile = this.props.currentUser;
@@ -407,66 +399,62 @@ export default class RhsThread extends React.Component {
}
return (
- <div className='post-right__container'>
- <FileUploadOverlay overlayType='right'/>
- <div className='search-bar__container sidebar--right__search-header'>{searchForm}</div>
- <div className='sidebar-right__body'>
- <FloatingTimestamp
- isScrolling={this.state.isScrolling}
- isMobile={Utils.isMobile()}
- createAt={this.state.topRhsPostCreateAt}
- isRhsPost={true}
- />
- <RhsHeaderPost
- fromFlaggedPosts={this.props.fromFlaggedPosts}
- fromSearch={this.props.fromSearch}
- isWebrtc={this.props.isWebrtc}
- isMentionSearch={this.props.isMentionSearch}
- toggleSize={this.props.toggleSize}
- shrink={this.props.shrink}
- />
- <Scrollbars
- autoHide={true}
- autoHideTimeout={500}
- autoHideDuration={500}
- renderThumbHorizontal={renderThumbHorizontal}
- renderThumbVertical={renderThumbVertical}
- renderView={renderView}
- onScroll={this.handleScroll}
- >
- <div className='post-right__scroll'>
- <DateSeparator
- date={previousPostDay}
- />
- <RootPost
- ref={selected.id}
- post={selected}
- commentCount={postsArray.length}
- user={profile}
- currentUser={this.props.currentUser}
- compactDisplay={this.state.compactDisplay}
- useMilitaryTime={this.props.useMilitaryTime}
- isFlagged={isRootFlagged}
- status={rootStatus}
- previewCollapsed={this.state.previewsCollapsed}
- isBusy={this.state.isBusy}
+ <div className='sidebar-right__body'>
+ <FloatingTimestamp
+ isScrolling={this.state.isScrolling}
+ isMobile={Utils.isMobile()}
+ createAt={this.state.topRhsPostCreateAt}
+ isRhsPost={true}
+ />
+ <RhsHeaderPost
+ fromFlaggedPosts={this.props.fromFlaggedPosts}
+ fromSearch={this.props.fromSearch}
+ isWebrtc={this.props.isWebrtc}
+ isMentionSearch={this.props.isMentionSearch}
+ toggleSize={this.props.toggleSize}
+ shrink={this.props.shrink}
+ />
+ <Scrollbars
+ autoHide={true}
+ autoHideTimeout={500}
+ autoHideDuration={500}
+ renderThumbHorizontal={renderThumbHorizontal}
+ renderThumbVertical={renderThumbVertical}
+ renderView={renderView}
+ onScroll={this.handleScroll}
+ >
+ <div className='post-right__scroll'>
+ <DateSeparator
+ date={previousPostDay}
+ />
+ <RootPost
+ ref={selected.id}
+ post={selected}
+ commentCount={postsArray.length}
+ user={profile}
+ currentUser={this.props.currentUser}
+ compactDisplay={this.state.compactDisplay}
+ useMilitaryTime={this.props.useMilitaryTime}
+ isFlagged={isRootFlagged}
+ status={rootStatus}
+ previewCollapsed={this.state.previewsCollapsed}
+ isBusy={this.state.isBusy}
+ />
+ <div
+ ref='rhspostlist'
+ className='post-right-comments-container'
+ >
+ {commentsLists}
+ </div>
+ <div className='post-create__container'>
+ <CreateComment
+ channelId={selected.channel_id}
+ rootId={selected.id}
+ latestPostId={postsArray.length > 0 ? postsArray[postsArray.length - 1].id : selected.id}
/>
- <div
- ref='rhspostlist'
- className='post-right-comments-container'
- >
- {commentsLists}
- </div>
- <div className='post-create__container'>
- <CreateComment
- channelId={selected.channel_id}
- rootId={selected.id}
- latestPostId={postsArray.length > 0 ? postsArray[postsArray.length - 1].id : selected.id}
- />
- </div>
</div>
- </Scrollbars>
- </div>
+ </div>
+ </Scrollbars>
</div>
);
}
diff --git a/webapp/components/search_bar.jsx b/webapp/components/search_bar.jsx
index b88e67a11..42a124eda 100644
--- a/webapp/components/search_bar.jsx
+++ b/webapp/components/search_bar.jsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import $ from 'jquery';
import * as GlobalActions from 'actions/global_actions.jsx';
import SearchStore from 'stores/search_store.jsx';
import UserStore from 'stores/user_store.jsx';
@@ -31,7 +30,9 @@ export default class SearchBar extends React.Component {
this.handleUserFocus = this.handleUserFocus.bind(this);
this.handleClear = this.handleClear.bind(this);
this.handleUserBlur = this.handleUserBlur.bind(this);
- this.performSearch = this.performSearch.bind(this);
+ this.handleSearch = this.handleSearch.bind(this);
+ this.handleSearchOnSuccess = this.handleSearchOnSuccess.bind(this);
+ this.handleSearchOnError = this.handleSearchOnError.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.searchMentions = this.searchMentions.bind(this);
this.getFlagged = this.getFlagged.bind(this);
@@ -125,7 +126,7 @@ export default class SearchBar extends React.Component {
this.setState({focused: true});
}
- performSearch(terms, isMentionSearch) {
+ handleSearch(terms, isMentionSearch) {
if (terms.length) {
this.setState({
isSearching: true,
@@ -136,23 +137,35 @@ export default class SearchBar extends React.Component {
terms,
isMentionSearch,
() => {
- this.setState({isSearching: false});
-
- if (Utils.isMobile() && this.search) {
- this.search.value = '';
- }
+ this.handleSearchOnSuccess();
},
() => {
- this.setState({isSearching: false});
+ this.handleSearchOnError();
}
);
}
}
+ handleSearchOnSuccess() {
+ if (this.mounted) {
+ this.setState({isSearching: false});
+
+ if (Utils.isMobile() && this.search) {
+ this.search.value = '';
+ }
+ }
+ }
+
+ handleSearchOnError() {
+ if (this.mounted) {
+ this.setState({isSearching: false});
+ }
+ }
+
handleSubmit(e) {
e.preventDefault();
- this.performSearch(this.state.searchTerm.trim());
- $(this.search).find('input').blur();
+ this.handleSearch(this.state.searchTerm.trim());
+ this.search.blur();
}
searchMentions(e) {
@@ -310,7 +323,7 @@ export default class SearchBar extends React.Component {
listComponent={SearchSuggestionList}
providers={this.suggestionProviders}
type='search'
- autoFocus={this.props.isFocus}
+ autoFocus={this.props.isFocus && this.state.searchTerm === ''}
/>
<div
className={clearClass}
diff --git a/webapp/components/search_results.jsx b/webapp/components/search_results.jsx
index ce72ec3b1..70f686f42 100644
--- a/webapp/components/search_results.jsx
+++ b/webapp/components/search_results.jsx
@@ -3,7 +3,6 @@
import SearchResultsHeader from './search_results_header.jsx';
import SearchResultsItem from './search_results_item.jsx';
-import SearchBox from './search_bar.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import SearchStore from 'stores/search_store.jsx';
@@ -168,11 +167,6 @@ export default class SearchResults extends React.Component {
render() {
var results = this.state.results;
- var currentId = UserStore.getCurrentId();
- var searchForm = null;
- if (currentId) {
- searchForm = <SearchBox isFocus={Utils.isMobile()}/>;
- }
var noResults = (!results || !results.order || !results.order.length);
const searchTerm = this.state.searchTerm;
const profiles = this.state.profiles || {};
@@ -312,23 +306,20 @@ export default class SearchResults extends React.Component {
}
return (
- <div className='sidebar--right__content'>
- <div className='search-bar__container sidebar--right__search-header'>{searchForm}</div>
- <div className='sidebar-right__body'>
- <SearchResultsHeader
- isMentionSearch={this.props.isMentionSearch}
- toggleSize={this.props.toggleSize}
- shrink={this.props.shrink}
- isFlaggedPosts={this.props.isFlaggedPosts}
- isPinnedPosts={this.props.isPinnedPosts}
- channelDisplayName={this.props.channelDisplayName}
- />
- <div
- id='search-items-container'
- className='search-items-container'
- >
- {ctls}
- </div>
+ <div className='sidebar-right__body'>
+ <SearchResultsHeader
+ isMentionSearch={this.props.isMentionSearch}
+ toggleSize={this.props.toggleSize}
+ shrink={this.props.shrink}
+ isFlaggedPosts={this.props.isFlaggedPosts}
+ isPinnedPosts={this.props.isPinnedPosts}
+ channelDisplayName={this.props.channelDisplayName}
+ />
+ <div
+ id='search-items-container'
+ className='search-items-container'
+ >
+ {ctls}
</div>
</div>
);
diff --git a/webapp/components/sidebar_right.jsx b/webapp/components/sidebar_right.jsx
index 42b7381f4..6a0716ce1 100644
--- a/webapp/components/sidebar_right.jsx
+++ b/webapp/components/sidebar_right.jsx
@@ -5,6 +5,8 @@ import $ from 'jquery';
import SearchResults from './search_results.jsx';
import RhsThread from './rhs_thread.jsx';
+import SearchBox from './search_bar.jsx';
+import FileUploadOverlay from './file_upload_overlay.jsx';
import SearchStore from 'stores/search_store.jsx';
import PostStore from 'stores/post_store.jsx';
import UserStore from 'stores/user_store.jsx';
@@ -188,30 +190,43 @@ export default class SidebarRight extends React.Component {
expandedClass = 'sidebar--right--expanded';
}
+ var currentId = UserStore.getCurrentId();
+ var searchForm = null;
+ if (currentId) {
+ searchForm = <SearchBox isFocus={this.state.searchVisible && Utils.isMobile()}/>;
+ }
+
if (this.state.searchVisible) {
content = (
- <SearchResults
- isMentionSearch={this.state.isMentionSearch}
- isFlaggedPosts={this.state.isFlaggedPosts}
- isPinnedPosts={this.state.isPinnedPosts}
- useMilitaryTime={this.state.useMilitaryTime}
- toggleSize={this.toggleSize}
- shrink={this.onShrink}
- channelDisplayName={this.props.channel ? this.props.channel.display_name : ''}
- />
+ <div className='sidebar--right__content'>
+ <div className='search-bar__container sidebar--right__search-header'>{searchForm}</div>
+ <SearchResults
+ isMentionSearch={this.state.isMentionSearch}
+ isFlaggedPosts={this.state.isFlaggedPosts}
+ isPinnedPosts={this.state.isPinnedPosts}
+ useMilitaryTime={this.state.useMilitaryTime}
+ toggleSize={this.toggleSize}
+ shrink={this.onShrink}
+ channelDisplayName={this.props.channel ? this.props.channel.display_name : ''}
+ />
+ </div>
);
} else if (this.state.postRightVisible) {
content = (
- <RhsThread
- fromFlaggedPosts={this.state.fromFlaggedPosts}
- fromSearch={this.state.fromSearch}
- isWebrtc={WebrtcStore.isBusy()}
- isMentionSearch={this.state.isMentionSearch}
- currentUser={this.state.currentUser}
- useMilitaryTime={this.state.useMilitaryTime}
- toggleSize={this.toggleSize}
- shrink={this.onShrink}
- />
+ <div className='post-right__container'>
+ <FileUploadOverlay overlayType='right'/>
+ <div className='search-bar__container sidebar--right__search-header'>{searchForm}</div>
+ <RhsThread
+ fromFlaggedPosts={this.state.fromFlaggedPosts}
+ fromSearch={this.state.fromSearch}
+ isWebrtc={WebrtcStore.isBusy()}
+ isMentionSearch={this.state.isMentionSearch}
+ currentUser={this.state.currentUser}
+ useMilitaryTime={this.state.useMilitaryTime}
+ toggleSize={this.toggleSize}
+ shrink={this.onShrink}
+ />
+ </div>
);
}
diff --git a/webapp/components/suggestion/suggestion_box.jsx b/webapp/components/suggestion/suggestion_box.jsx
index eade494ef..2ac842846 100644
--- a/webapp/components/suggestion/suggestion_box.jsx
+++ b/webapp/components/suggestion/suggestion_box.jsx
@@ -25,6 +25,7 @@ export default class SuggestionBox extends React.Component {
this.handleCompositionEnd = this.handleCompositionEnd.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handlePretextChanged = this.handlePretextChanged.bind(this);
+ this.blur = this.blur.bind(this);
this.suggestionId = Utils.generateId();
SuggestionStore.registerSuggestionBox(this.suggestionId);
@@ -189,6 +190,10 @@ export default class SuggestionBox extends React.Component {
}
}
+ blur() {
+ this.refs.textbox.blur();
+ }
+
render() {
const {
type,