Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: hide other direction vehicles. #41

Merged
merged 1 commit into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="description"
content="Maps to find your next bus in real-time, schedule alerts, view schedules and more." />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
Expand Down
12 changes: 8 additions & 4 deletions packages/ui/src/components/formItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface LabelProps {
grow: number
gap: string
justifyContent: string
alignItems: string
fontSize: string
fontWeight: FontWeight
}
Expand All @@ -25,12 +26,12 @@ const getFlexDirection = ({ direction }: LabelProps) => {
return 'column'
}
}
const getAlignItems = ({ direction }: LabelProps) => {
if (direction === 'vertical') {
return 'normal'
const getAlignItems = ({ alignItems }: LabelProps) => {
if (alignItems) {
return alignItems
}

return 'center'
return 'normal'
}
const getGap = ({ direction, gap }: LabelProps) => {
if (gap) {
Expand Down Expand Up @@ -89,6 +90,7 @@ interface FormItemProps {
gap?: string
grow?: number
justifyContent?: string
alignItems?: string
fontWeight?: FontWeight
fontSize?: string
}
Expand All @@ -100,6 +102,7 @@ const FormItem: FC<FormItemProps> = ({
gap = '4px',
grow = 0,
justifyContent = 'normal',
alignItems = 'normal',
fontWeight = 'bold',
fontSize = '14px'
}) => {
Expand All @@ -109,6 +112,7 @@ const FormItem: FC<FormItemProps> = ({
gap={gap}
grow={grow}
justifyContent={justifyContent}
alignItems={alignItems}
fontWeight={fontWeight}
fontSize={fontSize}>
<span>{label ?? ''}</span>
Expand Down
24 changes: 20 additions & 4 deletions packages/ui/src/components/settings/vehicle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ const VehicleSettings: FC = () => {
value: !vehicle.markPredictedVehicles
})
}, [vehicle])
const onToggleHideOtherDirections = useCallback(() => {
vehicle.dispatch({
type: 'hideOtherDirections',
value: !vehicle.hideOtherDirections
})
}, [vehicle])
const onChangeSpeedUnit = useCallback(
(evt: ChangeEvent<HTMLInputElement>) => {
vehicle.dispatch({
Expand All @@ -64,23 +70,33 @@ const VehicleSettings: FC = () => {
label="Visible"
direction="horizontal-rev"
justifyContent="flex-end"
fontWeight="normal"
grow={0}>
fontWeight="normal">
<input type="checkbox" checked={vehicle.visible} onChange={onChangeVisible} />
</FormItem>
<FormItem
label="Color predicted"
direction="horizontal-rev"
justifyContent="flex-end"
fontWeight="normal"
grow={0}>
fontWeight="normal">
<input
type="checkbox"
disabled={!vehicle.visible}
checked={vehicle.markPredictedVehicles}
onChange={onTogglePredictedVehicles}
/>
</FormItem>
<FormItem
label="Hide other directions"
direction="horizontal-rev"
justifyContent="flex-end"
fontWeight="normal">
<input
type="checkbox"
disabled={!vehicle.visible}
checked={vehicle.hideOtherDirections}
onChange={onToggleHideOtherDirections}
/>
</FormItem>
<fieldset className="row">
<legend>Speed units</legend>
<FormItem label="kph" fontWeight="normal" direction="horizontal-rev">
Expand Down
14 changes: 13 additions & 1 deletion packages/ui/src/contexts/settings/vehicle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { FC, ReactNode, Dispatch } from 'react'
type SpeedUnit = 'kph' | 'mph'
interface VehicleSettingsState {
visible: boolean
hideOtherDirections: boolean
markPredictedVehicles: boolean
speedUnit: SpeedUnit
dispatch: Dispatch<VehicleSettingsAction>
Expand All @@ -21,19 +22,30 @@ interface VisibileChanged {
type: 'visibile'
value: boolean
}
type VehicleSettingsAction = VisibileChanged | SpeedUnitChanged | MarkPredictedVehicles
interface HideOtherDirectionsChanged {
type: 'hideOtherDirections'
value: boolean
}
type VehicleSettingsAction =
| VisibileChanged
| SpeedUnitChanged
| MarkPredictedVehicles
| HideOtherDirectionsChanged

const defaultState: VehicleSettingsState = {
dispatch: () => {},
speedUnit: 'kph',
visible: true,
hideOtherDirections: false,
markPredictedVehicles: true
}
const VehicleSettings = createContext<VehicleSettingsState>(defaultState)
const reducer = (state: VehicleSettingsState, action: VehicleSettingsAction) => {
switch (action.type) {
case 'visibile':
return { ...state, visible: action.value }
case 'hideOtherDirections':
return { ...state, hideOtherDirections: action.value }
case 'speedUnit':
return { ...state, speedUnit: action.value }
case 'markPredictedVehicles':
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ aside.collapsed {
clip-path: polygon(0% 50%, 100% 35%, 100% 65%);
transform: rotate(-45deg);
}
.busmap-vehicle.hidden {
display: none;
}
.busmap-vehicle div {
display: flex;
align-items: center;
Expand Down
45 changes: 30 additions & 15 deletions packages/ui/src/hooks/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,51 @@ import type { MarkerOptions, LatLng } from 'leaflet'
import type { Vehicle } from '../types.js'
import type { SpeedUnit } from '../contexts/settings/vehicle.js'

interface VehicleMarkerConfig {
vehicle: Vehicle
speedUnit: SpeedUnit
hidden: boolean
}

class VehicleMarker extends Marker {
#vehicle: Vehicle
#speedUnit: SpeedUnit

constructor(
latlng: LatLng,
vehicle: Vehicle,
speedUnit: SpeedUnit,
options?: MarkerOptions
) {
#config: VehicleMarkerConfig

constructor(latlng: LatLng, config: VehicleMarkerConfig, options?: MarkerOptions) {
super(latlng, options)

this.#vehicle = vehicle
this.#speedUnit = speedUnit
this.#config = config
}

set config(value: VehicleMarkerConfig) {
this.#config = value
}

get config() {
return this.#config
}

get vehicle() {
return this.#vehicle
return this.#config.vehicle
}

set vehicle(value: Vehicle) {
this.#vehicle = value
this.#config.vehicle = value
}

get speedUnit() {
return this.#speedUnit
return this.#config.speedUnit
}

set speedUnit(value: SpeedUnit) {
this.#speedUnit = value
this.#config.speedUnit = value
}

set hidden(value: boolean) {
this.#config.hidden = value
}

get hidden() {
return this.#config.hidden
}
}

Expand Down
42 changes: 34 additions & 8 deletions packages/ui/src/hooks/useVehiclesLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,13 @@ const assignDynamicStyles = ({
* setIcon(), so as not to lose any previously applied values.
*/

divIcon.classList.remove(...quadrants)
divIcon.classList.remove(...quadrants, 'hidden')
divIcon.classList.add(quadrant)

if (marker.hidden) {
divIcon.classList.add('hidden')
}

carNode.style.color = vehicle.predictable ? route.textColor : 'white'
carNode.style.background = vehicle.predictable
? route.color
Expand Down Expand Up @@ -170,8 +175,9 @@ const getVehiclePopupContent = (marker: VehicleMarker, route: Route) => {
}
const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => {
const vehicles = useVehicles()
const { route, predictions } = useGlobals()
const { visible, markPredictedVehicles, speedUnit } = useVehicleSettings()
const { route, direction, predictions } = useGlobals()
const { visible, hideOtherDirections, markPredictedVehicles, speedUnit } =
useVehicleSettings()

const iconDimensions = useRef<Dimensions | null>(null)
const preds = useRef(predictions?.length ? predictions[0].values.slice(0, 3) : [])
Expand All @@ -194,6 +200,12 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => {
const marker = markers.find(m => m.vehicle.id === vehicle.id)

if (marker && iconDimensions.current) {
marker.vehicle = vehicle
marker.speedUnit = speedUnit
marker.hidden =
hideOtherDirections &&
Boolean(direction) &&
vehicle.directionId !== direction?.id
assignDynamicStyles({
route,
marker,
Expand All @@ -202,8 +214,6 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => {
preds: preds.current,
dimensions: iconDimensions.current
})
marker.vehicle = vehicle
marker.speedUnit = speedUnit
marker.getPopup()?.setContent(getVehiclePopupContent(marker, route))
marker.setLatLng(L.latLng(vehicle.lat, vehicle.lon))
} else {
Expand All @@ -217,8 +227,14 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => {
})
const marker = new VehicleMarker(
L.latLng(vehicle.lat, vehicle.lon),
vehicle,
speedUnit,
{
vehicle,
speedUnit,
hidden:
hideOtherDirections &&
Boolean(direction) &&
vehicle.directionId !== direction?.id
},
{
icon
}
Expand Down Expand Up @@ -261,6 +277,7 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => {
}
}

// Remove stale vehicle markers
for (const m of markers) {
const vehicle = vehicles.find(({ id }) => id === m.vehicle.id)

Expand All @@ -271,7 +288,16 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => {
} else {
vehiclesLayer.clearLayers()
}
}, [visible, vehicles, vehiclesLayer, route, markPredictedVehicles, speedUnit])
}, [
visible,
hideOtherDirections,
markPredictedVehicles,
speedUnit,
vehicles,
vehiclesLayer,
route,
direction
])
}

export { useVehiclesLayer }