Skip to content

Commit

Permalink
merged master
Browse files Browse the repository at this point in the history
  • Loading branch information
karussell committed Dec 17, 2024
2 parents 674a473 + f7d073f commit 7ace38f
Show file tree
Hide file tree
Showing 13 changed files with 497 additions and 500 deletions.
1 change: 0 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const config = {
'track_type',
'country',
],
snapPreventions: ['ferry'],
},

// Use 'profiles' to define which profiles are visible and how. Useful if the /info endpoint contains too many or too "ugly" profile
Expand Down
826 changes: 432 additions & 394 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"custom-model-editor": "github:graphhopper/custom-model-editor#3a46b6981d170b7eb70d621bbb92caed149e5a97",
"geojson": "^0.5.0",
"heightgraph": "github:easbar/Leaflet.Heightgraph#5f4f0b1fff3646aa071981381f5955c9e6f111f0",
"ol": "9.2.3",
"ol-mapbox-style": "12.3.2",
"ol": "10.2.1",
"ol-mapbox-style": "12.3.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-responsive": "^9.0.0"
Expand Down
3 changes: 2 additions & 1 deletion src/api/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,12 @@ export class ApiImpl implements Api {
locale: getTranslation().getLang(),
points_encoded: true,
points_encoded_multiplier: 1e6,
snap_preventions: config.request?.snapPreventions ? config.request.snapPreventions : [],
...profileConfig,
details: details,
}

if (config.request?.snapPreventions) request.snap_preventions = config.request?.snapPreventions

if (args.customModel) {
request['ch.disable'] = true
request.custom_model = args.customModel
Expand Down
2 changes: 1 addition & 1 deletion src/layers/UseQueryPointsLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function removeDragInteractions(map: Map) {
.forEach(i => map.removeInteraction(i))
}

function addDragInteractions(map: Map, queryPointsLayer: VectorLayer<Feature<Geometry>>) {
function addDragInteractions(map: Map, queryPointsLayer: VectorLayer<VectorSource<Feature<Geometry>>>) {
let tmp = queryPointsLayer.getSource()
if (tmp == null) throw new Error('source must not be null') // typescript requires this
const modify = new Modify({
Expand Down
11 changes: 11 additions & 0 deletions src/sidebar/search/AddressInput.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
scale: 0.7;
}

.btnCurrentLocation {
padding: 0 7px 0 5px;
color: grey;
width: 32px;
}

.btnCurrentLocation > svg {
height: 100%;
width: 100%;
}

.btnClose {
display: none;
}
Expand Down
83 changes: 42 additions & 41 deletions src/sidebar/search/AddressInput.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'
import { Coordinate, getBBoxFromCoord, QueryPoint, QueryPointType } from '@/stores/QueryStore'
import { Bbox, GeocodingHit, ReverseGeocodingHit } from '@/api/graphhopper'
import Autocomplete, {
AutocompleteItem,
GeocodingItem,
POIQueryItem,
SelectCurrentLocationItem,
} from '@/sidebar/search/AddressInputAutocomplete'
import Autocomplete, { AutocompleteItem, GeocodingItem, POIQueryItem } from '@/sidebar/search/AddressInputAutocomplete'

import ArrowBack from './arrow_back.svg'
import Cross from '@/sidebar/times-solid-thin.svg'
import CurrentLocationIcon from './current-location.svg'
import styles from './AddressInput.module.css'
import Api, { ApiImpl, getApi } from '@/api/Api'
import Api, { getApi } from '@/api/Api'
import { tr } from '@/translation/Translation'
import { coordinateToText, hitToItem, nominatimHitToItem, textToCoordinate } from '@/Converters'
import { useMediaQuery } from 'react-responsive'
Expand Down Expand Up @@ -78,17 +74,6 @@ export default function AddressInput(props: AddressInputProps) {

// if item is selected we need to clear the autocompletion list
useEffect(() => setAutocompleteItems([]), [props.point])
// if no items but input is selected show current location item
useEffect(() => {
if (hasFocus && text.length == 0 && autocompleteItems.length === 0)
setAutocompleteItems([new SelectCurrentLocationItem()])
}, [autocompleteItems, hasFocus])

function hideSuggestions() {
geocoder.cancel()
setOrigAutocompleteItems(autocompleteItems)
setAutocompleteItems([])
}

// highlighted result of geocoding results. Keep track which index is highlighted and change things on ArrowUp and Down
// on Enter select highlighted result or the 0th if nothing is highlighted
Expand All @@ -103,13 +88,9 @@ export default function AddressInput(props: AddressInputProps) {

const onKeypress = useCallback(
(event: React.KeyboardEvent<HTMLInputElement>) => {
const inputElement = event.target as HTMLInputElement
if (event.key === 'Escape') {
inputElement.blur()
// onBlur is deactivated for mobile so force:
setHasFocus(false)
setText(origText)
hideSuggestions()
searchInput.current!.blur()
return
}

Expand Down Expand Up @@ -146,7 +127,7 @@ export default function AddressInput(props: AddressInputProps) {
if (item instanceof POIQueryItem) {
handlePoiSearch(poiSearch, item.result, props.map)
props.onAddressSelected(item.result.text(item.result.poi), undefined)
} else if (highlightedResult < 0) {
} else if (highlightedResult < 0 && !props.point.isInitialized) {
// by default use the first result, otherwise the highlighted one
getApi()
.geocode(text, 'nominatim')
Expand All @@ -163,10 +144,8 @@ export default function AddressInput(props: AddressInputProps) {
props.onAddressSelected(item.toText(), item.point)
}
}
inputElement.blur()
// onBlur is deactivated for mobile so force:
setHasFocus(false)
hideSuggestions()
// do not disturb 'tab' cycle
if (event.key == 'Enter') searchInput.current!.blur()
break
}
},
Expand All @@ -181,6 +160,9 @@ export default function AddressInput(props: AddressInputProps) {
const lonlat = toLonLat(getMap().getView().getCenter()!)
const biasCoord = { lng: lonlat[0], lat: lonlat[1] }

// do not focus on mobile as we would hide the map with the "input"-view
const focusFirstInput = props.index == 0 && !isSmallScreen

return (
<div className={containerClass}>
<div
Expand All @@ -197,17 +179,18 @@ export default function AddressInput(props: AddressInputProps) {
>
<PlainButton
className={styles.btnClose}
onClick={() => {
setHasFocus(false)
hideSuggestions()
}}
onMouseDown={
e => e.preventDefault() // prevents that input->onBlur is called when just "mouse down" event (lose focus only for onClick)
}
onClick={() => searchInput.current!.blur()}
>
<ArrowBack />
</PlainButton>
<input
style={props.moveStartIndex == props.index ? { borderWidth: '2px', margin: '-1px' } : {}}
className={styles.input}
type="text"
autoFocus={focusFirstInput}
ref={searchInput}
autoComplete="off"
onChange={e => {
Expand All @@ -224,7 +207,10 @@ export default function AddressInput(props: AddressInputProps) {
if (origAutocompleteItems.length > 0) setAutocompleteItems(origAutocompleteItems)
}}
onBlur={() => {
if (!isSmallScreen) hideSuggestions() // see #398
setHasFocus(false)
geocoder.cancel()
setOrigAutocompleteItems(autocompleteItems)
setAutocompleteItems([])
}}
value={text}
placeholder={tr(
Expand All @@ -233,17 +219,38 @@ export default function AddressInput(props: AddressInputProps) {
/>

<PlainButton
tabIndex={-1}
style={text.length == 0 ? { display: 'none' } : {}}
className={styles.btnInputClear}
onClick={() => {
onMouseDown={
e => e.preventDefault() // prevents that input->onBlur is called when clicking the button (would hide this button and prevent onClick)
}
onClick={e => {
setText('')
props.onChange('')
// if we clear the text without focus then explicitly request it to improve usability:
searchInput.current!.focus()
}}
>
<Cross />
</PlainButton>

<PlainButton
tabIndex={-1}
style={text.length == 0 && hasFocus ? {} : { display: 'none' }}
className={styles.btnCurrentLocation}
onMouseDown={
e => e.preventDefault() // prevents that input->onBlur is called when clicking the button (would hide this button and prevent onClick)
}
onClick={() => {
onCurrentLocationSelected(props.onAddressSelected)
// but when clicked => we want to lose the focus e.g. to close mobile-input view
searchInput.current!.blur()
}}
>
<CurrentLocationIcon />
</PlainButton>

{autocompleteItems.length > 0 && (
<ResponsiveAutocomplete
inputRef={searchInputContainer.current!}
Expand All @@ -254,19 +261,13 @@ export default function AddressInput(props: AddressInputProps) {
items={autocompleteItems}
highlightedItem={autocompleteItems[highlightedResult]}
onSelect={item => {
setHasFocus(false)
if (item instanceof GeocodingItem) {
hideSuggestions()
props.onAddressSelected(item.toText(), item.point)
} else if (item instanceof SelectCurrentLocationItem) {
hideSuggestions()
onCurrentLocationSelected(props.onAddressSelected)
} else if (item instanceof POIQueryItem) {
hideSuggestions()
handlePoiSearch(poiSearch, item.result, props.map)
setText(item.result.text(item.result.poi))
}
searchInput.current!.blur()
searchInput.current!.blur() // see also AutocompleteEntry->onMouseDown
}}
/>
</ResponsiveAutocomplete>
Expand Down
17 changes: 0 additions & 17 deletions src/sidebar/search/AddressInputAutocomplete.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,6 @@
background-color: #c6c6c6;
}

.currentLocationEntry {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
margin: 0.5rem 0.5rem;
}

.currentLocationIcon {
width: 1.2rem;
}

.currentLocationIcon > svg {
height: 100%;
width: 100%;
}

.poiEntry {
padding: 0.5em 0;
display: flex;
Expand Down
32 changes: 4 additions & 28 deletions src/sidebar/search/AddressInputAutocomplete.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import styles from './AddressInputAutocomplete.module.css'
import CurrentLocationIcon from './current-location.svg'
import { tr } from '@/translation/Translation'
import { Bbox } from '@/api/graphhopper'
import { AddressParseResult } from '@/pois/AddressParseResult'

Expand All @@ -24,8 +22,6 @@ export class GeocodingItem implements AutocompleteItem {
}
}

export class SelectCurrentLocationItem implements AutocompleteItem {}

export class POIQueryItem implements AutocompleteItem {
result: AddressParseResult

Expand Down Expand Up @@ -55,8 +51,6 @@ export default function Autocomplete({ items, highlightedItem, onSelect }: Autoc
function mapToComponent(item: AutocompleteItem, isHighlighted: boolean, onSelect: (hit: AutocompleteItem) => void) {
if (item instanceof GeocodingItem)
return <GeocodingEntry item={item} isHighlighted={isHighlighted} onSelect={onSelect} />
else if (item instanceof SelectCurrentLocationItem)
return <SelectCurrentLocation item={item} isHighlighted={isHighlighted} onSelect={onSelect} />
else if (item instanceof POIQueryItem)
return <POIQueryEntry item={item} isHighlighted={isHighlighted} onSelect={onSelect} />
else throw Error('Unsupported item type: ' + typeof item)
Expand All @@ -82,27 +76,6 @@ export function POIQueryEntry({
)
}

export function SelectCurrentLocation({
item,
isHighlighted,
onSelect,
}: {
item: SelectCurrentLocationItem
isHighlighted: boolean
onSelect: (item: SelectCurrentLocationItem) => void
}) {
return (
<AutocompleteEntry isHighlighted={isHighlighted} onSelect={() => onSelect(item)}>
<div className={styles.currentLocationEntry}>
<div className={styles.currentLocationIcon}>
<CurrentLocationIcon />
</div>
<span className={styles.mainText}>{tr('current_location')}</span>
</div>
</AutocompleteEntry>
)
}

function GeocodingEntry({
item,
isHighlighted,
Expand Down Expand Up @@ -137,12 +110,15 @@ function AutocompleteEntry({
className={className}
// using click events for mouse interaction and touch end to select an entry.
onClick={() => onSelect()}
// minor workaround to improve success rate for click even if start and end location on screen are slightly different
onTouchEnd={e => {
e.preventDefault() // do not forward click to underlying component
onSelect()
}}
onMouseDown={e => {
e.preventDefault() // prevent blur event for our input, see #398
// prevents that input->onBlur is called when clicking the autocomplete item (focus would be lost and autocomplete items would disappear before they can be clicked)
// See also the onMouseDown calls in the buttons in AddressInput.tsx created for the same reason.
e.preventDefault()
}}
>
{children}
Expand Down
9 changes: 0 additions & 9 deletions src/sidebar/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,6 @@ const SearchBox = ({
}) => {
const point = points[index]

// With this ref and tabIndex=-1 we ensure that the first 'TAB' gives the focus the first input but the marker won't be included in the TAB sequence, #194
const myMarkerRef = useRef<HTMLDivElement>(null)

useEffect(() => {
if (index == 0) myMarkerRef.current?.focus()
}, [])

function onClickOrDrop() {
onDropPreviewSelect(-1)
const newIndex = moveStartIndex < index ? index + 1 : index
Expand All @@ -122,8 +115,6 @@ const SearchBox = ({
<>
{(moveStartIndex < 0 || moveStartIndex == index) && (
<div
ref={myMarkerRef}
tabIndex={-1}
title={tr('drag_to_reorder')}
className={styles.markerContainer}
draggable
Expand Down
2 changes: 1 addition & 1 deletion src/stores/QueryStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export default class QueryStore extends Store<QueryStoreState> {
...state,
queryPoints: newPoints,
}
return this.routeIfReady(newState, true)
return this.routeIfReady(newState, false)
} else if (action instanceof InfoReceived) {
// Do nothing if no routing profiles were received
if (action.result.profiles.length <= 0) return state
Expand Down
4 changes: 0 additions & 4 deletions test/routing/Api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ describe('route', () => {
locale: 'en_US',
points_encoded: true,
points_encoded_multiplier: 1e6,
snap_preventions: ['ferry'],
details: [
'road_class',
'road_environment',
Expand Down Expand Up @@ -155,7 +154,6 @@ describe('route', () => {
locale: 'en_US',
points_encoded: true,
points_encoded_multiplier: 1e6,
snap_preventions: ['ferry'],
details: [
'road_class',
'road_environment',
Expand Down Expand Up @@ -207,7 +205,6 @@ describe('route', () => {
locale: 'en_US',
points_encoded: true,
points_encoded_multiplier: 1e6,
snap_preventions: ['ferry'],
details: [
'road_class',
'road_environment',
Expand Down Expand Up @@ -315,7 +312,6 @@ describe('route', () => {
locale: 'de_DE',
points_encoded: true,
points_encoded_multiplier: 1e6,
snap_preventions: ['ferry'],
details: [
'road_class',
'road_environment',
Expand Down
Loading

0 comments on commit 7ace38f

Please sign in to comment.