« get me outta code hell

client: save & restore search results scroll offset - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-05-31 19:14:41 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-05-31 19:14:41 -0300
commit2d78de1bed2864e5496068e9466f2359c86d5194 (patch)
tree194c9ca71d17ef42b783982b1aad1989be4dbd3a
parentbd852b8553cc1fce355ece45b5c6dc77d659ee97 (diff)
client: save & restore search results scroll offset
-rw-r--r--src/static/js/client.js43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/static/js/client.js b/src/static/js/client.js
index 587c2582..b7b19d7f 100644
--- a/src/static/js/client.js
+++ b/src/static/js/client.js
@@ -3800,6 +3800,7 @@ const sidebarSearchInfo = initInfo('sidebarSearchInfo', {
     searchStage: null,
 
     stoppedTypingTimeout: null,
+    stoppedScrollingTimeout: null,
 
     indexDownloadStatuses: Object.create(null),
   },
@@ -3818,10 +3819,15 @@ const sidebarSearchInfo = initInfo('sidebarSearchInfo', {
       type: 'boolean',
       default: false,
     },
+
+    resultsScrollOffset: {
+      type: 'number',
+    },
   },
 
   settings: {
     stoppedTypingDelay: 800,
+    stoppedScrollingDelay: 200,
 
     maxActiveResultsStorage: 100000,
   },
@@ -4056,6 +4062,19 @@ function addSidebarSearchListeners() {
     possiblyHideSearchSidebarColumn();
     restoreSidebarSearchColumn();
   });
+
+  info.resultsContainer.addEventListener('scroll', () => {
+    const {settings, state} = info;
+
+    if (state.stoppedScrollingTimeout) {
+      clearTimeout(state.stoppedScrollingTimeout);
+    }
+
+    state.stoppedScrollingTimeout =
+      setTimeout(() => {
+        saveSidebarSearchResultsScrollOffset();
+      }, settings.stoppedScrollingDelay);
+  });
 }
 
 function initializeSidebarSearchState() {
@@ -4155,6 +4174,7 @@ async function activateSidebarSearch(query) {
 
   session.activeQuery = query;
   session.activeQueryResults = results;
+  session.resultsScrollOffset = 0;
 
   showSidebarSearchResults(results);
 }
@@ -4177,6 +4197,7 @@ function clearSidebarSearch() {
 
   session.activeQuery = null;
   session.activeQueryResults = null;
+  session.resultsScrollOffset = null;
 
   hideSidebarSearchResults();
 }
@@ -4320,6 +4341,8 @@ function showSidebarSearchResults(results) {
 
     tidySidebarSearchColumn();
   }
+
+  restoreSidebarSearchResultsScrollOffset();
 }
 
 function generateSidebarSearchResult(result) {
@@ -4475,6 +4498,10 @@ function generateSidebarSearchResultTemplate(slots) {
 
   link.appendChild(text);
 
+  link.addEventListener('click', () => {
+    saveSidebarSearchResultsScrollOffset();
+  });
+
   return link;
 }
 
@@ -4492,6 +4519,22 @@ function hideSidebarSearchResults() {
   cssProp(info.endSearchLine, 'display', 'none');
 }
 
+function saveSidebarSearchResultsScrollOffset() {
+  const info = sidebarSearchInfo;
+  const {session} = info;
+
+  session.resultsScrollOffset = info.resultsContainer.scrollTop;
+}
+
+function restoreSidebarSearchResultsScrollOffset() {
+  const info = sidebarSearchInfo;
+  const {session} = info;
+
+  if (session.resultsScrollOffset) {
+    info.resultsContainer.scrollTop = session.resultsScrollOffset;
+  }
+}
+
 function showSearchSidebarColumn() {
   const info = sidebarSearchInfo;
   const {state} = info;