nominatim search (without working dialog)

This commit is contained in:
Fedor Katurov 2020-01-20 16:42:46 +07:00
parent c3e136cebb
commit b20a3445d1
27 changed files with 450 additions and 61 deletions

View file

@ -112,3 +112,13 @@ export const editorSetRouter = (router: Partial<IEditorState['router']>) => ({
type: EDITOR_ACTIONS.SET_ROUTER,
router,
});
export const editorSetNominatim = (nominatim: Partial<IEditorState['nominatim']>) => ({
type: EDITOR_ACTIONS.SET_NOMINATIM,
nominatim,
})
export const editorSearchNominatim = (search: IEditorState['nominatim']['search']) => ({
type: EDITOR_ACTIONS.SEARCH_NOMINATIM,
search,
})

View file

@ -44,4 +44,6 @@ export const EDITOR_ACTIONS = {
KEY_PRESSED: `${P}-KEY_PRESSED`,
SET_ROUTER: `${P}-SET_ROUTER`,
SET_NOMINATIM: `${P}-SET_NOMINATIM`,
SEARCH_NOMINATIM: `${P}-SEARCH_NOMINATIM`,
};

View file

@ -157,6 +157,17 @@ const setRouter = (
},
});
const setNominatim = (
state,
{ nominatim }: ReturnType<typeof ACTIONS.editorSetNominatim>
): IEditorState => ({
...state,
nominatim: {
...state.nominatim,
...nominatim,
},
});
export const EDITOR_HANDLERS = {
[EDITOR_ACTIONS.SET_EDITING]: setEditing,
[EDITOR_ACTIONS.SET_CHANGED]: setChanged,
@ -184,4 +195,5 @@ export const EDITOR_HANDLERS = {
[EDITOR_ACTIONS.SET_FEATURE]: setFeature,
[EDITOR_ACTIONS.SET_IS_ROUTING]: setIsRouting,
[EDITOR_ACTIONS.SET_ROUTER]: setRouter,
[EDITOR_ACTIONS.SET_NOMINATIM]: setNominatim,
};

View file

@ -1,8 +1,9 @@
import { createReducer } from '~/utils/reducer';
import { IDialogs } from '~/constants/dialogs';
import { DIALOGS } from '~/constants/dialogs';
import { MODES } from '~/constants/modes';
import { EDITOR_HANDLERS } from './handlers';
import { ILatLng } from '../map/types';
import { INominatimResult } from '~/redux/types';
export interface IEditorState {
changed: boolean;
@ -11,13 +12,13 @@ export interface IEditorState {
markers_shown: boolean;
router: {
points: ILatLng[];
points: ILatLng[];
waypoints: ILatLng[];
};
mode: typeof MODES[keyof typeof MODES];
dialog: IDialogs[keyof IDialogs];
dialog: typeof DIALOGS[keyof typeof DIALOGS];
dialog_active: boolean;
routerPoints: number;
@ -31,6 +32,13 @@ export interface IEditorState {
features: {
routing: boolean;
nominatim: boolean;
};
nominatim: {
search: string;
loading: boolean;
list: INominatimResult[];
};
renderer: {
@ -76,6 +84,13 @@ export const EDITOR_INITIAL_STATE = {
features: {
routing: false,
nominatim: false,
},
nominatim: {
search: '',
loading: false,
list: [],
},
renderer: {

View file

@ -1,5 +1,13 @@
import { call, put, takeEvery, takeLatest, select, race } from 'redux-saga/effects';
import { delay, SagaIterator } from 'redux-saga';
import {
call,
put,
takeEvery,
takeLatest,
select,
race,
takeLeading,
delay,
} from 'redux-saga/effects';
import { selectEditor, selectEditorMode } from '~/redux/editor/selectors';
import { simplify } from '~/utils/simplify';
import {
@ -14,13 +22,16 @@ import {
editorLocationChanged,
editorKeyPressed,
editorSetSave,
editorSearchNominatim,
editorSetDialog,
editorSetNominatim,
} from '~/redux/editor/actions';
import { getUrlData, pushPath } from '~/utils/history';
import { MODES } from '~/constants/modes';
import { checkOSRMService } from '~/utils/api';
import { checkOSRMService, checkNominatimService, searchNominatim } from '~/utils/api';
import { LatLng } from 'leaflet';
import { searchSetTab } from '../user/actions';
import { TABS } from '~/constants/dialogs';
import { TABS, DIALOGS } from '~/constants/dialogs';
import { EDITOR_ACTIONS } from './constants';
import { getGPXString, downloadGPXTrack } from '~/utils/gpx';
import {
@ -76,11 +87,17 @@ function* checkOSRMServiceSaga() {
yield put(editorSetFeature({ routing }));
}
function* checkNominatimSaga() {
const nominatim = yield call(checkNominatimService);
yield put(editorSetFeature({ nominatim }));
}
export function* setReadySaga() {
yield put(editorSetReady(true));
hideLoader();
yield call(checkOSRMServiceSaga);
yield call(checkNominatimSaga);
yield put(searchSetTab(TABS.MY));
}
@ -217,7 +234,7 @@ function* keyPressedSaga({ key, target }: ReturnType<typeof editorKeyPressed>) {
}
}
function* getGPXTrackSaga(): SagaIterator {
function* getGPXTrackSaga() {
const { route, stickers, title, address }: ReturnType<typeof selectMap> = yield select(selectMap);
if (!route.length && !stickers.length) return;
@ -259,6 +276,22 @@ function* cancelSave() {
);
}
function* searchNominatimSaga({ search }: ReturnType<typeof editorSearchNominatim>) {
const { dialog, dialog_active }: ReturnType<typeof selectEditor> = yield select(selectEditor);
if (dialog !== DIALOGS.NOMINATIM || !dialog_active) {
yield put(editorSetDialog(DIALOGS.NOMINATIM));
yield put(editorSetDialogActive(true));
}
yield put(editorSetNominatim({ loading: true, search }));
const list = yield call(searchNominatim, search);
yield put(editorSetNominatim({ list }));
yield delay(1000); // safely wait for 1s to prevent from ddosing nominatim
yield put(editorSetNominatim({ loading: false }));
}
export function* editorSaga() {
yield takeEvery(EDITOR_ACTIONS.LOCATION_CHANGED, locationChangeSaga);
@ -271,4 +304,5 @@ export function* editorSaga() {
yield takeLatest(MAP_ACTIONS.MAP_CLICKED, mapClick);
yield takeLatest(EDITOR_ACTIONS.ROUTER_SUBMIT, routerSubmit);
yield takeLatest(EDITOR_ACTIONS.CANCEL_SAVE, cancelSave);
yield takeLeading(EDITOR_ACTIONS.SEARCH_NOMINATIM, searchNominatimSaga);
}

View file

@ -8,3 +8,4 @@ export const selectEditorActiveSticker = (state: IState) => state.editor.activeS
export const selectEditorRenderer = (state: IState) => state.editor.renderer;
export const selectEditorRouter = (state: IState) => state.editor.router;
export const selectEditorDistance = (state: IState) => state.editor.distance;
export const selectEditorNominatim = (state: IState) => state.editor.nominatim;

View file

@ -7,6 +7,7 @@ import {
race,
take,
takeLatest,
delay,
} from 'redux-saga/effects';
import { MAP_ACTIONS } from './constants';
import {
@ -36,7 +37,6 @@ import { getStoredMap, postMap } from '~/utils/api';
import { Unwrap } from '~/utils/middleware';
import { selectMap, selectMapProvider, selectMapRoute, selectMapStickers } from './selectors';
import { TIPS } from '~/constants/tips';
import { delay } from 'redux-saga';
import { setReadySaga } from '../editor/sagas';
import { selectEditor } from '../editor/selectors';
import { EDITOR_ACTIONS } from '../editor/constants';

View file

@ -0,0 +1,7 @@
import { LatLngLiteral } from 'leaflet';
export interface INominatimResult {
id: number;
title: string;
latlng: LatLngLiteral;
};

View file

@ -1,6 +1,5 @@
import { REHYDRATE, RehydrateAction } from 'redux-persist';
import { delay, SagaIterator } from 'redux-saga';
import { takeLatest, select, call, put, takeEvery } from 'redux-saga/effects';
import { takeLatest, select, call, put, takeEvery, delay } from 'redux-saga/effects';
import {
checkIframeToken,
checkUserToken,
@ -34,7 +33,6 @@ import { selectUser, selectUserUser } from './selectors';
import { mapInitSaga } from '~/redux/map/sagas';
import { editorSetDialog, editorSetDialogActive } from '../editor/actions';
import { selectEditor } from '../editor/selectors';
import { getLocation, watchLocation } from '~/utils/window';
function* generateGuestSaga() {
const {
@ -198,7 +196,7 @@ function* searchSetTabSaga() {
yield put(searchSetTitle(''));
}
function* userLogoutSaga(): SagaIterator {
function* userLogoutSaga() {
yield put(setUser(DEFAULT_USER));
yield call(generateGuestSaga);
}
@ -256,7 +254,7 @@ function* mapsLoadMoreSaga() {
yield put(searchSetLoading(false));
}
function* dropRouteSaga({ address }: ReturnType<typeof ActionCreators.dropRoute>): SagaIterator {
function* dropRouteSaga({ address }: ReturnType<typeof ActionCreators.dropRoute>) {
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
const {
routes: {
@ -290,7 +288,7 @@ function* modifyRouteSaga({
address,
title,
is_public,
}: ReturnType<typeof ActionCreators.modifyRoute>): SagaIterator {
}: ReturnType<typeof ActionCreators.modifyRoute>) {
const { token }: ReturnType<typeof selectUserUser> = yield select(selectUserUser);
const {
routes: {