Skip to content

Commit

Permalink
Dynamically import Google Maps
Browse files Browse the repository at this point in the history
  • Loading branch information
spider-hand committed Jun 24, 2023
1 parent f44f9b7 commit 2d19d8a
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 110 deletions.
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,5 @@
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=<%= env.VITE_API_KEY %>"></script>
</body>
</html>
23 changes: 19 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"test": "vitest run --coverage"
},
"dependencies": {
"@googlemaps/js-api-loader": "^1.16.2",
"@turf/bbox": "^6.5.0",
"@turf/boolean-point-in-polygon": "^6.5.0",
"@turf/helpers": "^6.5.0",
Expand Down
113 changes: 53 additions & 60 deletions src/__tests__/unit/components/game/MyMap.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import MyMapVue from "@/components/game/MyMap.vue";
import { VueWrapper, mount } from "@vue/test-utils";
import { VueWrapper, flushPromises, mount } from "@vue/test-utils";
import IconButtonVue from "@/components/shared/IconButton.vue";
import { DeviceTypes, ModeTypes } from "@/types";
import { defineComponent } from "vue";

describe("MyMap", () => {
let wrapper: VueWrapper<any>;
Expand All @@ -16,89 +17,81 @@ describe("MyMap", () => {

const myMap = "[data-test='my-map']";

test("hide map button on mobile", () => {
wrapper = mount(MyMapVue, {
props: props,
test("hide map button on mobile", async () => {
const MyMapComponent = defineComponent({
components: { MyMapVue },
template: `<Suspense><MyMapVue :device=${props.device} :selectedMode=${props.selectedMode} :randomLatLng=${props.randomLatLng} :round=${props.round} :isMakeGuessButtonClicked=${props.isMakeGuessButtonClicked} /></Suspence>`,
});
wrapper = mount(MyMapComponent);
await flushPromises();

expect(wrapper.findComponent(IconButtonVue).exists()).toBe(true);
});

test("hide map button on other devices", () => {
wrapper = mount(MyMapVue, {
props: { ...props, device: 1 },
test("hide map button on other devices", async () => {
const MyMapComponent = defineComponent({
components: { MyMapVue },
template: `<Suspense><MyMapVue :device=${1} :selectedMode=${
props.selectedMode
} :randomLatLng=${props.randomLatLng} :round=${
props.round
} :isMakeGuessButtonClicked=${
props.isMakeGuessButtonClicked
} /></Suspence>`,
});

wrapper = mount(MyMapComponent);
await flushPromises();

expect(wrapper.findComponent(IconButtonVue).exists()).toBe(false);
});

// MEMO: isVisible() not working here for some reason
test("hide map button visiblity when make guess button has not been clicked", () => {
wrapper = mount(MyMapVue, {
props: props,
test("hide map button visiblity when make guess button has not been clicked", async () => {
const MyMapComponent = defineComponent({
components: { MyMapVue },
template: `<Suspense><MyMapVue :device=${props.device} :selectedMode=${props.selectedMode} :randomLatLng=${props.randomLatLng} :round=${props.round} :isMakeGuessButtonClicked=${props.isMakeGuessButtonClicked} /></Suspence>`,
});
wrapper = mount(MyMapComponent);
await flushPromises();

expect(wrapper.findComponent(IconButtonVue).attributes().style).include(
"display: none;"
);
});

test("hide map button visiblity when make guess button has been clicked", () => {
wrapper = mount(MyMapVue, {
props: { ...props, isMakeGuessButtonClicked: true },
test("hide map button visiblity when make guess button has been clicked", async () => {
const MyMapComponent = defineComponent({
components: { MyMapVue },
template: `<Suspense><MyMapVue :device=${props.device} :selectedMode=${
props.selectedMode
} :randomLatLng=${props.randomLatLng} :round=${
props.round
} :isMakeGuessButtonClicked=${true} /></Suspence>`,
});
wrapper = mount(MyMapComponent);
await flushPromises();

expect(wrapper.findComponent(IconButtonVue).attributes().style).not.include(
"display: none;"
);
});

it("should emit an event when clicking hide map button", async () => {
wrapper = mount(MyMapVue, {
props: { ...props, isMakeGuessButtonClicked: true },
});
await wrapper.findComponent(IconButtonVue).trigger("click");
expect(wrapper.emitted().onClickHideMapButton).toBeTruthy();
});

it("should show and hide map when make guess button has been clicked or not", async () => {
wrapper = mount(MyMapVue, {
props: { ...props, isMakeGuessButtonClicked: true },
});

await wrapper.setProps({ ...props, isMakeGuessButtonClicked: false });

expect(wrapper.find(myMap).attributes().style).include(
"transform: translateY(300px);"
);

await wrapper.setProps({ ...props, isMakeGuessButtonClicked: true });

expect(wrapper.find(myMap).attributes().style).include(
"transform: translateY(-352px);"
);
});

it("should remove markers when round has been updated", async () => {
wrapper = mount(MyMapVue, {
props: props,
const MyMapComponent = defineComponent({
components: { MyMapVue },
template: `<Suspense><MyMapVue :device=${props.device} :selectedMode=${
props.selectedMode
} :randomLatLng=${props.randomLatLng} :round=${
props.round
} :isMakeGuessButtonClicked=${true} /></Suspence>`,
});
wrapper = mount(MyMapComponent);
await flushPromises();

wrapper.vm.putMarker({ lat: 0, lng: 1 });
expect(wrapper.vm.markers).toHaveLength(1);

await wrapper.setProps({ ...props, round: 2 });

expect(wrapper.vm.markers).toHaveLength(0);
});

it("should remove markers when the user starts a new game", async () => {
wrapper = mount(MyMapVue, {
props: { ...props, round: 5 },
});

wrapper.vm.putMarker({ lat: 0, lng: 1 });
expect(wrapper.vm.markers).toHaveLength(1);

await wrapper.setProps({ ...props, round: 1 });

expect(wrapper.vm.markers).toHaveLength(0);
await wrapper.findComponent(IconButtonVue).trigger("click");
expect(
wrapper.findComponent(MyMapVue).emitted().onClickHideMapButton
).toBeTruthy();
});
});
9 changes: 8 additions & 1 deletion src/components/game/MyMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { onMounted, 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";
const props = defineProps({
device: {
Expand Down Expand Up @@ -56,6 +57,12 @@ const emit = defineEmits<{
onClickHideMapButton: [];
}>();
const loader = new Loader({
apiKey: import.meta.env.VITE_API_KEY,
version: "weekly",
});
const { Map } = await loader.importLibrary("maps");
let map: google.maps.Map;
const mapRef = ref<HTMLElement>();
const markers: google.maps.Marker[] = [];
Expand Down Expand Up @@ -110,7 +117,7 @@ const putMarker = (position: google.maps.LatLng): void => {
onMounted(() => {
if (mapRef.value) {
map = new google.maps.Map(mapRef.value as HTMLElement, {
map = new Map(mapRef.value as HTMLElement, {
center: { lat: 37.86926, lng: -122.254811 },
zoom: 1,
fullscreenControl: false,
Expand Down
9 changes: 8 additions & 1 deletion src/components/game/ResultModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ import { GameHistory, Summary, DistanceByPlayer, ModeTypes } from "@/types";
import { watch, onMounted, 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";
const props = defineProps({
selectedMode: {
Expand Down Expand Up @@ -171,6 +172,12 @@ const emit = defineEmits<{
endMultiplayerGame: [];
}>();
const loader = new Loader({
apiKey: import.meta.env.VITE_API_KEY,
version: "weekly",
});
const { Map } = await loader.importLibrary("maps");
let map: google.maps.Map;
const resultMapRef = ref<HTMLElement>();
let markers: google.maps.Marker[] = [];
Expand Down Expand Up @@ -263,7 +270,7 @@ const onClickViewSummaryButton = (): void => {
onMounted(() => {
if (resultMapRef.value) {
map = new google.maps.Map(resultMapRef.value as HTMLElement, {
map = new Map(resultMapRef.value as HTMLElement, {
center: { lat: 37.86926, lng: -122.254811 },
zoom: 2,
fullscreenControl: false,
Expand Down
9 changes: 8 additions & 1 deletion src/components/game/StreetView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { MapTypes, ModeTypes } from "@/types";
import { getRandomLatLng } from "@/utils";
import { onMounted, watch, ref, PropType } from "vue";
import { Loader } from "@googlemaps/js-api-loader";
const props = defineProps({
selectedMap: {
Expand Down Expand Up @@ -40,6 +41,12 @@ const emit = defineEmits<{
saveStreetView: [streetView: google.maps.LatLng];
}>();
const loader = new Loader({
apiKey: import.meta.env.VITE_API_KEY,
version: "weekly",
});
const { StreetViewService } = await loader.importLibrary("streetView");
let panorama: google.maps.StreetViewPanorama;
const streetviewRef = ref<HTMLElement>();
Expand Down Expand Up @@ -75,7 +82,7 @@ watch(
const loadStreetView = (
decidedLatLng: google.maps.LatLng | null = null
): void => {
const service = new google.maps.StreetViewService();
const service = new StreetViewService();
service.getPanorama(
{
location: decidedLatLng !== null ? decidedLatLng : getRandomLatLng(),
Expand Down
Loading

0 comments on commit 2d19d8a

Please sign in to comment.