diff --git a/backend/routes/route.js b/backend/routes/route.js index 1e70f08..f9976bb 100644 --- a/backend/routes/route.js +++ b/backend/routes/route.js @@ -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; diff --git a/backend/routes/route/list.js b/backend/routes/route/list.js new file mode 100644 index 0000000..c3428a3 --- /dev/null +++ b/backend/routes/route/list.js @@ -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, + }); +}; + diff --git a/src/components/dialogs/MapListMoreDialog.jsx b/src/components/dialogs/MapListMoreDialog.jsx index 82fbafa..174326e 100644 --- a/src/components/dialogs/MapListMoreDialog.jsx +++ b/src/components/dialogs/MapListMoreDialog.jsx @@ -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 {
{ - list.map((route, index) => ( + list.map(route => ( )) } @@ -120,7 +119,6 @@ const mapStateToProps = ({ user: { editing, routes } }) => ({ }); const mapDispatchToProps = dispatch => bindActionCreators({ - searchSetAuthor, searchSetDistance, searchSetTitle, }, dispatch); diff --git a/src/components/panels/EditorPanel.jsx b/src/components/panels/EditorPanel.jsx index fa7c598..cf9619d 100644 --- a/src/components/panels/EditorPanel.jsx +++ b/src/components/panels/EditorPanel.jsx @@ -33,7 +33,7 @@ type Props = { class Component extends React.PureComponent { 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 { } 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); diff --git a/src/constants/api.js b/src/constants/api.js index b299d96..cb2466d 100644 --- a/src/constants/api.js +++ b/src/constants/api.js @@ -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`, }; diff --git a/src/redux/user/actions.js b/src/redux/user/actions.js index 27906fd..d4bb839 100644 --- a/src/redux/user/actions.js +++ b/src/redux/user/actions.js @@ -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 }) diff --git a/src/redux/user/constants.js b/src/redux/user/constants.js index e41beb9..7dd5d14 100644 --- a/src/redux/user/constants.js +++ b/src/redux/user/constants.js @@ -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 }); diff --git a/src/redux/user/reducer.js b/src/redux/user/reducer.js index 071d21f..9c2de66 100644 --- a/src/redux/user/reducer.js +++ b/src/redux/user/reducer.js @@ -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, diff --git a/src/redux/user/sagas.js b/src/redux/user/sagas.js index 0b27f7a..932298e 100644 --- a/src/redux/user/sagas.js +++ b/src/redux/user/sagas.js @@ -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); } diff --git a/src/utils/api.js b/src/utils/api.js index ff9fb99..f2f8853 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -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(() => ([]));