1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-19 17:39:39 +00:00
seahub/frontend/src/components/search/search.js

239 lines
6.1 KiB
JavaScript
Raw Normal View History

2018-08-06 10:29:12 +00:00
import React, { Component } from 'react';
2018-09-29 07:47:53 +00:00
import { gettext, repoID, siteRoot } from '../constants';
2018-09-04 09:16:50 +00:00
import SearchResultItem from './search-result-item';
2018-09-19 01:57:17 +00:00
import editorUtilities from '../../utils/editor-utilties';
import More from '../more';
2018-08-06 10:29:12 +00:00
class Search extends Component {
2018-08-17 04:23:55 +00:00
constructor(props) {
super(props);
this.state = {
width: 'default',
value: '',
resultItems: [],
isMaskShow: false,
isResultShow: false,
isResultGetted: false,
isCloseShow: false
};
this.inputValue = '';
this.source = null; // used to cancle request;
}
onFocusHandler = () => {
this.setState({
width: '30rem',
isMaskShow: true,
isCloseShow: true
})
}
onCloseHandler = () => {
this.resetToDefault();
}
onItemClickHandler = (item) => {
2018-08-17 04:23:55 +00:00
this.resetToDefault();
this.props.onSearchedClick(item);
2018-08-17 04:23:55 +00:00
}
onChangeHandler = (event) => {
let _this = this;
this.setState({value: event.target.value});
let newValue = event.target.value;
if (this.inputValue === newValue.trim()) {
return false;
}
this.inputValue = newValue.trim();
if (this.inputValue === '' || _this.getValueLength(this.inputValue) < 3) {
this.setState({
isResultShow: false,
isResultGetted: false
})
return false;
}
let queryData = {
q: newValue,
search_repo: repoID ? repoID : 'all',
search_ftypes: repoID ? 'custom' : 'all',
ftype: repoID ? 'Markdown' : '',
input_fexts: repoID ? 'md' : ''
2018-08-17 04:23:55 +00:00
}
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(_this.getSearchResult(queryData), 500);
}
getSearchResult(queryData) {
if(this.source){
this.cancelRequest();
}
this.setState({
isResultShow: true,
isResultGetted: false
})
2018-09-04 09:16:50 +00:00
this.source = editorUtilities.getSource();
2018-08-17 04:23:55 +00:00
this.sendRequest(queryData, this.source.token);
}
sendRequest(queryData, cancelToken) {
var _this = this;
2018-09-04 09:16:50 +00:00
editorUtilities.searchFiles(queryData,cancelToken).then(res => {
2018-08-17 04:23:55 +00:00
if (!res.data.total) {
_this.setState({
resultItems: [],
isResultGetted: true
})
_this.source = null;
return;
}
let items = _this.formatResultItems(res.data.results);
_this.setState({
resultItems: items,
isResultGetted: true
})
_this.source = null;
}).catch(res => {
console.log(res);
})
}
cancelRequest() {
this.source.cancel("prev request is cancelled");
}
getValueLength(str) {
var i = 0, code, len = 0;
for (; i < str.length; i++) {
code = str.charCodeAt(i);
if (code == 10) { //solve enter problem
len += 2;
} else if (code < 0x007f) {
len += 1;
} else if (code >= 0x0080 && code <= 0x07ff) {
len += 2;
} else if (code >= 0x0800 && code <= 0xffff) {
len += 3;
}
}
return len;
}
formatResultItems(data) {
let items = [];
let length = data.length > 5 ? 5 : data.length;
for (let i = 0; i < length; i++) {
items[i] = {};
items[i]['index'] = [i];
items[i]['name'] = data[i].name;
items[i]['path'] = data[i].fullpath;
items[i]['repo_id'] = data[i].repo_id;
2018-08-17 04:23:55 +00:00
items[i]['link_content'] = decodeURI(data[i].fullpath).substring(1);
items[i]['content'] = data[i].content_highlight;
}
return items;
}
resetToDefault() {
this.inputValue = null;
this.setState({
width: '',
value: '',
isMaskShow: false,
isCloseShow: false,
isResultShow: false,
isResultGetted: false,
resultItems: []
})
}
onShowMore = () => {
let newValue = this.state.value;
let queryData = {
q: newValue,
search_repo: repoID ? repoID : 'all',
search_ftypes: repoID ? 'custom' : 'all',
ftype: repoID ? 'Markdown' : '',
input_fexts: repoID ? 'md' : ''
};
let params = '';
for (let key in queryData) {
params += key + '=' + queryData[key] + '&';
}
2018-09-29 07:47:53 +00:00
window.location = siteRoot + '/search/?' + params.slice(0, params.length - 1);
}
2018-08-17 04:23:55 +00:00
renderSearchResult() {
var _this = this;
if (!this.state.isResultShow) {
return;
}
if (!this.state.isResultGetted || this.getValueLength(this.inputValue) < 3) {
return (
<span className="loading-icon loading-tip"></span>
)
}
if (!this.state.resultItems.length) {
return (
<div className="search-result-none">No results matching.</div>
)
}
let isShowMore = this.state.resultItems.length >= 5 ? true : false;
2018-08-17 04:23:55 +00:00
return (
<ul className="search-result-list">
{this.state.resultItems.map(item => {
return (
<SearchResultItem
key={item.index}
item={item}
onItemClickHandler={_this.onItemClickHandler}
/>
)
})}
{isShowMore && <More onShowMore={this.onShowMore}/>}
2018-08-17 04:23:55 +00:00
</ul>
)
}
2018-08-06 10:29:12 +00:00
render() {
2018-08-17 04:23:55 +00:00
let width = this.state.width !== 'default' ? this.state.width : '';
let style = {'width': width};
2018-08-06 10:29:12 +00:00
return (
2018-08-17 04:23:55 +00:00
<div className="search">
<div className={`search-mask ${this.state.isMaskShow ? "" : "hide"}`} onClick={this.onCloseHandler}></div>
<div className="search-container">
2018-09-19 01:57:17 +00:00
<div className="input-icon">
<i className="search-icon-left input-icon-addon fas fa-search"></i>
2018-08-17 04:23:55 +00:00
<input
type="text"
2018-09-19 01:57:17 +00:00
className="form-control search-input"
2018-08-17 04:23:55 +00:00
name="query"
placeholder={this.props.placeholder}
2018-08-17 04:23:55 +00:00
style={style}
value={this.state.value}
onFocus={this.onFocusHandler}
onChange={this.onChangeHandler}
autoComplete="off"
/>
{this.state.isCloseShow && <i className='search-icon-right input-icon-addon fas fa-times' onClick={this.onCloseHandler}></i>}
2018-08-17 04:23:55 +00:00
</div>
<div className="search-result-container">
{this.renderSearchResult()}
</div>
</div>
</div>
2018-08-06 10:29:12 +00:00
)
}
}
export default Search;