Skip to content

Commit

Permalink
Create a composable for map utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
spider-hand committed Jun 30, 2023
1 parent 285ed08 commit d3333ab
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 87 deletions.
68 changes: 68 additions & 0 deletions src/__tests__/unit/composables/game/map.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { ref } from "vue";
import { describe, expect, test, vi } from "vitest";
import { useMap } from "../../../../composables/game/map";
import * as GoogleMaps from "@googlemaps/js-api-loader";

vi.spyOn(GoogleMaps, "Loader").mockImplementation(() => {
return {
importLibrary: () =>
vi.fn().mockResolvedValue(() => {
return {
Map: vi.fn(),
};
}),
} as any;
});

describe("map", async () => {
const loader = new GoogleMaps.Loader({
apiKey: "",
version: "weekly",
});
const { Map } = await loader.importLibrary("maps");
const mapRef = ref<HTMLElement>();

test("putMarker puts a marker", () => {
const { markers, putMarker } = useMap(Map, mapRef);
const latLng = new google.maps.LatLng(1, 1);
putMarker(latLng);

expect(markers.value.length).toBe(1);
});

test("removeMarkers removes markers", () => {
const { markers, putMarker, removeMarkers } = useMap(Map, mapRef);
const latLng = new google.maps.LatLng(1, 1);
putMarker(latLng);
putMarker(latLng);

expect(markers.value.length).toBe(2);

removeMarkers();

expect(markers.value.length).toBe(0);
});

test("drawPolyline draws a polyline", () => {
const { polylines, drawPolyline } = useMap(Map, mapRef);
const from = new google.maps.LatLng(1, 1);
const to = new google.maps.LatLng(1, 1);
drawPolyline(from, to);

expect(polylines.value.length).toBe(1);
});

test("removePolyline removes polylines", () => {
const { polylines, drawPolyline, removePolyline } = useMap(Map, mapRef);
const from = new google.maps.LatLng(1, 1);
const to = new google.maps.LatLng(1, 1);
drawPolyline(from, to);
drawPolyline(from, to);

expect(polylines.value.length).toBe(2);

removePolyline();

expect(polylines.value.length).toBe(0);
});
});
5 changes: 5 additions & 0 deletions src/__tests__/unit/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ global.google = {
setMap: vi.fn(),
};
}),
Polyline: vi.fn().mockImplementation(() => {
return {
setMap: vi.fn(),
};
}),
LatLng: vi.fn().mockImplementation(() => {
return {};
}),
Expand Down
38 changes: 5 additions & 33 deletions src/components/game/MyMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
</template>

<script setup lang="ts">
import { onMounted, ref, watch, PropType } from "vue";
import { ref, watch, PropType } from "vue";
import { DEVICE_TYPES } from "@/constants";
import IconButton from "@/components/shared/IconButton.vue";
import { DeviceTypes, ModeTypes } from "@/types";
import { Loader } from "@googlemaps/js-api-loader";
import { useMap } from "@/composables/game/map";
const props = defineProps({
device: {
Expand Down Expand Up @@ -62,10 +63,8 @@ const loader = new Loader({
version: "weekly",
});
const { Map } = await loader.importLibrary("maps");
let map: google.maps.Map;
const mapRef = ref<HTMLElement>();
const markers: google.maps.Marker[] = [];
const { map, removeMarkers, putMarker } = useMap(Map, mapRef);
watch(
() => props.isMakeGuessButtonClicked,
Expand All @@ -90,42 +89,15 @@ watch(
watch(
() => props.randomLatLng,
(newVal: google.maps.LatLng | null) => {
if (newVal !== null) {
map.addListener("click", (e: google.maps.MapMouseEvent) => {
if (newVal !== null && map.value !== undefined) {
map.value.addListener("click", (e: google.maps.MapMouseEvent) => {
removeMarkers();
putMarker(e.latLng as google.maps.LatLng);
emit("updateSelectedLatLng", e.latLng as google.maps.LatLng);
});
}
}
);
const removeMarkers = (): void => {
markers.forEach((marker, index) => {
marker.setMap(null);
markers.splice(index, 1);
});
};
const putMarker = (position: google.maps.LatLng): void => {
const marker = new google.maps.Marker({
position: position,
map: map,
});
markers.push(marker);
};
onMounted(() => {
if (mapRef.value) {
map = new Map(mapRef.value as HTMLElement, {
center: { lat: 37.86926, lng: -122.254811 },
zoom: 1,
fullscreenControl: false,
mapTypeControl: false,
streetViewControl: false,
});
}
});
</script>

<style module lang="scss">
Expand Down
59 changes: 5 additions & 54 deletions src/components/game/ResultModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"
>
<div
ref="resultMapRef"
ref="mapRef"
:class="$style['result-modal__map']"
/>
<IconButton
Expand Down Expand Up @@ -98,10 +98,11 @@

<script setup lang="ts">
import { GameHistory, Summary, DistanceByPlayer, ModeTypes } from "@/types";
import { watch, onMounted, ref, PropType, computed, reactive } from "vue";
import { watch, ref, PropType, computed, reactive } from "vue";
import FlatButton from "@/components/shared/FlatButton.vue";
import IconButton from "@/components/shared/IconButton.vue";
import { Loader } from "@googlemaps/js-api-loader";
import { useMap } from "@/composables/game/map";
const props = defineProps({
selectedMode: {
Expand Down Expand Up @@ -177,11 +178,8 @@ const loader = new Loader({
version: "weekly",
});
const { Map } = await loader.importLibrary("maps");
let map: google.maps.Map;
const resultMapRef = ref<HTMLElement>();
let markers: google.maps.Marker[] = [];
let polylines: google.maps.Polyline[] = [];
const mapRef = ref<HTMLElement>();
const { removeMarkers, putMarker, drawPolyline, removePolyline } = useMap(Map, mapRef);
const state = reactive<{ isMapExpanding: boolean }>({
isMapExpanding: false,
Expand Down Expand Up @@ -225,40 +223,6 @@ watch(
}
);
const putMarker = (position: google.maps.LatLng): void => {
const marker = new google.maps.Marker({
position: position,
map: map,
});
markers.push(marker);
};
const removeMarkers = (): void => {
markers.forEach((marker) => {
marker.setMap(null);
});
markers = [];
};
const drawPolyline = (
from: google.maps.LatLng,
to: google.maps.LatLng
): void => {
const polyline = new google.maps.Polyline({
path: [from, to],
strokeColor: "hsl(0, 100%, 63%)",
});
polyline.setMap(map);
polylines.push(polyline);
};
const removePolyline = (): void => {
polylines.forEach((line) => {
line.setMap(null);
});
polylines = [];
};
const onClickViewSummaryButton = (): void => {
emit("onClickViewSummaryButton");
(props.gameHistory as Array<GameHistory>).forEach((e: GameHistory) => {
Expand All @@ -267,19 +231,6 @@ const onClickViewSummaryButton = (): void => {
drawPolyline(e.randomLatLng, e.selectedLatLng);
});
};
onMounted(() => {
if (resultMapRef.value) {
map = new Map(resultMapRef.value as HTMLElement, {
center: { lat: 37.86926, lng: -122.254811 },
zoom: 2,
fullscreenControl: false,
mapTypeControl: false,
streetViewControl: false,
zoomControl: false,
});
}
});
</script>

<style module lang="scss">
Expand Down
66 changes: 66 additions & 0 deletions src/composables/game/map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Ref, onMounted, shallowRef } from "vue";

export const useMap = (
Map: typeof google.maps.Map,
mapRef: Ref<HTMLElement | undefined>
) => {
const map = shallowRef<google.maps.Map>();
const markers = shallowRef<google.maps.Marker[]>([]);
const polylines = shallowRef<google.maps.Polyline[]>([]);

const removeMarkers = (): void => {
markers.value.forEach((marker) => {
marker.setMap(null);
});
markers.value.splice(0);
};

const putMarker = (position: google.maps.LatLng): void => {
const marker = new google.maps.Marker({
position: position,
map: map.value,
});
markers.value.push(marker);
};

const drawPolyline = (
from: google.maps.LatLng,
to: google.maps.LatLng
): void => {
const polyline = new google.maps.Polyline({
path: [from, to],
strokeColor: "hsl(0, 100%, 63%)",
});
polyline.setMap(map.value as google.maps.Map);
polylines.value.push(polyline);
};

const removePolyline = (): void => {
polylines.value.forEach((line) => {
line.setMap(null);
});
polylines.value = [];
};

onMounted(() => {
if (mapRef.value) {
map.value = new Map(mapRef.value as HTMLElement, {
center: { lat: 37.86926, lng: -122.254811 },
zoom: 1,
fullscreenControl: false,
mapTypeControl: false,
streetViewControl: false,
});
}
});

return {
map,
markers,
polylines,
removeMarkers,
putMarker,
drawPolyline,
removePolyline,
};
};

0 comments on commit d3333ab

Please sign in to comment.