mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-14 23:46:49 +00:00
[search] keep & display items visited recently(for both global search & search in a single library) (#5826)
This commit is contained in:
parent
2927c2ce02
commit
ce2df5f223
@ -197,9 +197,36 @@ export default class AISearch extends Component {
|
||||
|
||||
onItemClickHandler = (item) => {
|
||||
this.resetToDefault();
|
||||
this.keepVisitedItem(item);
|
||||
this.props.onSearchedClick(item);
|
||||
};
|
||||
|
||||
keepVisitedItem = (targetItem) => {
|
||||
const { repoID } = this.props;
|
||||
let targetIndex;
|
||||
let storeKey = 'sfVisitedAISearchItems';
|
||||
if (repoID) {
|
||||
storeKey += repoID;
|
||||
}
|
||||
const items = JSON.parse(localStorage.getItem(storeKey)) || [];
|
||||
for (let i = 0, len = items.length; i < len; i++) {
|
||||
const { repo_id, path } = items[i];
|
||||
const { repo_id: targetRepoID, path: targetPath } = targetItem;
|
||||
if (repo_id == targetRepoID && path == targetPath) {
|
||||
targetIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (targetIndex != undefined) {
|
||||
items.splice(targetIndex, 1);
|
||||
}
|
||||
items.unshift(targetItem);
|
||||
if (items.length > 50) { // keep 50 items at most
|
||||
items.pop();
|
||||
}
|
||||
localStorage.setItem(storeKey, JSON.stringify(items));
|
||||
};
|
||||
|
||||
onChangeHandler = (event) => {
|
||||
const newValue = event.target.value;
|
||||
this.setState({ value: newValue }, () => {
|
||||
@ -342,11 +369,54 @@ export default class AISearch extends Component {
|
||||
this.setState({ searchMode: SEARCH_MODE.COMBINED });
|
||||
}
|
||||
|
||||
renderVisitedItems = (items) => {
|
||||
const { highlightIndex } = this.state;
|
||||
const results = (
|
||||
<>
|
||||
<h4 className="visited-search-results-title">{gettext('Search results visited recently')}</h4>
|
||||
<ul className="search-result-list" ref={this.searchResultListRef}>
|
||||
{items.map((item, index) => {
|
||||
const isHighlight = index === highlightIndex;
|
||||
return (
|
||||
<SearchResultItem
|
||||
key={index}
|
||||
item={item}
|
||||
onItemClickHandler={this.onItemClickHandler}
|
||||
isHighlight={isHighlight}
|
||||
setRef={isHighlight ? (ref) => {this.highlightRef = ref;} : () => {}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MediaQuery query="(min-width: 768px)">
|
||||
<div className="search-result-list-container">{results}</div>
|
||||
</MediaQuery>
|
||||
<MediaQuery query="(max-width: 767.8px)">
|
||||
{results}
|
||||
</MediaQuery>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
renderSearchResult() {
|
||||
const { resultItems, highlightIndex, width, searchMode, answeringResult } = this.state;
|
||||
if (!width || width === 'default') return null;
|
||||
|
||||
if (!this.state.isResultShow) return null;
|
||||
if (!this.state.isResultShow) {
|
||||
const { repoID } = this.props;
|
||||
let storeKey = 'sfVisitedAISearchItems';
|
||||
if (repoID) {
|
||||
storeKey += repoID;
|
||||
}
|
||||
const visitedItems = JSON.parse(localStorage.getItem(storeKey)) || [];
|
||||
return visitedItems.length ? this.renderVisitedItems(visitedItems) : null;
|
||||
}
|
||||
|
||||
if (!this.state.isResultGetted || getValueLength(this.inputValue) < 3) {
|
||||
return (
|
||||
<span className="loading-icon loading-tip"></span>
|
||||
|
@ -163,9 +163,36 @@ class Search extends Component {
|
||||
|
||||
onItemClickHandler = (item) => {
|
||||
this.resetToDefault();
|
||||
this.keepVisitedItem(item);
|
||||
this.props.onSearchedClick(item);
|
||||
};
|
||||
|
||||
keepVisitedItem = (targetItem) => {
|
||||
const { repoID } = this.props;
|
||||
let targetIndex;
|
||||
let storeKey = 'sfVisitedSearchItems';
|
||||
if (repoID) {
|
||||
storeKey += repoID;
|
||||
}
|
||||
const items = JSON.parse(localStorage.getItem(storeKey)) || [];
|
||||
for (let i = 0, len = items.length; i < len; i++) {
|
||||
const { repo_id, path } = items[i];
|
||||
const { repo_id: targetRepoID, path: targetPath } = targetItem;
|
||||
if (repo_id == targetRepoID && path == targetPath) {
|
||||
targetIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (targetIndex != undefined) {
|
||||
items.splice(targetIndex, 1);
|
||||
}
|
||||
items.unshift(targetItem);
|
||||
if (items.length > 50) { // keep 50 items at most
|
||||
items.pop();
|
||||
}
|
||||
localStorage.setItem(storeKey, JSON.stringify(items));
|
||||
};
|
||||
|
||||
onChangeHandler = (event) => {
|
||||
const newValue = event.target.value;
|
||||
this.setState({ value: newValue }, () => {
|
||||
@ -341,7 +368,16 @@ class Search extends Component {
|
||||
const { resultItems, highlightIndex, width } = this.state;
|
||||
if (!width || width === 'default') return null;
|
||||
|
||||
if (!this.state.isResultShow) return null;
|
||||
if (!this.state.isResultShow) {
|
||||
const { repoID } = this.props;
|
||||
let storeKey = 'sfVisitedSearchItems';
|
||||
if (repoID) {
|
||||
storeKey += repoID;
|
||||
}
|
||||
const visitedItems = JSON.parse(localStorage.getItem(storeKey)) || [];
|
||||
return visitedItems.length ? this.renderResults(visitedItems, true) : null;
|
||||
}
|
||||
|
||||
if (!this.state.isResultGetted || getValueLength(this.inputValue) < 3) {
|
||||
return (
|
||||
<span className="loading-icon loading-tip"></span>
|
||||
@ -353,7 +389,14 @@ class Search extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
return this.renderResults(resultItems);
|
||||
}
|
||||
|
||||
renderResults = (resultItems, isVisited) => {
|
||||
const { highlightIndex } = this.state;
|
||||
const results = (
|
||||
<>
|
||||
{isVisited && <h4 className="visited-search-results-title">{gettext('Search results visited recently')}</h4>}
|
||||
<ul className="search-result-list" ref={this.searchResultListRef}>
|
||||
{resultItems.map((item, index) => {
|
||||
const isHighlight = index === highlightIndex;
|
||||
@ -368,6 +411,7 @@ class Search extends Component {
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -346,3 +346,10 @@
|
||||
.search-result-container .search-mode-similarity-index-status.index-status-uncreated {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.visited-search-results-title {
|
||||
color: #999;
|
||||
font-size: .875rem;
|
||||
font-weight: normal;
|
||||
margin: 7px 0 10px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user