routes: backend endpoint

This commit is contained in:
muerwre 2018-12-12 17:32:08 +07:00
parent d11dd9043c
commit c69da00b2a
10 changed files with 106 additions and 15 deletions

View file

@ -1,10 +1,12 @@
const express = require('express');
const post = require('./route/post');
const get = require('./route/get');
const list = require('./route/list');
const router = express.Router();
router.post('/', post);
router.get('/', get);
router.get('/list', list);
module.exports = router;

View file

@ -0,0 +1,50 @@
const { Route, User } = require('../../models');
module.exports = async (req, res) => {
const {
query: {
id, token, title, distance, author, starred,
}
} = req;
const user = await User.findOne({ _id: id, token });
let criteria = {};
if (title) {
criteria = {
...criteria,
$or: [
{ title: new RegExp(title, 'ig') },
{ _id: new RegExp(title, 'ig') },
],
};
}
if (!author || !user || (user._id !== author)) {
criteria = {
...criteria,
public: true,
};
}
const list = await Route.find({
...criteria,
distance: {
$gte: parseInt(distance[0], 10),
$lte: parseInt(distance[1], 10),
},
public: true,
}, '_id title distance owner updated_at', { limit: 500 }).populate('owner');
const filtered = list.filter(item => (
!author || item.owner._id === author
));
res.send({
success: true,
list: filtered,
});
};

View file

@ -5,7 +5,6 @@ import { connect } from 'react-redux';
import { RouteRow } from '$components/maps/RouteRow';
import { Scroll } from '$components/Scroll';
import {
searchSetAuthor,
searchSetDistance,
searchSetTitle,
} from '$redux/user/actions';
@ -98,11 +97,11 @@ class Component extends React.Component<Props> {
<Scroll className="dialog-shader">
<div className="dialog-maplist">
{
list.map((route, index) => (
list.map(route => (
<RouteRow
editing={editing}
{...route}
key={index}
key={route._id}
/>
))
}
@ -120,7 +119,6 @@ const mapStateToProps = ({ user: { editing, routes } }) => ({
});
const mapDispatchToProps = dispatch => bindActionCreators({
searchSetAuthor,
searchSetDistance,
searchSetTitle,
}, dispatch);

View file

@ -33,7 +33,7 @@ type Props = {
class Component extends React.PureComponent<Props, void> {
componentDidMount() {
window.addEventListener('keydown', this.props.keyPressed);
window.addEventListener('keydown', this.keyPressed);
const obj = document.getElementById('control-dialog');
const { width } = this.panel.getBoundingClientRect();
@ -44,9 +44,21 @@ class Component extends React.PureComponent<Props, void> {
}
componentWillUnmount() {
window.removeEventListener('keydown', this.props.keyPressed);
window.removeEventListener('keydown', this.keyPressed);
}
keyPressed = e => {
// if (
// e.target.tagName === 'INPUT' ||
// e.target.tagName === 'TEXTAREA'
// ) {
// if (e.key === 'Escape') e.target.blur();
// return;
// }
this.props.keyPressed(e);
};
startPolyMode = () => this.props.setMode(MODES.POLY);
startStickerMode = () => this.props.setMode(MODES.STICKERS_SELECT);
startRouterMode = () => this.props.setMode(MODES.ROUTER);

View file

@ -6,4 +6,6 @@ export const API = {
IFRAME_LOGIN_VK: `${CLIENT.API_ADDR}/auth/iframe/vk`,
GET_MAP: `${CLIENT.API_ADDR}/route`,
POST_MAP: `${CLIENT.API_ADDR}/route`,
GET_ROUTE_LIST: `${CLIENT.API_ADDR}/route/list`,
};

View file

@ -51,3 +51,4 @@ export const keyPressed = ({ key }) => ({ type: ACTIONS.KEY_PRESSED, key });
export const searchSetTitle = title => ({ type: ACTIONS.SEARCH_SET_TITLE, title });
export const searchSetDistance = distance => ({ type: ACTIONS.SEARCH_SET_DISTANCE, distance });
export const searchSetTab = tab => ({ type: ACTIONS.SEARCH_SET_TAB, tab });
export const searchPutRoutes = list => ({ type: ACTIONS.SEARCH_PUT_ROUTES, list })

View file

@ -55,4 +55,5 @@ export const ACTIONS = ({
SEARCH_SET_DISTANCE: 'SEARCH_SET_DISTANCE',
SEARCH_SET_TAB: 'SEARCH_SET_TAB',
SEARCH_PUT_ROUTES: 'SEARCH_PUT_ROUTES',
}: { [key: String]: String });

View file

@ -128,6 +128,14 @@ const searchSetTab = (state, { tab = 'mine' }) => ({
}
});
const searchPutRoutes = (state, { list = [] }) => ({
...state,
routes: {
...state.routes,
list,
}
});
const HANDLERS = ({
[ACTIONS.SET_USER]: setUser,
[ACTIONS.SET_EDITING]: setEditing,
@ -159,13 +167,13 @@ const HANDLERS = ({
[ACTIONS.SEARCH_SET_TITLE]: searchSetTitle,
[ACTIONS.SEARCH_SET_DISTANCE]: searchSetDistance,
[ACTIONS.SEARCH_SET_TAB]: searchSetTab,
[ACTIONS.SEARCH_PUT_ROUTES]: searchPutRoutes,
}: { [key: String]: Function });
export const INITIAL_STATE = {
ready: false,
user: { ...DEFAULT_USER },
editing: false,
// mode: MODES.NONE,
mode: MODES.NONE,
logo: DEFAULT_LOGO,
routerPoints: 0,

View file

@ -4,12 +4,12 @@ import { takeLatest, select, call, put, takeEvery, race, take } from 'redux-saga
import {
checkIframeToken,
checkUserToken,
getGuestToken,
getGuestToken, getRouteList,
getStoredMap,
postMap
} from '$utils/api';
import {
hideRenderer,
hideRenderer, searchPutRoutes,
setActiveSticker, setAddress,
setChanged, setDialogActive,
setEditing,
@ -431,15 +431,24 @@ function* keyPressedSaga({ key }): void {
if (dialog_active) return yield put(setDialogActive(false));
if (mode !== MODES.NONE) return yield put(setMode(MODES.NONE));
}
return;
}
function* searchSetSaga() {
yield delay(500);
const { routes: { filter: { title, distance, tab }}} = yield select(getState);
const { id, token } = yield select(getUser);
console.log({ title, distance, tab });
yield delay(500);
const { routes: { filter: { title, distance, tab } } } = yield select(getState);
const list = yield call(getRouteList, {
id,
token,
title,
distance,
author: tab === 'mine' ? id : '',
starred: tab === 'starred',
});
yield put(searchPutRoutes(list));
}
export function* userSaga() {
@ -478,5 +487,5 @@ export function* userSaga() {
yield takeLatest([
ACTIONS.SEARCH_SET_TITLE,
ACTIONS.SEARCH_SET_DISTANCE,
], searchSetSaga)
], searchSetSaga);
}

View file

@ -37,3 +37,11 @@ export const postMap = ({
export const checkIframeToken = ({ viewer_id, auth_key }) => axios.get(API.IFRAME_LOGIN_VK, {
params: { viewer_id, auth_key }
}).then(result => (result && result.data && result.data.success && result.data.user)).catch(() => (false));
export const getRouteList = ({
title, distance, author, starred
}) => axios.get(API.GET_ROUTE_LIST, {
params: {
title, distance, author, starred
}
}).then(result => (result && result.data && result.data.success && result.data.list)).catch(() => ([]));