Skip to content

Commit

Permalink
fix(appbar): Fix the geolocator language and map interactoin wwhen ap… (
Browse files Browse the repository at this point in the history
Canadian-Geospatial-Platform#2566)

* fix(appbar): Fix the geolocator language and map interactoin wwhen app bar panel open
Closes Canadian-Geospatial-Platform#2561, Canadian-Geospatial-Platform#2545

* fix comment
  • Loading branch information
jolevesq authored Oct 25, 2024
1 parent 4bfd792 commit d55a8d9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 36 deletions.
81 changes: 46 additions & 35 deletions packages/geoview-core/src/core/components/geolocator/geolocator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useTheme } from '@mui/material';
import { CloseIcon, SearchIcon, AppBarUI, Box, Divider, IconButton, ProgressBar, Toolbar } from '@/ui';
import { StyledInputField, sxClasses } from './geolocator-style';
import { OL_ZOOM_DURATION } from '@/core/utils/constant';
import { useActiveAppBarTab, useUIStoreActions } from '@/core/stores/store-interface-and-intial-values/ui-state';
import { useActiveAppBarTab, useUIActiveTrapGeoView, useUIStoreActions } from '@/core/stores/store-interface-and-intial-values/ui-state';
import { useAppGeolocatorServiceURL, useAppDisplayLanguage } from '@/core/stores/store-interface-and-intial-values/app-state';
import { GeolocatorResult } from './geolocator-result';
import { logger } from '@/core/utils/logger';
Expand Down Expand Up @@ -43,10 +43,10 @@ export function Geolocator(): JSX.Element {
const displayLanguage = useAppDisplayLanguage();
const geolocatorServiceURL = useAppGeolocatorServiceURL();
const { setActiveAppBarTab } = useUIStoreActions();

const { tabGroup, isOpen } = useActiveAppBarTab();
const activeTrapGeoView = useUIActiveTrapGeoView();

const urlRef = useRef<string>(`${geolocatorServiceURL}&lang=${displayLanguage}`);
const displayLanguageRef = useRef(displayLanguage);
const geolocatorRef = useRef<HTMLDivElement>();
const abortControllerRef = useRef<AbortController | null>(null);
const fetchTimerRef = useRef<NodeJS.Timeout | undefined>();
Expand Down Expand Up @@ -92,41 +92,47 @@ export function Geolocator(): JSX.Element {
* @param {string} searchTerm the search term entered by the user
* @returns {Promise<void>}
*/
const getGeolocations = async (searchTerm: string): Promise<void> => {
try {
setIsLoading(true);
// Abort any pending requests
if (abortControllerRef.current) {
abortControllerRef.current.abort();
clearTimeout(fetchTimerRef.current);
}
const getGeolocations = useCallback(
async (searchTerm: string): Promise<void> => {
try {
setIsLoading(true);
// Abort any pending requests
if (abortControllerRef.current) {
abortControllerRef.current.abort();
clearTimeout(fetchTimerRef.current);
}

// Create new abort controller
const newAbortController = new AbortController();
abortControllerRef.current = newAbortController;
// Create new abort controller
const newAbortController = new AbortController();
abortControllerRef.current = newAbortController;

const response = await fetch(`${urlRef.current}&q=${encodeURIComponent(`${searchTerm}*`)}`, {
signal: abortControllerRef.current.signal,
});
if (!response.ok) {
throw new Error('Error');
}
const result = (await response.json()) as GeoListItem[];
const ddSupport = getDecimalDegreeItem(searchTerm);
// Use the current value from the ref
const currentUrl = `${geolocatorServiceURL}&lang=${displayLanguageRef.current}`;

if (ddSupport) {
// insert at the top of array.
result.unshift(ddSupport);
}
const response = await fetch(`${currentUrl}&q=${encodeURIComponent(`${searchTerm}*`)}`, {
signal: abortControllerRef.current.signal,
});
if (!response.ok) {
throw new Error('Error');
}
const result = (await response.json()) as GeoListItem[];
const ddSupport = getDecimalDegreeItem(searchTerm);

setData(result);
setError(null);
setIsLoading(false);
clearTimeout(fetchTimerRef?.current);
} catch (err) {
setError(err as Error);
}
};
if (ddSupport) {
// insert at the top of array.
result.unshift(ddSupport);
}

setData(result);
setError(null);
setIsLoading(false);
clearTimeout(fetchTimerRef?.current);
} catch (err) {
setError(err as Error);
}
},
[geolocatorServiceURL]
);

/**
* Reset loading and data state and clear fetch timer.
Expand Down Expand Up @@ -249,8 +255,13 @@ export function Geolocator(): JSX.Element {
};
}, [isLoading]);

// Update the ref whenever displayLanguage changes
useEffect(() => {
displayLanguageRef.current = displayLanguage;
}, [displayLanguage]);

return (
<FocusTrapContainer open={tabGroup === CV_DEFAULT_APPBAR_CORE.GEOLOCATOR && isOpen} id="geolocator-focus-trap">
<FocusTrapContainer open={tabGroup === CV_DEFAULT_APPBAR_CORE.GEOLOCATOR && isOpen && activeTrapGeoView} id="geolocator-focus-trap">
<Box
sx={sxClasses.root}
visibility={tabGroup === CV_DEFAULT_APPBAR_CORE.GEOLOCATOR && isOpen ? 'visible' : 'hidden'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,20 @@ export function initializeUIState(set: TypeSetStore, get: TypeGetStore): IUIStat
});
},
setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean, isFocusTrapped: boolean = false) => {
// Gv Side effect with focus trap and side panel app bar open
// We need to check if the viewer is in keyboard navigation mode. If not, we do nt apply the focus trap.
// Focus trap has side effect when a app bar panel is open. It does not let user use their mouse
// to pan the map. Even scroll is difficult, user needs to click outside the brower then come back for
// the mouse wheel to work
const isFocusTrappedAndKeyboardNavigation = get().uiState.activeTrapGeoView ? isFocusTrapped : false;
set({
uiState: {
...get().uiState,
activeAppBarTab: {
tabId,
tabGroup,
isOpen,
isFocusTrapped,
isFocusTrapped: isFocusTrappedAndKeyboardNavigation,
},
},
});
Expand Down

0 comments on commit d55a8d9

Please sign in to comment.