import React from 'react'; import Filters from './Filters'; import Listings from './Listings'; import ListingDetails from './ListingDetails'; import { pacSelectFirst } from '../helpers/googleMaps'; import { loadProperties, loadSeen } from '../lib/api' import { handleMessage } from '../lib/handlers' class Main extends React.Component { constructor(props) { super(props); this.state = { listingDetails: false, listings: (new Map()), imageIndex: 0, page: 0, filters: { rooms: {}, category: {} } }; } dispatch ({type, action = {}}) { handleMessage({type, action}, this); } componentDidMount() { const uluru = {lat: 43.845031, lng: 18.4019262}; const map = new google.maps.Map(this.refs.map, { zoom: 13, center: uluru, streetViewControl: false, mapTypeControl: false }); //const marker = new google.maps.Marker({ //position: uluru, //map: map //}); var control = document.createElement('div'); control.classList.add('filters-btn-toggle'); control.innerHTML = 'Filters'; //control.style = "top: 200px;" control["style"]= "top: 200px;" var input = document.getElementById('gmaps-places-input'); pacSelectFirst(input); var options = { componentRestrictions: {country: "BA"} }; var searchBox = new google.maps.places.Autocomplete(input, options); searchBox.addListener('place_changed', () => { var place = searchBox.getPlace(); if (!place.geometry) { return; } if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); } else { map.setCenter(place.geometry.location); map.setZoom(18); } console.log(map.getBounds()); this.dispatch({type: 'SEARCH_PLACE_CHANGED'}); }); control.addEventListener('click', (e) => { this.setState({ mapClicked: true }); }); control.index = 1; map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control); this.map = map; map.addListener('zoom_changed', () => { console.log('zoom_changed'); this.removeAllMarkers(); this.markers = []; }); map.addListener('idle', () => { console.log('idle'); this.dispatch({type: 'MAP_IDLE'}); //this.refreshListings(); }); } removeAllMarkers () { if (this.markers) { console.log('removeAllMarkers'); this.markers.forEach((m) => m.marker.setMap(null)); } } onCloseClick(e) { if (this.state.mapClicked) { setTimeout(() => { google.maps.event.trigger(this.map, 'resize'); }, 100); } this.setState({ mapClicked: false }); } findMarker (id) { if (!this.markers) { return null; } const index = this.markers.findIndex(m => m.id === id); return this.markers[index]; } isSeen (id) { const seen = loadSeen(); return seen.findIndex(s => s === id) !== -1 } loadPins () { const map = this.map; const { rooms, minSize, maxSize, minPrice, maxPrice, category } = this.state.filters; const bounds = map.getBounds(); const properties = loadProperties({ bounds: bounds.toUrlValue(), rooms, minSize, maxSize, minPrice, maxPrice, category, page: this.state.page, pins: true }); const markerExists = (id) => { return this.findMarker(id) != null; } properties .then(p => { return { body: p.text(), totalCount: p.headers.get('X-Total-Count') }; }) .then(({body, totalCount}) => { body.then(p => { console.log('results_received: ', totalCount); const data = JSON.parse(p); const listingExists = (id) => { return data.findIndex(l => l._id === id) !== -1 }; const newMarkers = []; if (this.markers) { this.markers.forEach((m) => { if (!listingExists(m.id)) { m.marker.setMap(null); } else { newMarkers.push(m); } }); console.log('markers_removed'); } for(const [index, prop] of data.entries()) { const myLatLng = {lat: prop.loc[0], lng: prop.loc[1]}; if (!markerExists(prop._id)) { const marker = new google.maps.Marker({ position : myLatLng, map : map, title : prop.title, icon : this.isSeen(prop._id) ? this.visitedMarkerIcon() : this.defaultMarkerIcon(), id : prop._id }); marker.addListener('mouseover', () => { if (marker.id !== this.state.listingId) { if (this.isSeen(marker.id)) { marker.setIcon(this.visitedHoveredMarkerIcon()); } else { marker.setIcon(this.hoveredMarkerIcon()); } } }); marker.addListener('mouseout', () => { if (marker.id !== this.state.listingId) { if (this.isSeen(marker.id)) { marker.setIcon(this.visitedMarkerIcon()); } else { marker.setIcon(this.defaultMarkerIcon()); } } }); marker.addListener('click', () => { console.log('clicking...', prop._id); if (this.state.listingId) { const prevSelected = this.findMarker(this.state.listingId); if (prevSelected) { console.log('prevselected', prevSelected); prevSelected.marker.setIcon(this.visitedMarkerIcon()); } } marker.setIcon(this.selectedMarkerIcon()); this.dispatch({type: 'VIEW_LISTING_DETAILS', action: { id: prop._id }}); }); newMarkers.push({ marker, id: prop._id }); } } this.dispatch({ type: 'PINS_LOADED', action: { newMarkers } }); }); }) } /* * Refreshes search */ refreshListings(more = false) { console.log('refreshListings'); this.loadPins(); const map = this.map; const { rooms, minSize, maxSize, minPrice, maxPrice, category } = this.state.filters; const bounds = map.getBounds(); const properties = loadProperties({ bounds: bounds.toUrlValue(), rooms, minSize, maxSize, minPrice, maxPrice, category, page: this.state.page }); properties .then(p => { return { body: p.text(), totalCount: p.headers.get('X-Total-Count') }; }) .then(({body, totalCount}) => { body.then(p => { console.log('results_received: ', totalCount); const data = JSON.parse(p); this.dispatch({ type: 'LISTINGS_LOADED', action: { listings: data, more, totalCount } }); }); }) } /* * Get default marker icon */ defaultMarkerIcon () { const sf = 0.5; const width = 48; const height = 64; const icon = { url : "static/images/pins_sprite.png", size : new google.maps.Size(width * sf, height * sf), scaledSize : new google.maps.Size(730 * sf, 102 * sf), origin : new google.maps.Point(0, 36 * sf) } return icon; } /* * Get visited marker icon */ visitedMarkerIcon () { const sf = 0.5; const width = 48; const height = 64; const icon = { url : "static/images/pins_sprite.png", size : new google.maps.Size(width * sf, height * sf), scaledSize : new google.maps.Size(730 * sf, 102 * sf), origin : new google.maps.Point(152 * sf, 36 * sf) } return icon; } /* * Visited hovered marker icon */ visitedHoveredMarkerIcon () { const sf = 0.5; const width = 61; const height = 82; const icon = { url : "static/images/pins_sprite.png", size : new google.maps.Size(width * sf, height * sf), scaledSize : new google.maps.Size(730 * sf, 102 * sf), origin : new google.maps.Point(480 * sf, 18 * sf) } return icon; } /* * Hovered marker icon */ hoveredMarkerIcon () { const sf = 0.5; const width = 61; const height = 82; const icon = { url : "static/images/pins_sprite.png", size : new google.maps.Size(width * sf, height * sf), scaledSize : new google.maps.Size(730 * sf, 102 * sf), origin : new google.maps.Point(303 * sf, 18 * sf) } return icon; } /* * Selected marker icon */ selectedMarkerIcon () { const sf = 0.5; const width = 73; const height = 100; const icon = { url : "static/images/pins_sprite.png", size : new google.maps.Size(width * sf, height * sf), scaledSize : new google.maps.Size(730 * sf, 102 * sf), origin : new google.maps.Point(655 * sf, 1 * sf) } return icon; } renderRightContent() { const children = []; if (this.state.listingDetails) { console.log('CURRENT LISTINGS', this.state.listings); const listing = this.state.listings.get(this.state.listingId); console.log(this.state); children.push(); } else { children.push(); children.push(); } const content = ( {children} ); return content; } render() { const leftStyle = {}; const rightStyle = {}; const listingDetails = true; let leftClass = 'left-base'; let rightClass = 'right-base'; if (this.state.mapClicked) { leftClass = 'left-hidden'; rightClass = 'right-shown'; } return ( K Kiwi {this.renderRightContent()} ) } } export default Main;