diff --git a/frontend/src/components/search/search.js b/frontend/src/components/search/search.js index 2b31c8fdfd..3e5a4d61a8 100644 --- a/frontend/src/components/search/search.js +++ b/frontend/src/components/search/search.js @@ -3,15 +3,15 @@ import PropTypes from 'prop-types'; import isHotkey from 'is-hotkey'; import MediaQuery from 'react-responsive'; import { seafileAPI } from '../../utils/seafile-api'; -import { enableSeafileAI, gettext, siteRoot } from '../../utils/constants'; +import { gettext, siteRoot } from '../../utils/constants'; import SearchResultItem from './search-result-item'; import { Utils } from '../../utils/utils'; import { isMac } from '../../utils/extra-attributes'; import toaster from '../toast'; -import { SEARCH_DELAY_TIME, getValueLength } from './constant'; const propTypes = { repoID: PropTypes.string, + path: PropTypes.string, placeholder: PropTypes.string, onSearchedClick: PropTypes.func.isRequired, isPublic: PropTypes.bool, @@ -28,6 +28,7 @@ class Search extends Component { this.state = { width: 'default', value: '', + inputValue: '', resultItems: [], highlightIndex: 0, page: 0, @@ -40,13 +41,11 @@ class Search extends Component { isSearchInputShow: false, // for mobile searchPageUrl: this.baseSearchPageURL, }; - this.inputValue = ''; this.highlightRef = null; this.source = null; // used to cancel request; this.inputRef = React.createRef(); this.searchContainer = React.createRef(); this.searchResultListRef = React.createRef(); - this.timer = null; this.isChineseInput = false; } @@ -60,33 +59,14 @@ class Search extends Component { document.removeEventListener('keydown', this.onDocumentKeydown); document.removeEventListener('compositionstart', this.onCompositionStart); document.removeEventListener('compositionend', this.onCompositionEnd); - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - this.isChineseInput = false; } onCompositionStart = () => { this.isChineseInput = true; - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } }; onCompositionEnd = () => { this.isChineseInput = false; - // chrome:compositionstart -> onChange -> compositionend - // not chrome:compositionstart -> compositionend -> onChange - // The onChange event will setState and change input value, then setTimeout to initiate the search - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - this.timer = setTimeout(() => { - this.onSearch(); - }, SEARCH_DELAY_TIME); }; onDocumentKeydown = (e) => { @@ -197,45 +177,24 @@ class Search extends Component { if (this.state.showRecent) { this.setState({ showRecent: false }); } - const newValue = event.target.value; - this.setState({ value: newValue }, () => { - if (this.inputValue === newValue.trim()) return; - this.inputValue = newValue.trim(); - if (!this.isChineseInput) { - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - this.timer = setTimeout(() => { - this.onSearch(); - }, SEARCH_DELAY_TIME); + this.setState({ value: event.target.value }); + setTimeout(() => { + if (this.isChineseInput === false) { + this.setState({ inputValue: event.target.value }); } - }); + }, 1); }; onKeydownHandler = (event) => { if (isHotkey('enter', event)) { - this.onSearch(); - } - }; - - onSearch = () => { - const { value } = this.state; - const { repoID } = this.props; - if (this.inputValue === '' || getValueLength(this.inputValue) < 3) { + this.searchRepo(); + } else { this.setState({ highlightIndex: 0, resultItems: [], isResultGetted: false }); - return; } - const queryData = { - q: value, - search_repo: repoID ? repoID : 'all', - search_ftypes: 'all', - }; - this.getSearchResult(queryData); }; getSearchResult = (queryData) => { @@ -281,11 +240,7 @@ class Search extends Component { this.setState({ isLoading: false }); }); } else { - if (enableSeafileAI) { - this.onAiSearch(queryData, cancelToken); - } else { - this.onNormalSearch(queryData, cancelToken, page); - } + this.onNormalSearch(queryData, cancelToken, page); } }; @@ -319,23 +274,6 @@ class Search extends Component { }); } - onAiSearch = (params, cancelToken) => { - let results = []; - seafileAPI.aiSearchFiles(params, cancelToken).then(res => { - results = [...results, ...this.formatResultItems(res.data.results)]; - this.setState({ - resultItems: results, - isResultGetted: true, - isLoading: false, - hasMore: false, - }); - }).catch(error => { - /* eslint-disable */ - console.log(error); - this.setState({ isLoading: false }); - }); - }; - onResultListScroll = (e) => { // Load less than 100 results if (!this.state.hasMore || this.state.isLoading || this.state.resultItems.length > 100) { @@ -377,10 +315,10 @@ class Search extends Component { } resetToDefault() { - this.inputValue = ''; this.setState({ width: '', value: '', + inputValue: '', isMaskShow: false, isCloseShow: false, isResultGetted: false, @@ -407,16 +345,11 @@ class Search extends Component { } } - const searchStrLength = getValueLength(this.inputValue); - - if (searchStrLength === 0) { + if (this.state.inputValue.trim().length === 0) { return
{gettext('Type characters to start search')}
; } - else if (searchStrLength < 3) { - return
{gettext('Type more characters to start search')}
; - } else if (!isResultGetted) { - return ; + return this.renderSearchTypes(this.state.inputValue.trim()); } else if (resultItems.length > 0) { return this.renderResults(resultItems); @@ -426,6 +359,63 @@ class Search extends Component { } } + renderSearchTypes = (inputValue) => { + return ( +
+ {this.props.repoID && +
+ + {inputValue} + {gettext('in this library')} +
+ } + {(this.props.path && this.props.path !== '/') && +
+ + {inputValue} + {gettext('in this folder')} +
+ } +
+ + {inputValue} + {gettext('in all libraries')} +
+
+ ); + } + + searchRepo = () => { + const { value } = this.state; + const queryData = { + q: value, + search_repo: this.props.repoID, + search_ftypes: 'all', + }; + this.getSearchResult(queryData); + }; + + searchFolder = () => { + const { value } = this.state; + const queryData = { + q: value, + search_repo: this.props.repoID, + search_ftypes: 'all', + search_path: this.props.path, + }; + this.getSearchResult(queryData); + }; + + searchAllRepos = () => { + const { value } = this.state; + const queryData = { + q: value, + search_repo: 'all', + search_ftypes: 'all', + }; + this.getSearchResult(queryData); + }; + renderResults = (resultItems, isVisited) => { const { highlightIndex } = this.state; const results = ( diff --git a/frontend/src/components/toolbar/common-toolbar.js b/frontend/src/components/toolbar/common-toolbar.js index 1fe836bb4f..a5938d4a9f 100644 --- a/frontend/src/components/toolbar/common-toolbar.js +++ b/frontend/src/components/toolbar/common-toolbar.js @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { isPro, gettext, showLogoutIcon, enableSeafileAI } from '../../utils/constants'; +import { isPro, gettext, showLogoutIcon } from '../../utils/constants'; import Search from '../search/search'; -import AISearch from '../search/ai-search'; +// import AISearch from '../search/ai-search'; import SearchByName from '../search/search-by-name'; import Notification from '../common/notification'; import Account from '../common/account'; @@ -10,6 +10,7 @@ import Logout from '../common/logout'; const propTypes = { repoID: PropTypes.string, + path: PropTypes.string, repoName: PropTypes.string, isLibView: PropTypes.bool, onSearchedClick: PropTypes.func.isRequired, @@ -20,30 +21,30 @@ const propTypes = { class CommonToolbar extends React.Component { renderSearch = () => { - const { repoID, repoName, isLibView, searchPlaceholder } = this.props; + const { repoID, repoName, isLibView, searchPlaceholder, path } = this.props; const placeholder = searchPlaceholder || gettext('Search files'); if (isPro) { - if (enableSeafileAI && isLibView) { - return ( - - ); - } else { - return ( - - ); - } + return ( + + ); + // if (enableSeafileAI && isLibView) { + // return ( + // + // ); + // } } else { if (isLibView) { return ( diff --git a/frontend/src/css/search.css b/frontend/src/css/search.css index f0e5360aeb..ea02dbee23 100644 --- a/frontend/src/css/search.css +++ b/frontend/src/css/search.css @@ -385,3 +385,26 @@ font-weight: normal; margin: 7px 0 10px; } + +.search-types { + padding-right: 16px; + padding-top: 6px; +} + +.search-types>div { + position: relative; + height: 40px; + line-height: 40px; + cursor: pointer; + padding: 0px 40px; + border-radius: 4px; +} + +.search-types>div:hover { + background-color: rgb(245, 245, 245); +} + +.search-types .search-types-text { + margin-left: 6px; + color: #666; +} diff --git a/frontend/src/pages/lib-content-view/lib-content-toolbar.js b/frontend/src/pages/lib-content-view/lib-content-toolbar.js index b846a5631d..50d7719c4d 100644 --- a/frontend/src/pages/lib-content-view/lib-content-toolbar.js +++ b/frontend/src/pages/lib-content-view/lib-content-toolbar.js @@ -9,6 +9,7 @@ const propTypes = { repoName: PropTypes.string.isRequired, onSearchedClick: PropTypes.func.isRequired, currentRepoInfo: PropTypes.object, + path: PropTypes.string, }; class LibContentToolbar extends React.Component { @@ -21,6 +22,7 @@ class LibContentToolbar extends React.Component {