Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor globalThis usage by moving functions to utils.js #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 3 additions & 22 deletions components/AttractionDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<script setup>
import { getState } from '~/state'
import { Attraction } from '~/state'
import { createMarker, updateDistances, calculateDirections } from '~/utils'

const state = getState()

Expand Down Expand Up @@ -72,32 +73,12 @@ const toggleAttractionInItinerary = (attraction) => {
}
globalThis.map.panTo(attraction.location)
createMarker(attraction)
globalThis.updateDistances()
updateDistances()
if (!state._selectedAttractions.includes(attraction.name))
globalThis.calculateDirections()
calculateDirections()
if (state._selectedAttractions.length === 0) {
state.activeView = 'map'
}
window.scrollTo({ top: 0, behavior: 'smooth' })
}


const createMarker = (attraction) => {
const marker = new google.maps.Marker({
map: globalThis.map,
position: attraction.location,
title: attraction.name,
animation: google.maps.Animation.DROP,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 8,
fillColor: attraction.inItinerary ? '#4CAF50' : '#FFA500',
fillOpacity: 0.9,
strokeWeight: 0
}
})

state.markers.push(marker)

}
</script>
15 changes: 8 additions & 7 deletions components/AttractionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@
</div>
</template>
<script setup>
import { computed } from 'vue'
import { computed, watch } from 'vue'
import { getState } from '../state.js'
import AttractionDetails from './AttractionDetails.vue'
import { updateDistances, calculateDirections, calculateDistance } from '../utils.js'

const state = getState()
const openInGoogleMaps = () => {
Expand Down Expand Up @@ -91,14 +92,14 @@ const toggleItinerary = () => {
}
watch(() => [state.showItinerary, state._selectedAttractions.length], (newValue) => {

globalThis.calculateDirections()
globalThis.updateDistances()
calculateDirections()
updateDistances()

})



globalThis.updateDistances = () => {
updateDistances = () => {
const itineraryAttractions = state.attractions.filter(a => state._selectedAttractions.includes(a.name))
for (const attraction of state.attractions) {
if (state._selectedAttractions.includes(attraction.name)) {
Expand All @@ -110,9 +111,9 @@ globalThis.updateDistances = () => {
if (leg)
attraction.distance = leg.distance.value / 1000;
} else {
let minDistance = globalThis.calculateDistance(state._homeLocation, attraction.location)
let minDistance = calculateDistance(state._homeLocation, attraction.location)
for (const itineraryAttraction of itineraryAttractions) {
const distanceToItinerary = globalThis.calculateDistance(itineraryAttraction.location, attraction.location)
const distanceToItinerary = calculateDistance(itineraryAttraction.location, attraction.location)
if (distanceToItinerary < minDistance) {
minDistance = distanceToItinerary
}
Expand All @@ -121,7 +122,7 @@ globalThis.updateDistances = () => {
}
}
}
globalThis.calculateDistance = (point1, point2) => {
calculateDistance = (point1, point2) => {
return google.maps.geometry.spherical.computeDistanceBetween(
new google.maps.LatLng(point1),
new google.maps.LatLng(point2)
Expand Down
34 changes: 3 additions & 31 deletions components/LocationModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<script setup>
import { ref, onMounted, watch } from 'vue'
import { getState } from '~/state'
import { updateLocation } from '~/utils'

const state = getState()
const autocompleteInput = ref(null)
Expand All @@ -28,7 +29,7 @@ const setNewLocation = () => {

if (place) {
if (place && place.geometry) {
globalThis.updateLocation(place.geometry.location, place.name)
updateLocation(place.geometry.location, place.name)
}
} else {
navigator.geolocation.getCurrentPosition(
Expand All @@ -37,41 +38,13 @@ const setNewLocation = () => {
lat: position.coords.latitude,
lng: position.coords.longitude
}
globalThis.updateLocation(location)
updateLocation(location)
},
() => alert('Unable to get location. Please enter manually.')
)
}
}

globalThis.updateLocation = (location, placeName = 'Current Location') => {
state._homeLocation = {
lat: typeof location.lat === 'function' ? location.lat() : location.lat,
lng: typeof location.lng === 'function' ? location.lng() : location.lng
}
globalThis.map.setCenter(location)
state._selectedAttractions = [];
globalThis.clearMarkers()
state._title = `${placeName}`
globalThis.placeHomeMarker();
}
globalThis.placeHomeMarker = () => {
const homeIcon = {
url: 'https://maps.google.com/mapfiles/kml/shapes/homegardenbusiness.png',
scaledSize: new google.maps.Size(40, 40),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(20, 40)
}
state.markers.push(
new google.maps.Marker({
position: state._homeLocation,
map: globalThis.map,
icon: homeIcon,
title: 'Home'
})
)
}

watch(() => state._title, (newValue) => {
document.title = newValue
document.querySelector('h1').textContent = newValue
Expand All @@ -86,7 +59,6 @@ setTimeout(() => {
fields: ['place_id', 'geometry', 'name']
}
)
globalThis.calculateDirections();
}, 1000);

watch(() => state.showModal, (newValue) => {
Expand Down
126 changes: 1 addition & 125 deletions components/MapView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,137 +3,13 @@
</template>
<script setup>
import { onMounted, watch } from 'vue'
import { Attraction, getState } from '../state'
import { Attraction, getState, initMap, clearMarkers, calculateDirections, updateAttractions, focusAttraction, placeHomeMarker } from '../utils'
let state = getState();
/** @type {google.maps.DirectionsService} */
let directionsService;
/** @type {google.maps.DirectionsRenderer} */
let directionsRenderer;
/** @type {google.maps.Map} */
globalThis.map;
const initMap = globalThis.initMap = () => {
directionsService = new google.maps.DirectionsService()
directionsRenderer = new google.maps.DirectionsRenderer()
globalThis.map = new google.maps.Map(document.getElementById('map'), {
center: state._homeLocation || { lat: -8.3405, lng: 115.0920 },
zoom: 12,gestureHandling: "greedy"
})


directionsRenderer.setMap(globalThis.map)

globalThis.map.addListener('idle', () => {
updateAttractions()
})
watch(() => state._placeType, () => {

updateAttractions()
})

if (!state._homeLocation) {
navigator.geolocation.getCurrentPosition(
(position) => globalThis.updateLocation({
lat: position.coords.latitude,
lng: position.coords.longitude
}),
() => fetch('https://ipapi.co/json/')
.then(response => response.json())
.then(data => globalThis.updateLocation({
lat: data.latitude,
lng: data.longitude
}, data.city))
.catch(() => alert('Unable to get location. Please enter manually.'))
);
}else{
globalThis.placeHomeMarker();
}


}

globalThis.clearMarkers = () => {
state.markers.forEach(marker => {
marker.setVisible(false)
marker.setMap(null)
})
state.markers = []
state.attractions = []
directionsRenderer.setDirections({ routes: [] })
state.showItinerary = false

}

globalThis.calculateDirections = () => {
const itineraryAttractions = state.attractions.filter(a => a.inItinerary)
if (itineraryAttractions.length === 0) return

const origin = state._homeLocation
const destination = itineraryAttractions[itineraryAttractions.length - 1].location
const waypoints = itineraryAttractions.map(a => ({
location: a.location,
stopover: true
}))

directionsService.route({
origin: origin,
destination: destination,
waypoints: waypoints,
optimizeWaypoints: true,
travelMode: 'DRIVING'
}, (result, status) => {
if (status === 'OK') {
directionsRenderer.setDirections(result)
}
})
}

const updateAttractions = () => {
const bounds = globalThis.map.getBounds()
const service = new google.maps.places.PlacesService(globalThis.map)

let request = {
bounds: bounds,
}

if (state._placeType === 'food') {
request.type = undefined
request.keyword = ['restaurant']
} else {
request.type = ['tourist_attraction']
request.keyword = undefined;
}

service.nearbySearch(request, (results, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (const place of results) {
if (!state.attractions.some(a => a.id === place.place_id)) {
service.getDetails({ placeId: place.place_id }, (details, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK) {
const attraction = Attraction(details, { distance: globalThis.calculateDistance(state._homeLocation, details.geometry.location),type: state._placeType })
if (!state.attractions.some(a => a.id === attraction.id)) {
state.attractions.push(attraction)
}

}
})
}
}//remove duplicates

}
})
}



const focusAttraction = (attraction) => {
globalThis.map.panTo(attraction.location)
}

onMounted(() => {
if (window.google) {
initMap()
}
})


</script>
5 changes: 3 additions & 2 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { getState } from '../state.js'
import AttractionList from '../components/AttractionList.vue'
import MapView from '../components/MapView.vue'
import LocationModal from '../components/LocationModal.vue'
import { calculateDirections } from '../utils.js'

const state = getState()

Expand All @@ -40,10 +41,10 @@ const toggleModal = () => {
const ActiveView = (view) => {
state.activeView = view
if (view === 'map') {
globalThis.calculateDirections()
calculateDirections()
}
}
</script>
<style>
@import './styles.css';
</style>
</style>
52 changes: 52 additions & 0 deletions utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Function to update the location and refresh the map view
export const updateLocation = (location, placeName = 'Current Location') => {
const state = getState();
state._homeLocation = {
lat: typeof location.lat === 'function' ? location.lat() : location.lat,
lng: typeof location.lng === 'function' ? location.lng() : location.lng
};
globalThis.map.setCenter(location);
state._selectedAttractions = [];
clearMarkers();
state._title = `${placeName}`;
placeHomeMarker();
};

// Function to calculate directions between attractions
export const calculateDirections = () => {
const state = getState();
const itineraryAttractions = state.attractions.filter(a => a.inItinerary);
if (itineraryAttractions.length === 0) return;

const origin = state._homeLocation;
const destination = itineraryAttractions[itineraryAttractions.length - 1].location;
const waypoints = itineraryAttractions.map(a => ({
location: a.location,
stopover: true
}));

directionsService.route({
origin: origin,
destination: destination,
waypoints: waypoints,
optimizeWaypoints: true,
travelMode: 'DRIVING'
}, (result, status) => {
if (status === 'OK') {
directionsRenderer.setDirections(result);
}
});
};

// Function to clear all markers from the map
export const clearMarkers = () => {
const state = getState();
state.markers.forEach(marker => {
marker.setVisible(false);
marker.setMap(null);
});
state.markers = [];
state.attractions = [];
directionsRenderer.setDirections({ routes: [] });
state.showItinerary = false;
};