@@ -13,7 +13,13 @@ import {
1313 type MenuSelectionDetails ,
1414} from "@chakra-ui/react" ;
1515import { LngLatBounds } from "maplibre-gl" ;
16- import { useEffect , useState , type Dispatch , type SetStateAction } from "react" ;
16+ import {
17+ useEffect ,
18+ useRef ,
19+ useState ,
20+ type Dispatch ,
21+ type SetStateAction ,
22+ } from "react" ;
1723import { LuSearch } from "react-icons/lu" ;
1824import type { StacCollection , StacItem , StacLink } from "stac-ts" ;
1925import { useMap } from "../map/context" ;
@@ -233,7 +239,11 @@ function SearchResults({
233239 link : StacLink ;
234240 setPicked : Dispatch < SetStateAction < StacValue | undefined > > ;
235241} ) {
236- const { items, loading, error } = useStacSearch ( { collections, bbox, link } ) ;
242+ const { items, error, loading, cancel } = useStacSearch ( {
243+ collections,
244+ bbox,
245+ link,
246+ } ) ;
237247 const [ itemCollection , setItemCollection ] = useState <
238248 StacItemCollection | undefined
239249 > ( ) ;
@@ -259,18 +269,24 @@ function SearchResults({
259269 }
260270 } , [ items , setItemCollection ] ) ;
261271
262- if ( itemCollection ) {
263- return (
264- < ItemCollection
265- itemCollection = { itemCollection }
266- setPicked = { setPicked }
267- > </ ItemCollection >
268- ) ;
269- } else if ( loading ) {
270- return < Skeleton h = { 200 } > </ Skeleton > ;
271- } else {
272- return < > </ > ;
273- }
272+ return (
273+ < Stack >
274+ { loading && (
275+ < HStack >
276+ < Button colorPalette = { "red" } onClick = { ( ) => ( cancel . current = true ) } >
277+ Abort
278+ </ Button >
279+ </ HStack >
280+ ) }
281+ { ( itemCollection && (
282+ < ItemCollection
283+ itemCollection = { itemCollection }
284+ setPicked = { setPicked }
285+ > </ ItemCollection >
286+ ) ) ||
287+ ( loading && < Skeleton h = { 200 } > </ Skeleton > ) }
288+ </ Stack >
289+ ) ;
274290}
275291
276292function useStacSearch ( {
@@ -285,6 +301,7 @@ function useStacSearch({
285301 const [ loading , setLoading ] = useState ( false ) ;
286302 const [ error , setError ] = useState < string | undefined > ( ) ;
287303 const [ items , setItems ] = useState < StacItem [ ] | undefined > ( [ ] ) ;
304+ const cancel = useRef ( false ) ;
288305
289306 useEffect ( ( ) => {
290307 ( async ( ) => {
@@ -300,6 +317,9 @@ function useStacSearch({
300317 url . searchParams . set ( "bbox" , bbox . join ( "," ) ) ;
301318 }
302319 while ( true ) {
320+ if ( cancel . current ) {
321+ break ;
322+ }
303323 const response = await fetch ( url ) ;
304324 if ( response . ok ) {
305325 const data : StacItemCollection = await response . json ( ) ;
@@ -328,11 +348,12 @@ function useStacSearch({
328348 }
329349 }
330350 }
351+ cancel . current = false ;
331352 setLoading ( false ) ;
332353 } ) ( ) ;
333- } , [ collections , bbox , link ] ) ;
354+ } , [ bbox , collections , link . href , link . type ] ) ;
334355
335- return { loading, error, items } ;
356+ return { loading, error, items, cancel } ;
336357}
337358
338359function isCollectionWithinBounds (
0 commit comments