Skip to content

Commit 710a9a5

Browse files
karusselleasbar
andauthored
Allow custom model for mobile devices (plus separate settings panel) (#316)
* initial version * custom model is kept even when switching back and forth between desktop and mobile size * fix bug when mobile view is changed to compact view and no new route is calculated because of an invalid custom model due to missing encoded values (recreation of CustomModelBox without the previously expected /info endpoint being called) * move CustomModelBox into SettingsBox but outside of settingsTable * minor -> warn * minor css fix * make settings css better fit the rest * 1. URL with custom_model should trigger a routing request with it; 2. avoid route re-calculation if settings box is shown; 3. invalid custom model is reset to custom model before if settings box is closed * tricky to fix error 'Cannot use import statement outside a module' in tests: 1. insist on transpiling custom model editor code to avoid ES6 modules for jest and 2. allowJs in tsconfig and 3. explicitly transform js files using ts-jest - why? * remove CustomModel from QueryStore state * formatting * revert change with SettingsContext to use ShowDistanceInMilesContext * format and clean up imports * show error message if invalid custom model (not possible at Settings construction time) * not many benefits to use validateJson as e.g. encoded values not yet known * revert commit 96108d7 * remove TODO NOW * Use string to represent custom model state (#320) * Move custom model examples to separate file * Minor rename * Extract custom model area function * Remove openSettingsHandle * Rename custom model examples file * Remove warning that can never occur * Move state from settings to query store, query store even depended on settings.. * minor * move custom model box out of settings * oops, made a mistake * Use string to represent custom model state! * much better * add todos * Rename action * no shadow, use text instead * i18n: update * separate custom model box and settings box and use gear as indicator instead of shadow * format --------- Co-authored-by: easbar <easbar.mail@posteo.net>
1 parent e8000dd commit 710a9a5

19 files changed

+651
-344
lines changed

src/App.tsx

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Menu from '@/sidebar/menu.svg'
4141
import Cross from '@/sidebar/times-solid.svg'
4242
import PlainButton from '@/PlainButton'
4343
import useAreasLayer from '@/layers/UseAreasLayer'
44+
import { Settings } from '@/stores/SettingsStore'
4445

4546
export const POPUP_CONTAINER_ID = 'popup-container'
4647
export const SIDEBAR_CONTENT_ID = 'sidebar-content'
@@ -99,7 +100,7 @@ export default function App() {
99100
// our different map layers
100101
useBackgroundLayer(map, mapOptions.selectedStyle)
101102
useMapBorderLayer(map, info.bbox)
102-
useAreasLayer(map, query.customModelEnabled && query.customModelValid ? query.customModel?.areas! : null)
103+
useAreasLayer(map, getCustomModelAreas(query))
103104
useRoutingGraphLayer(map, mapOptions.routingGraphEnabled)
104105
useUrbanDensityLayer(map, mapOptions.urbanDensityEnabled)
105106
usePathsLayer(map, route.routingResult.paths, route.selectedPath)
@@ -119,6 +120,7 @@ export default function App() {
119120
mapOptions={mapOptions}
120121
error={error}
121122
encodedValues={info.encoded_values}
123+
settings={settings}
122124
/>
123125
) : (
124126
<LargeScreenLayout
@@ -128,6 +130,7 @@ export default function App() {
128130
mapOptions={mapOptions}
129131
error={error}
130132
encodedValues={info.encoded_values}
133+
settings={settings}
131134
/>
132135
)}
133136
</div>
@@ -142,10 +145,12 @@ interface LayoutProps {
142145
mapOptions: MapOptionsStoreState
143146
error: ErrorStoreState
144147
encodedValues: object[]
148+
settings: Settings
145149
}
146150

147151
function LargeScreenLayout({ query, route, map, error, mapOptions, encodedValues }: LayoutProps) {
148152
const [showSidebar, setShowSidebar] = useState(true)
153+
const [showCustomModelBox, setShowCustomModelBox] = useState(false)
149154
return (
150155
<>
151156
{showSidebar ? (
@@ -157,15 +162,18 @@ function LargeScreenLayout({ query, route, map, error, mapOptions, encodedValues
157162
<RoutingProfiles
158163
routingProfiles={query.profiles}
159164
selectedProfile={query.routingProfile}
160-
customModelAllowed={true}
161-
customModelEnabled={query.customModelEnabled}
162-
/>
163-
<CustomModelBox
164-
enabled={query.customModelEnabled}
165-
encodedValues={encodedValues}
166-
initialCustomModelStr={query.initialCustomModelStr}
167-
queryOngoing={query.currentRequest.subRequests[0]?.state === RequestState.SENT}
165+
showCustomModelBox={showCustomModelBox}
166+
toggleCustomModelBox={() => setShowCustomModelBox(!showCustomModelBox)}
167+
customModelBoxEnabled={query.customModelEnabled}
168168
/>
169+
{showCustomModelBox && (
170+
<CustomModelBox
171+
customModelEnabled={query.customModelEnabled}
172+
encodedValues={encodedValues}
173+
customModelStr={query.customModelStr}
174+
queryOngoing={query.currentRequest.subRequests[0]?.state === RequestState.SENT}
175+
/>
176+
)}
169177
<Search points={query.queryPoints} />
170178
<div>{!error.isDismissed && <ErrorMessage error={error} />}</div>
171179
<RoutingResults
@@ -201,11 +209,17 @@ function LargeScreenLayout({ query, route, map, error, mapOptions, encodedValues
201209
)
202210
}
203211

204-
function SmallScreenLayout({ query, route, map, error, mapOptions }: LayoutProps) {
212+
function SmallScreenLayout({ query, route, map, error, mapOptions, encodedValues, settings }: LayoutProps) {
205213
return (
206214
<>
207215
<div className={styles.smallScreenSidebar}>
208-
<MobileSidebar query={query} route={route} error={error} />
216+
<MobileSidebar
217+
query={query}
218+
route={route}
219+
error={error}
220+
encodedValues={encodedValues}
221+
settings={settings}
222+
/>
209223
</div>
210224
<div className={styles.smallScreenMap}>
211225
<MapComponent map={map} />
@@ -231,3 +245,12 @@ function SmallScreenLayout({ query, route, map, error, mapOptions }: LayoutProps
231245
</>
232246
)
233247
}
248+
249+
function getCustomModelAreas(queryStoreState: QueryStoreState): object | null {
250+
if (!queryStoreState.customModelEnabled) return null
251+
try {
252+
return JSON.parse(queryStoreState.customModelStr)['areas']
253+
} catch {
254+
return null
255+
}
256+
}

src/NavBar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ export default class NavBar {
3636

3737
result.searchParams.append('profile', queryStoreState.routingProfile.name)
3838
result.searchParams.append('layer', mapState.selectedStyle.name)
39-
if (queryStoreState.customModelEnabled && queryStoreState.customModel && queryStoreState.customModelValid)
40-
result.searchParams.append('custom_model', JSON.stringify(queryStoreState.customModel))
39+
if (queryStoreState.customModelEnabled)
40+
result.searchParams.append('custom_model', queryStoreState.customModelStr.replace(/\s+/g, ''))
4141

4242
return result
4343
}

src/actions/Actions.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class InvalidatePoint implements Action {
7777
}
7878
}
7979

80-
export class SetCustomModelBoxEnabled implements Action {
80+
export class SetCustomModelEnabled implements Action {
8181
readonly enabled: boolean
8282

8383
constructor(enabled: boolean) {
@@ -86,14 +86,12 @@ export class SetCustomModelBoxEnabled implements Action {
8686
}
8787

8888
export class SetCustomModel implements Action {
89-
readonly customModel: CustomModel | null
90-
readonly valid: boolean
91-
readonly issueRouteRequest
92-
93-
constructor(customModel: CustomModel | null, valid: boolean, issueRouteRequest = false) {
94-
this.customModel = customModel
95-
this.valid = valid
96-
this.issueRouteRequest = issueRouteRequest
89+
readonly customModelStr: string
90+
readonly issueRoutingRequest: boolean
91+
92+
constructor(customModelStr: string, issueRoutingRequest: boolean) {
93+
this.customModelStr = customModelStr
94+
this.issueRoutingRequest = issueRoutingRequest
9795
}
9896
}
9997

src/sidebar/CustomModelBox.module.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
height: 18rem;
66
}
77

8+
.customModelOptionTable {
9+
display: grid;
10+
font-size: 14px;
11+
grid-template-columns: 15% auto;
12+
grid-template-rows: 1.3rem;
13+
align-content: center;
14+
align-items: center;
15+
margin: 1.5rem 0.5rem 0.5rem 0;
16+
}
17+
18+
.customModelOptionTable svg {
19+
scale: 0.7;
20+
}
21+
822
#element::-webkit-scrollbar {
923
display: none;
1024
}

0 commit comments

Comments
 (0)