From 690569595828b341c1237ac7fedfe85fdf532b7f Mon Sep 17 00:00:00 2001 From: Edin Dazdarevic Date: Thu, 6 Apr 2017 01:11:51 +0200 Subject: [PATCH] Handle marker icons --- backend/build/server.js | 34 ++++++--- backend/server.js | 11 ++- web/components/Listings.js | 12 ++- web/components/Main.js | 101 +++++++++++++++++++++++-- web/dist/static/images/pins_sprite.png | Bin 0 -> 20320 bytes web/lib/handlers.js | 20 ++++- 6 files changed, 150 insertions(+), 28 deletions(-) create mode 100644 web/dist/static/images/pins_sprite.png diff --git a/backend/build/server.js b/backend/build/server.js index 44f22d0..ffc23dc 100644 --- a/backend/build/server.js +++ b/backend/build/server.js @@ -74,7 +74,7 @@ router.get('/search', function () { var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(req, res, next) { - var bounds, minPrice, maxPrice, minSize, maxSize, rooms, adType, category, sort, properties, query, _bounds$split$map, _bounds$split$map2, lat1, lng1, lat2, lng2, box, price, allRooms, or, size, allCategories, _or, all; + var bounds, minPrice, maxPrice, minSize, maxSize, rooms, adType, category, sort, properties, query, _bounds$split$map, _bounds$split$map2, lat1, lng1, lat2, lng2, box, price, and, allRooms, or, size, allCategories, _or, all; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { @@ -130,6 +130,8 @@ }); } + and = []; + if (rooms) { allRooms = rooms.split(','); or = allRooms.map(function (val) { @@ -146,9 +148,10 @@ }); - query = Object.assign(query, { - "$or": or - }); + and.push({ "$or": or }); + //query = Object.assign(query, { + //rooms: + //}); } if (minSize || maxSize) { @@ -176,40 +179,47 @@ }); + and.push({ "$or": _or }); + //query = Object.assign(query, { + //{"$or" : or } + //}); + } + + if (and.length > 0) { query = Object.assign(query, { - "$or": _or + "$and": and }); } console.log('QUERY: ', query); - _context.next = 21; + _context.next = 23; return properties.find(query, { //"sort": [['field1','asc'], ['field2','desc']] "sort": [['price', 'asc']] }).toArray(); - case 21: + case 23: all = _context.sent; res.json(all); res.end(); - _context.next = 30; + _context.next = 32; break; - case 26: - _context.prev = 26; + case 28: + _context.prev = 28; _context.t0 = _context['catch'](0); console.log('error:', _context.t0); next(_context.t0); - case 30: + case 32: case 'end': return _context.stop(); } } - }, _callee, undefined, [[0, 26]]); + }, _callee, undefined, [[0, 28]]); })); return function (_x, _x2, _x3) { diff --git a/backend/server.js b/backend/server.js index a393ded..82e987f 100644 --- a/backend/server.js +++ b/backend/server.js @@ -60,6 +60,7 @@ router.get('/search', async (req, res, next) => { }); } + const and = []; if (rooms) { const allRooms = rooms.split(','); const or = allRooms.map(val => { @@ -75,9 +76,7 @@ router.get('/search', async (req, res, next) => { }; }); - query = Object.assign(query, { - "$or": or - }); + and.push({ "$or": or }); } if (minSize || maxSize) { @@ -103,8 +102,12 @@ router.get('/search', async (req, res, next) => { }; }); + and.push({ "$or": or }); + } + + if (and.length > 0) { query = Object.assign(query, { - "$or": or + "$and": and }); } diff --git a/web/components/Listings.js b/web/components/Listings.js index f69969f..88bde65 100644 --- a/web/components/Listings.js +++ b/web/components/Listings.js @@ -11,6 +11,15 @@ export default class Listings extends React.Component { }); } + onMouseEnter (id) { + this.props.dispatch({ + type: 'ON_LISTING_MOUSE_OVER', + action: { + id + } + }); + } + renderListings () { const {listings = (new Map())} = this.props; @@ -22,8 +31,9 @@ export default class Listings extends React.Component { rendered.push(
+ onClick={this.onListingClick.bind(this, l._id)}>
diff --git a/web/components/Main.js b/web/components/Main.js index ecf73f5..9b01f5a 100644 --- a/web/components/Main.js +++ b/web/components/Main.js @@ -112,6 +112,15 @@ class Main extends React.Component { }); } + findMarker (id) { + if (!this.markers) { + return null; + } + + const index = this.markers.findIndex(m => m.id === id); + return this.markers[index]; + } + /* * Refreshes search */ @@ -138,8 +147,9 @@ class Main extends React.Component { category }); + const markerExists = (id) => { - return (this.markers || []).findIndex(m => m.id === id) !== -1; + return this.findMarker(id) != null; } properties.then(p => p.text()).then(p => { @@ -168,18 +178,42 @@ class Main extends React.Component { for(const [index, prop] of data.entries()) { const myLatLng = {lat: prop.loc[0], lng: prop.loc[1]}; - if (!markerExists(p._id)) { + if (!markerExists(prop._id)) { + const marker = new google.maps.Marker({ - position: myLatLng, - map: map, - title: prop.title + position : myLatLng, + map : map, + title : prop.title, + icon : this.defaultMarkerIcon(), + id : prop._id + }); + + marker.addListener('mouseover', () => { + if (marker.id !== this.state.listingId) { + marker.setIcon(this.hoveredMarkerIcon()); + } + }); + + marker.addListener('mouseout', () => { + if (marker.id !== this.state.listingId) { + marker.setIcon(this.defaultMarkerIcon()); + } }); marker.addListener('click', () => { - console.log('clicking...') + 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.defaultMarkerIcon()); + } + } + + marker.setIcon(this.selectedMarkerIcon()); this.dispatch({type: 'VIEW_LISTING_DETAILS', action: { - id: prop.url - }}) + id: prop._id + }}); }); newMarkers.push({ @@ -211,6 +245,57 @@ class Main extends React.Component { }) } + /* + * 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; + } + + /* + * 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 = []; diff --git a/web/dist/static/images/pins_sprite.png b/web/dist/static/images/pins_sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..65339486e4e39b2d55b03e43db8b372759242154 GIT binary patch literal 20320 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 { const currentListings = new Map(); for (const listing of action.listings) { - currentListings.set(listing.url, listing); + currentListings.set(listing._id, listing); } component.setState({ @@ -151,7 +151,20 @@ const setCategory = ({type, action}, component) => { component.refreshListings(); } ); -} +}; + +const onListingMouseOver = ({type, action}, component) => { + const marker = component.findMarker(action.id); + if (marker) { + marker.marker.setIcon(component.hoveredMarkerIcon()); + marker.marker.setAnimation(google.maps.Animation.BOUNCE); + setTimeout(() => { + marker.marker.setAnimation(null); + marker.marker.setIcon(component.defaultMarkerIcon()); + } , 710); + } + +}; const handlers = { SET_MIN_PRICE: setMinPrice, @@ -167,7 +180,8 @@ const handlers = { SET_ROOMS: setRooms, VIEW_LISTING_DETAILS: viewListingDetails, UPDATE_SEARCH: updateSearch, - SET_CATEGORY: setCategory + SET_CATEGORY: setCategory, + ON_LISTING_MOUSE_OVER: onListingMouseOver }; export const handleMessage = ({ type, action }, component) => {