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 0000000..6533948
Binary files /dev/null and b/web/dist/static/images/pins_sprite.png differ
diff --git a/web/lib/handlers.js b/web/lib/handlers.js
index db6ce87..7b2c13d 100644
--- a/web/lib/handlers.js
+++ b/web/lib/handlers.js
@@ -55,7 +55,7 @@ const listingsLoaded = ({ type, action }, component) => {
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) => {