Router done
This commit is contained in:
@@ -46,10 +46,16 @@ export default class Filters extends React.Component {
|
|||||||
this.props.dispatch({type: 'UPDATE_ROUTE', action: {
|
this.props.dispatch({type: 'UPDATE_ROUTE', action: {
|
||||||
params: {rooms}
|
params: {rooms}
|
||||||
}});
|
}});
|
||||||
|
|
||||||
this.props.dispatch({type: 'SET_ROOMS', action: {rooms}});
|
this.props.dispatch({type: 'SET_ROOMS', action: {rooms}});
|
||||||
}
|
}
|
||||||
|
|
||||||
onCategoryClick(category) {
|
onCategoryClick(category) {
|
||||||
|
|
||||||
|
this.props.dispatch({type: 'UPDATE_ROUTE', action: {
|
||||||
|
params: {category}
|
||||||
|
}});
|
||||||
|
|
||||||
this.props.dispatch({type: 'SET_CATEGORY', action: {category}});
|
this.props.dispatch({type: 'SET_CATEGORY', action: {category}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export default class Listings extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
loadListing(id).then(l => l.text()).then(l => {
|
loadListing(id).then(l => l.text()).then(l => {
|
||||||
console.log('lising clicked');
|
|
||||||
this.props.dispatch({type: 'UPDATE_ROUTE', action: {
|
this.props.dispatch({type: 'UPDATE_ROUTE', action: {
|
||||||
toDispatch: {
|
toDispatch: {
|
||||||
type: 'VIEW_LISTING_DETAILS', action: {
|
type: 'VIEW_LISTING_DETAILS', action: {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ class Main extends React.Component {
|
|||||||
state.filters.category = props.initialState.category;
|
state.filters.category = props.initialState.category;
|
||||||
state.sort = props.initialState.sort || state.sort;
|
state.sort = props.initialState.sort || state.sort;
|
||||||
state.listingId = props.initialState.listingId;
|
state.listingId = props.initialState.listingId;
|
||||||
|
state.bounds = props.initialState.bounds;
|
||||||
|
state.zoom = props.initialState.zoom;
|
||||||
if (state.listingId) {
|
if (state.listingId) {
|
||||||
state.listingDetails = true;
|
state.listingDetails = true;
|
||||||
}
|
}
|
||||||
@@ -44,12 +46,20 @@ class Main extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const uluru = {lat: 43.845031, lng: 18.4019262};
|
const uluru = {lat: 43.845031, lng: 18.4019262};
|
||||||
const map = new google.maps.Map(this.refs.map, {
|
const opts = {
|
||||||
zoom: 13,
|
//zoom: 13,
|
||||||
center: uluru,
|
//center: uluru,
|
||||||
streetViewControl: false,
|
streetViewControl: false,
|
||||||
mapTypeControl: false
|
mapTypeControl: false
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (!this.state.bounds) {
|
||||||
|
opts.zoom = 13;
|
||||||
|
opts.center= uluru;
|
||||||
|
};
|
||||||
|
|
||||||
|
const map = new google.maps.Map(this.refs.map, opts);
|
||||||
|
window.gmap = map;
|
||||||
|
|
||||||
//const marker = new google.maps.Marker({
|
//const marker = new google.maps.Marker({
|
||||||
//position: uluru,
|
//position: uluru,
|
||||||
@@ -68,6 +78,37 @@ class Main extends React.Component {
|
|||||||
var options = {
|
var options = {
|
||||||
componentRestrictions: {country: "BA"}
|
componentRestrictions: {country: "BA"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const regularIdle = () => {
|
||||||
|
this.dispatch({type: 'UPDATE_ROUTE', action: {params: {
|
||||||
|
bounds: map.getBounds().toUrlValue(),
|
||||||
|
zoom: map.getZoom()
|
||||||
|
}}});
|
||||||
|
|
||||||
|
this.dispatch({type: 'MAP_IDLE'});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if initial bounds are passed-in
|
||||||
|
|
||||||
|
google.maps.event.addListenerOnce(map, 'idle', () => {
|
||||||
|
|
||||||
|
if (this.state.bounds) {
|
||||||
|
const [ lat1, lng1, lat2, lng2 ] = this.state.bounds.split(",");
|
||||||
|
const sw = new google.maps.LatLng({lat: parseFloat(lat1), lng: parseFloat(lng1)});
|
||||||
|
const ne = new google.maps.LatLng({lat: parseFloat(lat2), lng: parseFloat(lng2)});
|
||||||
|
|
||||||
|
const initialBounds = new google.maps.LatLngBounds(sw, ne);
|
||||||
|
//map.fitBounds(initialBounds);
|
||||||
|
|
||||||
|
const originalMaxZoom = map.maxZoom;
|
||||||
|
const originalMinZoom = map.minZoom;
|
||||||
|
map.setOptions({maxZoom: parseInt(this.state.zoom), minZoom: parseInt(this.state.zoom)});
|
||||||
|
map.fitBounds(initialBounds);
|
||||||
|
map.setOptions({maxZoom: originalMaxZoom, minZoom: originalMinZoom});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
map.addListener('idle', regularIdle);
|
||||||
var searchBox = new google.maps.places.Autocomplete(input, options);
|
var searchBox = new google.maps.places.Autocomplete(input, options);
|
||||||
|
|
||||||
searchBox.addListener('place_changed', () => {
|
searchBox.addListener('place_changed', () => {
|
||||||
@@ -98,25 +139,8 @@ class Main extends React.Component {
|
|||||||
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);
|
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(control);
|
||||||
this.map = map;
|
this.map = map;
|
||||||
|
|
||||||
map.addListener('zoom_changed', () => {
|
|
||||||
this.removeAllMarkers();
|
|
||||||
this.markers = [];
|
|
||||||
});
|
|
||||||
|
|
||||||
map.addListener('idle', () => {
|
|
||||||
this.dispatch({type: 'UPDATE_ROUTE', action: {params: {
|
|
||||||
bounds: map.getBounds().toUrlValue()
|
|
||||||
}}});
|
|
||||||
|
|
||||||
this.dispatch({type: 'MAP_IDLE'});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: if state contains listingId reload
|
// TODO: if state contains listingId reload
|
||||||
//
|
|
||||||
|
|
||||||
if (this.state.listingId) {
|
if (this.state.listingId) {
|
||||||
|
|
||||||
loadListing(this.state.listingId).then(l => l.text()).then(l => {
|
loadListing(this.state.listingId).then(l => l.text()).then(l => {
|
||||||
this.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
|
this.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
|
||||||
id: this.state.listingId,
|
id: this.state.listingId,
|
||||||
|
|||||||
10
web/index.js
10
web/index.js
@@ -13,8 +13,12 @@ const getInitialState = (url) => {
|
|||||||
|
|
||||||
for(const param of params) {
|
for(const param of params) {
|
||||||
const [key, value] = param.split("=");
|
const [key, value] = param.split("=");
|
||||||
|
console.log('analyzing param ', key, value);
|
||||||
if (key === "rooms" && value !== '') {
|
if (key === "rooms" && value !== '') {
|
||||||
|
|
||||||
|
console.log("IT's ROOMS");
|
||||||
value.split(",").forEach(k => {
|
value.split(",").forEach(k => {
|
||||||
|
console.log("IT's ROOMS", k);
|
||||||
initialState.rooms[parseInt(k)] = true;
|
initialState.rooms[parseInt(k)] = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -30,16 +34,20 @@ const getInitialState = (url) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key === "bounds") {
|
if (key === "bounds") {
|
||||||
// TODO: save bounds
|
|
||||||
initialState.bounds = value;
|
initialState.bounds = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key === "listingId") {
|
if (key === "listingId") {
|
||||||
initialState.listingId = value;
|
initialState.listingId = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key === "zoom") {
|
||||||
|
initialState.zoom = parseInt(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('initial state dump', initialState);
|
console.log('initial state dump', initialState);
|
||||||
|
console.log('initial state ROOMS', initialState.rooms);
|
||||||
return initialState;
|
return initialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,13 @@
|
|||||||
class ToggleHash {
|
import clone from 'lodash.clonedeep';
|
||||||
constructor(data, key) {
|
|
||||||
this.data = data;
|
|
||||||
this.key = key;
|
|
||||||
this.data[key] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle (field) {
|
|
||||||
if (!field) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const val = this.data[this.key][field];
|
|
||||||
this.data[this.key][field] = !val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Router {
|
export default class Router {
|
||||||
constructor(comp, initialState) {
|
constructor(comp, initialState) {
|
||||||
this.component = comp;
|
this.component = comp;
|
||||||
this.state = initialState || {};
|
this.state = clone(initialState) || {};
|
||||||
|
|
||||||
this.roomsToggler = new ToggleHash(this.state, 'rooms');
|
|
||||||
this.categoryToggler = new ToggleHash(this.state, 'category');
|
|
||||||
|
|
||||||
window.onpopstate = (event) => {
|
window.onpopstate = (event) => {
|
||||||
const state = event.state;
|
const state = event.state;
|
||||||
console.log('POPING STATE', state);
|
|
||||||
if (state) {
|
if (state) {
|
||||||
if (state.toDispatch) {
|
if (state.toDispatch) {
|
||||||
this.component.dispatch(state.toDispatch);
|
this.component.dispatch(state.toDispatch);
|
||||||
@@ -38,16 +20,22 @@ export default class Router {
|
|||||||
const params = [];
|
const params = [];
|
||||||
if (state.params) {
|
if (state.params) {
|
||||||
|
|
||||||
this.roomsToggler.toggle(state.params.rooms);
|
let cloned = clone(state);
|
||||||
this.categoryToggler.toggle(state.params.category);
|
|
||||||
|
|
||||||
delete state.params['rooms'];
|
if (cloned.params.rooms != null) {
|
||||||
delete state.params['category'];
|
this.state.rooms[cloned.params.rooms] = !this.state.rooms[cloned.params.rooms];
|
||||||
|
}
|
||||||
|
|
||||||
this.state = Object.assign(this.state, state.params);
|
if (cloned.params.category != null) {
|
||||||
|
this.state.category[cloned.params.category] = !this.state.category[cloned.params.category];
|
||||||
|
}
|
||||||
|
|
||||||
console.log('router state is: ', this.state);
|
delete cloned.params['rooms'];
|
||||||
const {listingId, bounds, sort, rooms = {}, category = {}} = this.state;
|
delete cloned.params['category'];
|
||||||
|
|
||||||
|
this.state = Object.assign(this.state, cloned.params);
|
||||||
|
|
||||||
|
const {listingId, bounds, sort, rooms = {}, category = {}, zoom} = this.state;
|
||||||
|
|
||||||
if (listingId) {
|
if (listingId) {
|
||||||
params.push(`listingId=${listingId}`);
|
params.push(`listingId=${listingId}`);
|
||||||
@@ -55,22 +43,20 @@ export default class Router {
|
|||||||
|
|
||||||
params.push(`sort=${sort}`);
|
params.push(`sort=${sort}`);
|
||||||
params.push(`bounds=${bounds}`);
|
params.push(`bounds=${bounds}`);
|
||||||
|
params.push(`zoom=${zoom}`);
|
||||||
params.push(`rooms=${Object.keys(rooms).filter(v => rooms[v]).join(",")}`);
|
params.push(`rooms=${Object.keys(rooms).filter(v => rooms[v]).join(",")}`);
|
||||||
params.push(`category=${Object.keys(category).filter(v => category[v]).join(",")}`);
|
params.push(`category=${Object.keys(category).filter(v => category[v]).join(",")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.toDispatch) {
|
if (state.toDispatch) {
|
||||||
console.log('PUSHING STATE', state);
|
|
||||||
window.history.pushState(state, '', `/?${params.join("&")}`);
|
window.history.pushState(state, '', `/?${params.join("&")}`);
|
||||||
} else {
|
} else {
|
||||||
const oldState = window.history.state;
|
const oldState = window.history.state;
|
||||||
if (oldState) {
|
if (oldState) {
|
||||||
const newState = Object.assign(oldState, state);
|
const newState = Object.assign(oldState, state);
|
||||||
console.log('REPLACING STATE', newState);
|
|
||||||
window.history.replaceState(newState, '',`/?${params.join("&")}`);
|
window.history.replaceState(newState, '',`/?${params.join("&")}`);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
console.log('PUSHING STATE', state);
|
|
||||||
window.history.replaceState(state, '',`/?${params.join("&")}`);
|
window.history.replaceState(state, '',`/?${params.join("&")}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-preset-stage-3": "^6.22.0",
|
"babel-preset-stage-3": "^6.22.0",
|
||||||
|
"lodash.clonedeep": "^4.5.0",
|
||||||
|
"lodash.merge": "^4.6.0",
|
||||||
"react": "^15.3.2",
|
"react": "^15.3.2",
|
||||||
"react-dom": "^15.3.2"
|
"react-dom": "^15.3.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1673,6 +1673,14 @@ loader-utils@^0.2.11, loader-utils@^0.2.16:
|
|||||||
json5 "^0.5.0"
|
json5 "^0.5.0"
|
||||||
object-assign "^4.0.1"
|
object-assign "^4.0.1"
|
||||||
|
|
||||||
|
lodash.clonedeep:
|
||||||
|
version "4.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||||
|
|
||||||
|
lodash.merge:
|
||||||
|
version "4.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5"
|
||||||
|
|
||||||
lodash@^4.17.2, lodash@^4.2.0:
|
lodash@^4.17.2, lodash@^4.2.0:
|
||||||
version "4.17.4"
|
version "4.17.4"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||||
|
|||||||
Reference in New Issue
Block a user