-
+
+
{
+ if (customModelEnabled) Dispatcher.dispatch(new DismissLastError())
+ Dispatcher.dispatch(new ClearRoute())
+ Dispatcher.dispatch(new SetCustomModelEnabled(!customModelEnabled))
+ }}
+ >
+ {customModelEnabled ? : }
+
+
{tr('custom_model_enabled')}
+
+
+
+
-
- {tr('help_custom_model')}
-
-
+ {tr('help_custom_model')}
+
+
+
{
+ if (!customModelEnabled) Dispatcher.dispatch(new SetCustomModelEnabled(true))
+ Dispatcher.dispatch(new SetCustomModel(editor.value, true))
+ }}
>
- dispatchCustomModel(editor.value, true, true)}
- >
- {tr('apply_custom_model')}
-
- {queryOngoing && }
-
+ {tr('apply_custom_model')}
+
+ {queryOngoing &&
}
- )}
+
>
)
}
-
-function dispatchCustomModel(customModelString: string, isValid: boolean, withRouteRequest: boolean) {
- try {
- const parsedValue = JSON.parse(customModelString)
- Dispatcher.dispatch(new SetCustomModel(parsedValue, isValid, withRouteRequest))
- } catch (e) {
- Dispatcher.dispatch(new SetCustomModel(null, false, withRouteRequest))
- }
-}
-
-function customModel2prettyString(customModel: CustomModel) {
- return JSON.stringify(customModel, null, 2)
-}
diff --git a/src/sidebar/CustomModelExamples.ts b/src/sidebar/CustomModelExamples.ts
new file mode 100644
index 00000000..8e4511aa
--- /dev/null
+++ b/src/sidebar/CustomModelExamples.ts
@@ -0,0 +1,63 @@
+import { CustomModel } from '@/stores/QueryStore'
+
+export const customModelExamples: { [key: string]: CustomModel } = {
+ default_example: {
+ distance_influence: 15,
+ priority: [{ if: 'road_environment == FERRY', multiply_by: '0.9' }],
+ speed: [],
+ areas: {
+ type: 'FeatureCollection',
+ features: [],
+ },
+ },
+ exclude_motorway: {
+ priority: [{ if: 'road_class == MOTORWAY', multiply_by: '0.0' }],
+ },
+ limit_speed: {
+ speed: [
+ { if: 'true', limit_to: '100' },
+ { if: 'road_class == TERTIARY', limit_to: '80' },
+ ],
+ },
+ exclude_area: {
+ priority: [{ if: 'in_berlin_bbox', multiply_by: '0' }],
+ areas: {
+ type: 'FeatureCollection',
+ features: [
+ {
+ type: 'Feature',
+ id: 'berlin_bbox',
+ properties: {},
+ geometry: {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [13.253, 52.608],
+ [13.228, 52.437],
+ [13.579, 52.447],
+ [13.563, 52.609],
+ [13.253, 52.608],
+ ],
+ ],
+ },
+ },
+ ],
+ },
+ },
+ cargo_bike: {
+ speed: [{ if: 'road_class == TRACK', limit_to: '2' }],
+ priority: [{ if: 'max_width < 1.5 || road_class == STEPS', multiply_by: '0' }],
+ },
+ combined: {
+ distance_influence: 100,
+ speed: [{ if: 'road_class == TRACK || road_environment == FERRY || surface == DIRT', limit_to: '10' }],
+ priority: [
+ { if: 'road_environment == TUNNEL || toll == ALL', multiply_by: '0.5' },
+ { if: 'max_weight < 3 || max_height < 2.5', multiply_by: '0.0' },
+ ],
+ },
+}
+
+export function customModel2prettyString(customModel: CustomModel) {
+ return JSON.stringify(customModel, null, 2)
+}
diff --git a/src/sidebar/MobileSidebar.tsx b/src/sidebar/MobileSidebar.tsx
index 1c683f19..c7807619 100644
--- a/src/sidebar/MobileSidebar.tsx
+++ b/src/sidebar/MobileSidebar.tsx
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef, useState } from 'react'
-import { QueryPoint, QueryPointType, QueryStoreState } from '@/stores/QueryStore'
+import { QueryPoint, QueryPointType, QueryStoreState, RequestState } from '@/stores/QueryStore'
import { RouteStoreState } from '@/stores/RouteStore'
import { ErrorStoreState } from '@/stores/ErrorStore'
import styles from './MobileSidebar.module.css'
@@ -10,14 +10,19 @@ import { MarkerComponent } from '@/map/Marker'
import RoutingProfiles from '@/sidebar/search/routingProfiles/RoutingProfiles'
import OpenInputsIcon from './unfold.svg'
import CloseInputsIcon from './unfold_less.svg'
+import CustomModelBox from '@/sidebar/CustomModelBox'
+import { Settings } from '@/stores/SettingsStore'
type MobileSidebarProps = {
query: QueryStoreState
route: RouteStoreState
error: ErrorStoreState
+ encodedValues: object[]
+ settings: Settings
}
-export default function ({ query, route, error }: MobileSidebarProps) {
+export default function ({ query, route, error, encodedValues, settings }: MobileSidebarProps) {
+ const [showCustomModelBox, setShowCustomModelBox] = useState(false)
// the following three elements control, whether the small search view is displayed
const isShortScreen = useMediaQuery({ query: '(max-height: 55rem)' })
const [isSmallSearchView, setIsSmallSearchView] = useState(isShortScreen && hasResult(route))
@@ -55,9 +60,18 @@ export default function ({ query, route, error }: MobileSidebarProps) {
setShowCustomModelBox(!showCustomModelBox)}
+ customModelBoxEnabled={query.customModelEnabled}
/>
+ {showCustomModelBox && (
+
+ )}
)}
diff --git a/src/sidebar/SettingsBox.module.css b/src/sidebar/SettingsBox.module.css
new file mode 100644
index 00000000..660a2e4d
--- /dev/null
+++ b/src/sidebar/SettingsBox.module.css
@@ -0,0 +1,50 @@
+.parent {
+ margin-top: 15px;
+ padding: 15px 5px 10px 5px;
+ border-top: 1px lightgray solid;
+ border-bottom: 1px lightgray solid;
+}
+
+.settingsTable {
+ display: grid;
+ grid-template-columns: 50px auto;
+ grid-template-rows: 1.3rem;
+ align-content: flex-start;
+ align-items: center;
+ margin: 1rem 0.5rem 1.5rem 0;
+}
+
+.settingsTable svg {
+ scale: 0.7;
+ margin-left: calc(-8px); /* scaling svg creates white space around it */
+}
+
+.settingsTable button {
+}
+
+.infoLine {
+ padding: 10px 2px 0 0;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+}
+
+.infoLine a {
+ color: gray;
+ text-decoration: none;
+}
+
+.infoLine a:hover {
+ color: black;
+}
+
+.title {
+ font-weight: bold;
+}
+
+.title,
+.infoLine,
+.settingsTable {
+ font-size: 14px;
+ color: gray;
+}
diff --git a/src/sidebar/SettingsBox.tsx b/src/sidebar/SettingsBox.tsx
new file mode 100644
index 00000000..d1a08f06
--- /dev/null
+++ b/src/sidebar/SettingsBox.tsx
@@ -0,0 +1,36 @@
+import { ToggleDistanceUnits } from '@/actions/Actions'
+import Dispatcher from '@/stores/Dispatcher'
+import styles from '@/sidebar/SettingsBox.module.css'
+import { tr } from '@/translation/Translation'
+import PlainButton from '@/PlainButton'
+import OnIcon from '@/sidebar/toggle_on.svg'
+import OffIcon from '@/sidebar/toggle_off.svg'
+import { useContext } from 'react'
+import { ShowDistanceInMilesContext } from '@/ShowDistanceInMilesContext'
+
+export default function SettingsBox() {
+ const showDistanceInMiles = useContext(ShowDistanceInMilesContext)
+ return (
+