Skip to content

Commit

Permalink
refactor: 구글 지도를 전반적으로 개선한다 (#434)
Browse files Browse the repository at this point in the history
* refactor: 지도의 축소/확대 범위를 제한

[#433]

* refactor: 지도가 어떤 상황에서도 제스처 적용이 가능하도록 설정 수정

[#433]

* refactor: 최초 요청 시, 기본 바운더리가 없어서 생기는 문제를 휴리스틱하게 요청할 수 있도록 개선

- initMarkersEvent 제거

[#433]

* refactor: QUERY_KEY_STATIONS 적용

[#433]

* refactor: msw 모드에서도 줌 레벨 제한 기능 복구 및 랜덤 목데이터 개선

[#433]

* feat: 지도를 너무 축소한 경우 토스트로 알림

[#433]

* feat: 지도 이동 범위 제한

[#433]

* refactor: infoWindow 기본 크기 지정

[#433]

* refactor: infoWindow x버튼 제거

[#433]

* refactor: .map 제거

[#433]

* refactor: 피드백 반영

[#433]
  • Loading branch information
gabrielyoon7 authored Aug 11, 2023
1 parent 1d0f98a commit c7a98b6
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 46 deletions.
19 changes: 9 additions & 10 deletions frontend/src/components/google-maps/map/CarFfeineMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { getGoogleMapStore } from '@stores/google-maps/googleMapStore';
import { toastActions } from '@stores/layout/toastStore';

import { useUserFilters } from '@hooks/tanstack-query/station-filters/useUserFilters';
import { useUpdateStations } from '@hooks/tanstack-query/station-markers/useUpdateStations';

import ToastContainer from '@common/Toast/ToastContainer';

Expand All @@ -20,6 +19,8 @@ import MapController from '@ui/MapController';
import ModalContainer from '@ui/ModalContainer';
import NavigationBar from '@ui/NavigationBar';

import { INITIAL_ZOOM_SIZE } from '@constants/googleMaps';
import { QUERY_KEY_STATIONS } from '@constants/queryKeys';
import { LOCAL_KEY_LAST_POSITION, SESSION_KEY_USER_TOKEN } from '@constants/storageKeys';

const CarFfeineMap = () => {
Expand All @@ -38,26 +39,24 @@ const CarFfeineMap = () => {
};

const CarFfeineMapListener = () => {
const { updateStations } = useUpdateStations();
const googleMap = useExternalValue(getGoogleMapStore());

const queryClient = useQueryClient();

useEffect(() => {
googleMap.addListener('idle', () => {
console.log('idle');
queryClient.invalidateQueries({ queryKey: ['stations'] });
console.log('idle (테스트용: 제거 예정)');

if (googleMap.getZoom() < INITIAL_ZOOM_SIZE) {
toastActions.showToast('지도를 조금만 더 확대해주세요', 'warning', 'bottom-center');
}

queryClient.invalidateQueries({ queryKey: [QUERY_KEY_STATIONS] });
setLocalStorage<google.maps.LatLngLiteral>(LOCAL_KEY_LAST_POSITION, {
lat: googleMap.getCenter().lat(),
lng: googleMap.getCenter().lng(),
});
});

const initMarkersEvent = googleMap.addListener('bounds_changed', async () => {
updateStations();

google.maps.event.removeListener(initMarkersEvent);
});
}, []);

return <></>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Text from '@common/Text';
import { useNavigationBar } from '@ui/compound/NavigationBar/hooks/useNavigationBar';

import type { COMPANY_NAME } from '@constants/chargers';
import { QUERY_KEY_STATIONS } from '@constants/queryKeys';

import type { Capacity } from '@type';

Expand Down Expand Up @@ -44,7 +45,7 @@ const ServerStationFilters = () => {
const { connectorTypes, capacities, companyNames } = serverStationFilters;

const handleApplySelectedFilters = () => {
queryClient.invalidateQueries({ queryKey: ['stations'] });
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_STATIONS] });
showToast('필터가 적용되었습니다');
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { useNavigationBar } from '@ui/compound/NavigationBar/hooks/useNavigation

import { pillStyle } from '@style';

import { QUERY_KEY_STATIONS } from '@constants/queryKeys';

import type { StationPosition } from '@type/stations';

import SearchResult from './SearchResult';
Expand Down Expand Up @@ -60,7 +62,7 @@ const StationSearchBar = () => {

const showStationDetails = ({ stationId, latitude, longitude }: StationPosition) => {
googleMap.panTo({ lat: latitude, lng: longitude });
queryClient.invalidateQueries({ queryKey: ['stations'] });
queryClient.invalidateQueries({ queryKey: [QUERY_KEY_STATIONS] });
setSelectedStationId(stationId);
openLastPanel(<StationDetailsWindow />);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ export const fetchStation = async () => {
const googleMap = getStoreSnapshot(getGoogleMapStore());
const displayPosition = getDisplayPosition(googleMap);

const mswMode = getStoreSnapshot(mswModeStore);

if (!mswMode && displayPosition.zoom < INITIAL_ZOOM_SIZE) {
if (displayPosition.zoom < INITIAL_ZOOM_SIZE) {
return new Promise<StationSummary[]>((resolve) => resolve([]));
}

const displayPositionKey = getTypedObjectKeys<DisplayPosition>(displayPosition);
const displayPositionValue = Object.values(displayPosition).map(String);

const displayPositionString = getTypedObjectFromEntries(displayPositionKey, displayPositionValue);

const requestQueryParams = getQueryFormattedUrl({
Expand Down Expand Up @@ -79,7 +76,9 @@ export const useStations = () => {
const isNoFreeParking = isParkingFreeStationFilterSelected && !isParkingFree;
const isNoPublic = isPrivateStationFilterSelected && isPrivate;

if (isNoAvailable || isNoFastCharge || isNoFreeParking || isNoPublic) return false;
if (isNoAvailable || isNoFastCharge || isNoFreeParking || isNoPublic) {
return false;
}
return true;
});
},
Expand Down

This file was deleted.

34 changes: 24 additions & 10 deletions frontend/src/mocks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,24 @@ export const generateRandomChargers = () => {
return chargers;
};

export const stations: Station[] = Array.from({ length: 3000 }).map((_, index) => {
const generateRandomStationId = () => {
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '0123456789';

const randomChar = (source: string) => source[Math.floor(Math.random() * source.length)];

const randomLetter1 = randomChar(letters);
const randomLetter2 = randomChar(letters);
const randomNumber = Array.from({ length: 6 }, () => randomChar(numbers)).join('');

return `${randomLetter1}${randomLetter2}${randomNumber}`;
};

export const stations: Station[] = Array.from({ length: 3000 }, (_, index) => {
const randomStationId = generateRandomStationId();
return {
stationId: String(index),
stationName: `잠실의 충전소 ${index}`,
stationId: randomStationId,
stationName: `충전소 ${randomStationId}`,
companyName: generateRandomData<CompanyName>(Object.values(COMPANY_NAME)),
contact: generateRandomData(['', '010-1234-5678', '02-000-0000']),
chargers: generateRandomChargers(),
Expand All @@ -56,8 +70,8 @@ export const stations: Station[] = Array.from({ length: 3000 }).map((_, index) =
'null',
]),
detailLocation: generateRandomData<string>(['지상 1층', '지하 1층', '지하 2층', '']),
latitude: 37 + 9999 * Math.random() * 0.0001,
longitude: 127 + 9999 * Math.random() * 0.0001,
latitude: 37 + 0.25 + 9999 * Math.random() * 0.00005,
longitude: 127 - 0.25 + 9999 * Math.random() * 0.00005,
isPrivate: generateRandomData<boolean>([true, false]),
totalCount: generateRandomData<number>([3, 4, 5]),
availableCount: generateRandomData<number>([0, 1, 2, 3]),
Expand Down Expand Up @@ -96,9 +110,9 @@ const getCongestions = (): Record<EnglishDaysType, Congestion[]> => {
return getTypedObjectFromEntries(
ENGLISH_DAYS,
ENGLISH_DAYS.map(() =>
Array.from({ length: 24 }).map((_, i) => {
Array.from({ length: 24 }, (_, index) => {
return {
hour: i,
hour: index,
ratio: Math.floor(Math.random() * 102 - 1),
};
})
Expand All @@ -107,9 +121,9 @@ const getCongestions = (): Record<EnglishDaysType, Congestion[]> => {
};

export const generateReviewsWithReplies = (): Review[] => {
return Array.from({ length: 10 }, (_, i) => {
return Array.from({ length: 10 }, (_, index) => {
return {
reviewId: i,
reviewId: index,
userId: generateRandomToken(),
latestUpdateDate: getRandomTime(),
ratings: parseFloat((Math.random() * 5).toFixed(2)),
Expand All @@ -125,7 +139,7 @@ export const generateReviewsWithReplies = (): Review[] => {
]),
isUpdated: generateRandomData([true, false]),
isDeleted: generateRandomData([true, false]),
replies: Array.from({ length: generateRandomCommentsLength(0, 4) }, (_, i) => {
replies: Array.from({ length: generateRandomCommentsLength(0, 4) }, (_, index) => {
return {
replyId: generateRandomToken(),
userId: generateRandomToken(),
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/stores/google-maps/googleMapStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export const getGoogleMapStore = (() => {
zoom: INITIAL_ZOOM_SIZE,
disableDefaultUI: true,
mapId: '92cb7201b7d43b21',
minZoom: 8,
maxZoom: 20,
gestureHandling: 'greedy',
restriction: {
latLngBounds: {
north: 39,
south: 33,
east: 132,
west: 124,
},
strictBounds: true,
},
});
}

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/stores/google-maps/stationSummaryWindowStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const getStationSummaryWindowStore = (() => {
const stationSummaryRoot = createRoot(container);
const infoWindowInstance = new google.maps.InfoWindow({
content: container,
maxWidth: 320,
minWidth: 320,
});

const initialStationSummaryWindow = {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/style/GlobalStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ export const GlobalStyle = createGlobalStyle`
body:has(.modal-open) {
overflow: hidden;
}
button.gm-ui-hover-effect {
visibility: hidden;
}
`;
4 changes: 2 additions & 2 deletions frontend/src/utils/google-maps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export const getDisplayPosition = (map: google.maps.Map) => {

const longitudeDelta = bounds
? (bounds.getNorthEast().lng() - bounds.getSouthWest().lng()) / 2
: 0;
: 0.15;
const latitudeDelta = bounds
? (bounds.getNorthEast().lat() - bounds.getSouthWest().lat()) / 2
: 0;
: 0.15;
const longitude = center.lng();
const latitude = center.lat();
const zoom = map.getZoom();
Expand Down

0 comments on commit c7a98b6

Please sign in to comment.