mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05:00 
			
		
		
		
	fix(web): add debounce to location search (#9074)
This commit is contained in:
		
							parent
							
								
									f1083a4c73
								
							
						
					
					
						commit
						59537f8f1b
					
				@ -1,7 +1,7 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  import { createEventDispatcher } from 'svelte';
 | 
					  import { createEventDispatcher } from 'svelte';
 | 
				
			||||||
  import ConfirmDialogue from './confirm-dialogue.svelte';
 | 
					  import ConfirmDialogue from './confirm-dialogue.svelte';
 | 
				
			||||||
  import { timeBeforeShowLoadingSpinner } from '$lib/constants';
 | 
					  import { timeDebounceOnSearch } from '$lib/constants';
 | 
				
			||||||
  import { handleError } from '$lib/utils/handle-error';
 | 
					  import { handleError } from '$lib/utils/handle-error';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  import { clickOutside } from '$lib/utils/click-outside';
 | 
					  import { clickOutside } from '$lib/utils/click-outside';
 | 
				
			||||||
@ -22,7 +22,7 @@
 | 
				
			|||||||
  let places: PlacesResponseDto[] = [];
 | 
					  let places: PlacesResponseDto[] = [];
 | 
				
			||||||
  let suggestedPlaces: PlacesResponseDto[] = [];
 | 
					  let suggestedPlaces: PlacesResponseDto[] = [];
 | 
				
			||||||
  let searchWord: string;
 | 
					  let searchWord: string;
 | 
				
			||||||
  let isSearching = false;
 | 
					  let latestSearchTimeout: number;
 | 
				
			||||||
  let showSpinner = false;
 | 
					  let showSpinner = false;
 | 
				
			||||||
  let suggestionContainer: HTMLDivElement;
 | 
					  let suggestionContainer: HTMLDivElement;
 | 
				
			||||||
  let hideSuggestion = false;
 | 
					  let hideSuggestion = false;
 | 
				
			||||||
@ -66,24 +66,34 @@
 | 
				
			|||||||
    return `${name}${admin1Name ? ', ' + admin1Name : ''}${admin2Name ? ', ' + admin2Name : ''}`;
 | 
					    return `${name}${admin1Name ? ', ' + admin1Name : ''}${admin2Name ? ', ' + admin2Name : ''}`;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleSearchPlaces = async () => {
 | 
					  const handleSearchPlaces = () => {
 | 
				
			||||||
    if (searchWord === '' || isSearching) {
 | 
					    if (searchWord === '') {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: refactor setTimeout/clearTimeout logic - there are no less than 12 places that duplicate this code
 | 
					    if (latestSearchTimeout) {
 | 
				
			||||||
    isSearching = true;
 | 
					      clearTimeout(latestSearchTimeout);
 | 
				
			||||||
    const timeout = setTimeout(() => (showSpinner = true), timeBeforeShowLoadingSpinner);
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      places = await searchPlaces({ name: searchWord });
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
      places = [];
 | 
					 | 
				
			||||||
      handleError(error, "Can't search places");
 | 
					 | 
				
			||||||
    } finally {
 | 
					 | 
				
			||||||
      clearTimeout(timeout);
 | 
					 | 
				
			||||||
      isSearching = false;
 | 
					 | 
				
			||||||
      showSpinner = false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    showSpinner = true;
 | 
				
			||||||
 | 
					    const searchTimeout = window.setTimeout(() => {
 | 
				
			||||||
 | 
					      searchPlaces({ name: searchWord })
 | 
				
			||||||
 | 
					        .then((searchResult) => {
 | 
				
			||||||
 | 
					          // skip result when a newer search is happening
 | 
				
			||||||
 | 
					          if (latestSearchTimeout === searchTimeout) {
 | 
				
			||||||
 | 
					            places = searchResult;
 | 
				
			||||||
 | 
					            showSpinner = false;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch((error) => {
 | 
				
			||||||
 | 
					          // skip error when a newer search is happening
 | 
				
			||||||
 | 
					          if (latestSearchTimeout === searchTimeout) {
 | 
				
			||||||
 | 
					            places = [];
 | 
				
			||||||
 | 
					            handleError(error, "Can't search places");
 | 
				
			||||||
 | 
					            showSpinner = false;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }, timeDebounceOnSearch);
 | 
				
			||||||
 | 
					    latestSearchTimeout = searchTimeout;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleUseSuggested = (latitude: number, longitude: number) => {
 | 
					  const handleUseSuggested = (latitude: number, longitude: number) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -91,6 +91,8 @@ export const timeToLoadTheMap: number = 100;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const timeBeforeShowLoadingSpinner: number = 100;
 | 
					export const timeBeforeShowLoadingSpinner: number = 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const timeDebounceOnSearch: number = 300;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// should be the same values as the ones in the app.html
 | 
					// should be the same values as the ones in the app.html
 | 
				
			||||||
export enum Theme {
 | 
					export enum Theme {
 | 
				
			||||||
  LIGHT = 'light',
 | 
					  LIGHT = 'light',
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user