diff --git a/frontend/src/components/search/ai-search.js b/frontend/src/components/search/ai-search.js
index f6c8c04930..8f5fd3c6f7 100644
--- a/frontend/src/components/search/ai-search.js
+++ b/frontend/src/components/search/ai-search.js
@@ -73,6 +73,13 @@ export default class AISearch extends Component {
this.isRepoOwner = false;
this.isAdmin = false;
}
+ this.searchResultListContainerRef = React.createRef();
+ const { repoID } = props;
+ let storeKey = 'sfVisitedAISearchItems';
+ if (repoID) {
+ storeKey += repoID;
+ }
+ this.storeKey = storeKey;
}
componentDidMount() {
@@ -150,6 +157,22 @@ export default class AISearch extends Component {
onUp = (e) => {
e.preventDefault();
e.stopPropagation();
+
+ if (this.state.showRecent) {
+ const { highlightIndex } = this.state;
+ if (highlightIndex > 0) {
+ this.setState({ highlightIndex: highlightIndex - 1 }, () => {
+ if (this.highlightRef) {
+ const { top, height } = this.highlightRef.getBoundingClientRect();
+ if (top - height < 0) {
+ this.searchResultListContainerRef.current.scrollTop -= height;
+ }
+ }
+ });
+ }
+ return;
+ }
+
if (!this.state.isResultGetted) {
let highlightSearchTypesIndex = this.state.highlightSearchTypesIndex - 1;
if (highlightSearchTypesIndex < 0) {
@@ -158,13 +181,14 @@ export default class AISearch extends Component {
this.setState({ highlightSearchTypesIndex });
return;
}
+
const { highlightIndex } = this.state;
if (highlightIndex > 0) {
this.setState({ highlightIndex: highlightIndex - 1 }, () => {
if (this.highlightRef) {
const { top, height } = this.highlightRef.getBoundingClientRect();
if (top - height < 0) {
- this.searchContainer.current.scrollTop -= height;
+ this.searchResultListContainerRef.current.scrollTop -= height;
}
}
});
@@ -174,6 +198,25 @@ export default class AISearch extends Component {
onDown = (e) => {
e.preventDefault();
e.stopPropagation();
+
+ if (this.state.showRecent) {
+ const visitedItems = JSON.parse(localStorage.getItem(this.storeKey)) || [];
+ const { highlightIndex } = this.state;
+ if (highlightIndex < visitedItems.length - 1) {
+ this.setState({ highlightIndex: highlightIndex + 1 }, () => {
+ if (this.highlightRef) {
+ const { top, height } = this.highlightRef.getBoundingClientRect();
+ const outerHeight = 300;
+ if (top > outerHeight) {
+ const newScrollTop = this.searchResultListContainerRef.current.scrollTop + height;
+ this.searchResultListContainerRef.current.scrollTop = newScrollTop;
+ }
+ }
+ });
+ }
+ return;
+ }
+
if (!this.state.isResultGetted) {
let highlightSearchTypesIndex = this.state.highlightSearchTypesIndex + 1;
if (highlightSearchTypesIndex > this.state.searchTypesMax) {
@@ -182,6 +225,7 @@ export default class AISearch extends Component {
this.setState({ highlightSearchTypesIndex });
return;
}
+
const { highlightIndex, resultItems } = this.state;
if (highlightIndex < resultItems.length - 1) {
this.setState({ highlightIndex: highlightIndex + 1 }, () => {
@@ -189,7 +233,8 @@ export default class AISearch extends Component {
const { top, height } = this.highlightRef.getBoundingClientRect();
const outerHeight = 300;
if (top > outerHeight) {
- this.searchContainer.current.scrollTop += height;
+ const newScrollTop = this.searchResultListContainerRef.current.scrollTop + height;
+ this.searchResultListContainerRef.current.scrollTop = newScrollTop;
}
}
});
@@ -198,6 +243,19 @@ export default class AISearch extends Component {
onEnter = (e) => {
e.preventDefault();
+
+ if (this.state.showRecent) {
+ const visitedItems = JSON.parse(localStorage.getItem(this.storeKey)) || [];
+ const item = visitedItems[this.state.highlightIndex];
+ if (item) {
+ if (document.activeElement) {
+ document.activeElement.blur();
+ }
+ this.onItemClickHandler(item);
+ }
+ return;
+ }
+
if (!this.state.isResultGetted) {
let highlightDom = document.querySelector('.search-types-highlight');
if (highlightDom) {
@@ -213,6 +271,7 @@ export default class AISearch extends Component {
return;
}
}
+
let item = this.state.resultItems[this.state.highlightIndex];
if (item) {
if (document.activeElement) {
@@ -244,13 +303,8 @@ export default class AISearch extends Component {
};
keepVisitedItem = (targetItem) => {
- const { repoID } = this.props;
let targetIndex;
- let storeKey = 'sfVisitedAISearchItems';
- if (repoID) {
- storeKey += repoID;
- }
- const items = JSON.parse(localStorage.getItem(storeKey)) || [];
+ const items = JSON.parse(localStorage.getItem(this.storeKey)) || [];
for (let i = 0, len = items.length; i < len; i++) {
const { repo_id, path } = items[i];
const { repo_id: targetRepoID, path: targetPath } = targetItem;
@@ -266,7 +320,7 @@ export default class AISearch extends Component {
if (items.length > 50) { // keep 50 items at most
items.pop();
}
- localStorage.setItem(storeKey, JSON.stringify(items));
+ localStorage.setItem(this.storeKey, JSON.stringify(items));
};
onChangeHandler = (event) => {
@@ -436,7 +490,7 @@ export default class AISearch extends Component {
return (
<>
- {results}
+ {results}
{results}
@@ -567,12 +621,7 @@ export default class AISearch extends Component {
if (!width || width === 'default') return null;
if (this.state.showRecent) {
- const { repoID } = this.props;
- let storeKey = 'sfVisitedAISearchItems';
- if (repoID) {
- storeKey += repoID;
- }
- const visitedItems = JSON.parse(localStorage.getItem(storeKey)) || [];
+ const visitedItems = JSON.parse(localStorage.getItem(this.storeKey)) || [];
if (visitedItems.length) {
return this.renderVisitedItems(visitedItems);
}
diff --git a/frontend/src/components/search/search.js b/frontend/src/components/search/search.js
index 8a4435a9aa..35e4838735 100644
--- a/frontend/src/components/search/search.js
+++ b/frontend/src/components/search/search.js
@@ -57,6 +57,13 @@ class Search extends Component {
this.searchContainer = React.createRef();
this.searchResultListRef = React.createRef();
this.isChineseInput = false;
+ this.searchResultListContainerRef = React.createRef();
+ const { repoID } = props;
+ let storeKey = 'sfVisitedSearchItems';
+ if (repoID) {
+ storeKey += repoID;
+ }
+ this.storeKey = storeKey;
}
componentDidMount() {
@@ -112,6 +119,22 @@ class Search extends Component {
onUp = (e) => {
e.preventDefault();
e.stopPropagation();
+
+ if (this.state.showRecent) {
+ const { highlightIndex } = this.state;
+ if (highlightIndex > 0) {
+ this.setState({ highlightIndex: highlightIndex - 1 }, () => {
+ if (this.highlightRef) {
+ const { top, height } = this.highlightRef.getBoundingClientRect();
+ if (top - height < 0) {
+ this.searchResultListContainerRef.current.scrollTop -= height;
+ }
+ }
+ });
+ }
+ return;
+ }
+
if (!this.state.isResultGetted) {
let highlightSearchTypesIndex = this.state.highlightSearchTypesIndex - 1;
if (highlightSearchTypesIndex < 0) {
@@ -120,13 +143,14 @@ class Search extends Component {
this.setState({ highlightSearchTypesIndex });
return;
}
+
const { highlightIndex } = this.state;
if (highlightIndex > 0) {
this.setState({ highlightIndex: highlightIndex - 1 }, () => {
if (this.highlightRef) {
const { top, height } = this.highlightRef.getBoundingClientRect();
if (top - height < 0) {
- this.searchContainer.current.scrollTop -= height;
+ this.searchResultListContainerRef.current.scrollTop -= height;
}
}
});
@@ -136,6 +160,25 @@ class Search extends Component {
onDown = (e) => {
e.preventDefault();
e.stopPropagation();
+
+ if (this.state.showRecent) {
+ const visitedItems = JSON.parse(localStorage.getItem(this.storeKey)) || [];
+ const { highlightIndex } = this.state;
+ if (highlightIndex < visitedItems.length - 1) {
+ this.setState({ highlightIndex: highlightIndex + 1 }, () => {
+ if (this.highlightRef) {
+ const { top, height } = this.highlightRef.getBoundingClientRect();
+ const outerHeight = 300;
+ if (top > outerHeight) {
+ const newScrollTop = this.searchResultListContainerRef.current.scrollTop + height;
+ this.searchResultListContainerRef.current.scrollTop = newScrollTop;
+ }
+ }
+ });
+ }
+ return;
+ }
+
if (!this.state.isResultGetted) {
let highlightSearchTypesIndex = this.state.highlightSearchTypesIndex + 1;
if (highlightSearchTypesIndex > this.state.searchTypesMax) {
@@ -144,6 +187,7 @@ class Search extends Component {
this.setState({ highlightSearchTypesIndex });
return;
}
+
const { highlightIndex, resultItems } = this.state;
if (highlightIndex < resultItems.length - 1) {
this.setState({ highlightIndex: highlightIndex + 1 }, () => {
@@ -151,7 +195,8 @@ class Search extends Component {
const { top, height } = this.highlightRef.getBoundingClientRect();
const outerHeight = 300;
if (top > outerHeight) {
- this.searchContainer.current.scrollTop += height;
+ const newScrollTop = this.searchResultListContainerRef.current.scrollTop + height;
+ this.searchResultListContainerRef.current.scrollTop = newScrollTop;
}
}
});
@@ -160,6 +205,17 @@ class Search extends Component {
onEnter = (e) => {
e.preventDefault();
+ if (this.state.showRecent) {
+ const visitedItems = JSON.parse(localStorage.getItem(this.storeKey)) || [];
+ const item = visitedItems[this.state.highlightIndex];
+ if (item) {
+ if (document.activeElement) {
+ document.activeElement.blur();
+ }
+ this.onItemClickHandler(item);
+ }
+ return;
+ }
if (!this.state.isResultGetted) {
let highlightDom = document.querySelector('.search-types-highlight');
if (highlightDom) {
@@ -206,12 +262,8 @@ class Search extends Component {
};
keepVisitedItem = (targetItem) => {
- const { repoID } = this.props;
let targetIndex;
- let storeKey = 'sfVisitedSearchItems';
- if (repoID) {
- storeKey += repoID;
- }
+ const storeKey = this.storeKey;
const items = JSON.parse(localStorage.getItem(storeKey)) || [];
for (let i = 0, len = items.length; i < len; i++) {
const { repo_id, path } = items[i];
@@ -416,12 +468,7 @@ class Search extends Component {
if (!width || width === 'default') return null;
if (showRecent) {
- const { repoID } = this.props;
- let storeKey = 'sfVisitedSearchItems';
- if (repoID) {
- storeKey += repoID;
- }
- const visitedItems = JSON.parse(localStorage.getItem(storeKey)) || [];
+ const visitedItems = JSON.parse(localStorage.getItem(this.storeKey)) || [];
if (visitedItems.length > 0) {
return this.renderResults(visitedItems, true);
}
@@ -586,7 +633,7 @@ class Search extends Component {
return (
<>
- {results}
+ {results}
{results}