Skip to content

Commit e72fe8b

Browse files
authored
bias geocoding (#469)
* bias geocoding * test coverage
1 parent 7aea772 commit e72fe8b

File tree

5 files changed

+94
-39
lines changed

5 files changed

+94
-39
lines changed

public/app.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/helpers/load-meeting-data.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function loadMeetingData(
1919
strings: Translation,
2020
timezone?: string
2121
): {
22+
bounds?: { north: string; south: string; east: string; west: string };
2223
capabilities: Data['capabilities'];
2324
indexes: Data['indexes'];
2425
meetings: Data['meetings'];
@@ -36,6 +37,9 @@ export function loadMeetingData(
3637
distance: [],
3738
};
3839

40+
const latitudes: number[] = [];
41+
const longitudes: number[] = [];
42+
3943
// loop through each entry
4044
flattenDays(data).forEach(meeting => {
4145
const {
@@ -219,6 +223,8 @@ export function loadMeetingData(
219223
typeof meeting.longitude === 'string'
220224
? parseFloat(meeting.longitude)
221225
: meeting.longitude;
226+
latitudes.push(latitude);
227+
longitudes.push(longitude);
222228
}
223229
}
224230

@@ -561,7 +567,18 @@ export function loadMeetingData(
561567
// determine sharing
562568
capabilities.sharing = typeof navigator.canShare === 'function';
563569

564-
return { meetings, indexes, capabilities, slugs };
570+
// bounds to bias the geocoder
571+
const bounds =
572+
latitudes.length && longitudes.length
573+
? {
574+
north: Math.max(...latitudes).toString(),
575+
south: Math.min(...latitudes).toString(),
576+
east: Math.max(...longitudes).toString(),
577+
west: Math.min(...longitudes).toString(),
578+
}
579+
: undefined;
580+
581+
return { bounds, capabilities, indexes, meetings, slugs };
565582
}
566583

567584
// look for data with multiple days and make them all single

src/hooks/data.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export const DataProvider = ({
7979
}: PropsWithChildren<{ google?: string; src?: string; timezone?: string }>) => {
8080
const [data, setData] = useState<Data>(defaultData);
8181
const { setError } = useError();
82-
const { input, latitude, longitude } = useInput();
82+
const { input, latitude, longitude, setBounds } = useInput();
8383
const { settings, strings } = useSettings();
8484

8585
useEffect(() => {
@@ -148,18 +148,17 @@ export const DataProvider = ({
148148
throw new Error('data is not in the correct format');
149149
}
150150

151-
const { meetings, indexes, capabilities, slugs } = loadMeetingData(
152-
json,
153-
data.capabilities,
154-
settings,
155-
strings,
156-
timezone
157-
);
151+
const { bounds, capabilities, indexes, meetings, slugs } =
152+
loadMeetingData(json, data.capabilities, settings, strings, timezone);
158153

159154
if (!timezone && !slugs.length) {
160155
throw new Error('time zone is not set');
161156
}
162157

158+
if (bounds) {
159+
setBounds(bounds);
160+
}
161+
163162
setData({
164163
capabilities,
165164
indexes,

src/hooks/input.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,25 @@ const InputContext = createContext<
2222
input: TSMLReactConfig['defaults'];
2323
latitude?: number;
2424
longitude?: number;
25+
setBounds: (bounds: {
26+
north: string;
27+
south: string;
28+
east: string;
29+
west: string;
30+
}) => void;
2531
} & Coordinates
26-
>({ input: defaults.defaults, waitingForInput: false });
32+
>({ input: defaults.defaults, waitingForInput: false, setBounds: () => {} });
2733

2834
export const InputProvider = ({ children }: PropsWithChildren) => {
2935
const { setError } = useError();
3036
const [searchParams] = useSearchParams();
3137
const { settings, strings } = useSettings();
38+
const [bounds, setBounds] = useState({
39+
north: '',
40+
south: '',
41+
east: '',
42+
west: '',
43+
});
3244

3345
const [input, setInput] = useState<TSMLReactConfig['defaults']>(
3446
defaults.defaults
@@ -96,6 +108,7 @@ export const InputProvider = ({ children }: PropsWithChildren) => {
96108
language: settings.language,
97109
referrer: window.location.href,
98110
search: input.search,
111+
...bounds,
99112
})}`
100113
)
101114
.then(result => result.json())
@@ -145,7 +158,7 @@ export const InputProvider = ({ children }: PropsWithChildren) => {
145158
}, [input.mode, input.search]);
146159

147160
return (
148-
<InputContext.Provider value={{ input, ...coordinates }}>
161+
<InputContext.Provider value={{ input, setBounds, ...coordinates }}>
149162
{children}
150163
</InputContext.Provider>
151164
);

test/__tests__/load-meeting-data.spec.ts

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,32 @@ describe('loadMeetingData', () => {
1818
city: 'Anytown',
1919
state: 'OK',
2020
country: 'USA',
21+
latitude: 37,
22+
longitude: -122,
23+
day: '0',
24+
},
25+
{
26+
name: 'Other Meeting',
27+
slug: 'other-meeting',
28+
time: '09:00',
29+
end_time: '10:00',
30+
address: '123 Main St',
31+
city: 'Anytown',
32+
state: 'OK',
33+
country: 'USA',
34+
latitude: 38,
35+
longitude: -121,
36+
day: '0',
2137
},
2238
{
2339
name: 'Inactive Meeting',
2440
slug: 'inactive-meeting',
2541
formatted_address: 'Anytown, OK, USA',
42+
latitude: 38,
43+
longitude: -121,
2644
},
2745
];
28-
const { meetings, indexes, capabilities, slugs } = loadMeetingData(
46+
const { bounds, meetings, indexes, capabilities, slugs } = loadMeetingData(
2947
data,
3048
{
3149
coordinates: false,
@@ -43,8 +61,8 @@ describe('loadMeetingData', () => {
4361
defaults.strings[defaults.language],
4462
'America/Los_Angeles'
4563
);
46-
expect(meetings).toStrictEqual({
47-
'test-meeting': {
64+
expect(meetings['test-meeting']).toEqual(
65+
expect.objectContaining({
4866
address: '123 Main St',
4967
approximate: false,
5068
formatted_address: '123 Main St, Anytown, OK, USA',
@@ -57,70 +75,78 @@ describe('loadMeetingData', () => {
5775
search: '123 main st, anytown, ok, usa\ttest meeting\tanytown',
5876
slug: 'test-meeting',
5977
types: ['in-person', 'active'],
60-
},
61-
'inactive-meeting': {
62-
approximate: true,
63-
formatted_address: 'Anytown, OK, USA',
64-
isActive: false,
65-
isInPerson: false,
66-
isOnline: false,
67-
isTempClosed: false,
68-
name: 'Inactive Meeting',
69-
regions: [],
70-
search: 'anytown, ok, usa\tinactive meeting',
71-
slug: 'inactive-meeting',
72-
types: ['inactive'],
73-
},
74-
});
78+
})
79+
);
7580
expect(indexes).toStrictEqual({
7681
distance: [],
7782
region: [
7883
{
7984
children: [],
8085
key: 'anytown',
8186
name: 'Anytown',
82-
slugs: ['test-meeting'],
87+
slugs: ['test-meeting', 'other-meeting'],
8388
},
8489
],
8590
time: [
91+
{
92+
key: 'morning',
93+
name: 'Morning',
94+
slugs: ['test-meeting', 'other-meeting'],
95+
},
8696
{
8797
key: 'appointment',
8898
name: 'Appointment',
89-
slugs: ['test-meeting', 'inactive-meeting'],
99+
slugs: ['inactive-meeting'],
90100
},
91101
],
92102
type: [
93103
{
94104
key: 'active',
95105
name: 'Active',
96-
slugs: ['test-meeting'],
106+
slugs: ['test-meeting', 'other-meeting'],
97107
},
98108
{
99109
key: 'in-person',
100110
name: 'In-person',
101-
slugs: ['test-meeting'],
111+
slugs: ['test-meeting', 'other-meeting'],
102112
},
103113
{
104114
key: 'inactive',
105115
name: 'Inactive',
106116
slugs: ['inactive-meeting'],
107117
},
108118
],
109-
weekday: [],
119+
weekday: [
120+
{
121+
key: 'sunday',
122+
name: 'Sunday',
123+
slugs: ['test-meeting', 'other-meeting'],
124+
},
125+
],
110126
});
111127
expect(capabilities).toStrictEqual({
112-
coordinates: false,
128+
coordinates: true,
113129
distance: false,
114130
geolocation: undefined,
115131
inactive: true,
116132
location: false,
117133
region: true,
118134
sharing: false,
119-
time: false,
135+
time: true,
120136
type: true,
121-
weekday: false,
137+
weekday: true,
138+
});
139+
expect(slugs).toStrictEqual([
140+
'test-meeting',
141+
'other-meeting',
142+
'inactive-meeting',
143+
]);
144+
expect(bounds).toStrictEqual({
145+
north: '38',
146+
south: '37',
147+
east: '-121',
148+
west: '-122',
122149
});
123-
expect(slugs).toStrictEqual(['test-meeting', 'inactive-meeting']);
124150
});
125151
});
126152

0 commit comments

Comments
 (0)