Skip to content

Commit ebaf2d8

Browse files
committed
Add basic geolocation watching
1 parent e411ae0 commit ebaf2d8

File tree

4 files changed

+63
-6
lines changed

4 files changed

+63
-6
lines changed

apps/web-api-demo/geolocation.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ <h2>Geolocation</h2>
1616
<p>longitude: <span id="longitude" /></p>
1717

1818
<button id="get-location">Get Location</button>
19+
20+
<button id="start-watching">Start Watching</button>
21+
<button id="stop-watching">Stop Watching</button>
1922
</section>
2023
<script type="module" src="/src/geolocation.ts"></script>
2124
</body>

apps/web-api-demo/src/geolocation.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { trackGeolocation } from '@withease/web-api';
33
const latitudeElement = document.querySelector('#latitude')!;
44
const longitudeElement = document.querySelector('#longitude')!;
55
const getLocationButton = document.querySelector('#get-location')!;
6+
const startWatchingButton = document.querySelector('#start-watching')!;
7+
const stopWatchingButton = document.querySelector('#stop-watching')!;
68

7-
const { $latitude, $longitude, request } = trackGeolocation({});
9+
const { $latitude, $longitude, request, watching } = trackGeolocation({});
810

911
$latitude.watch((latitude) => {
1012
console.log('latitude', latitude);
@@ -16,3 +18,5 @@ $longitude.watch((longitude) => {
1618
});
1719

1820
getLocationButton.addEventListener('click', () => request());
21+
startWatchingButton.addEventListener('click', () => watching.start());
22+
stopWatchingButton.addEventListener('click', () => watching.stop());

apps/web-api-demo/test/geolocation.spec.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ test.use({
77
permissions: ['geolocation'],
88
});
99

10-
test('should show geolocation', async ({ page, context }) => {
10+
test('request', async ({ page, context }) => {
1111
await page.goto(GEOLOCATION_PAGE);
1212

1313
const latitudeContainer = await page.$('#latitude');
@@ -32,3 +32,32 @@ test('should show geolocation', async ({ page, context }) => {
3232
expect(await latitudeContainer!.textContent()).toBe('32.890221');
3333
expect(await longitudeContainer!.textContent()).toBe('22.492348');
3434
});
35+
36+
test('watch', async ({ page, context }) => {
37+
await page.goto(GEOLOCATION_PAGE);
38+
39+
const latitudeContainer = await page.$('#latitude');
40+
const longitudeContainer = await page.$('#longitude');
41+
const startWatchingButton = await page.$('#start-watching');
42+
const stopWatchingButton = await page.$('#stop-watching');
43+
44+
// By default it should be null
45+
expect(await latitudeContainer!.textContent()).toBe('null');
46+
expect(await longitudeContainer!.textContent()).toBe('null');
47+
48+
// After watching the location, it should be updated immediately
49+
await startWatchingButton!.click();
50+
expect(await latitudeContainer!.textContent()).toBe('12.492348');
51+
expect(await longitudeContainer!.textContent()).toBe('41.890221');
52+
53+
// Change geolocation, values should be updated immediately
54+
await context.setGeolocation({ longitude: 22.492348, latitude: 32.890221 });
55+
expect(await latitudeContainer!.textContent()).toBe('32.890221');
56+
expect(await longitudeContainer!.textContent()).toBe('22.492348');
57+
58+
// Stop watching and change geolocation, values should NOT be updated
59+
await stopWatchingButton!.click();
60+
await context.setGeolocation({ longitude: 42.492348, latitude: 52.890221 });
61+
expect(await latitudeContainer!.textContent()).toBe('32.890221');
62+
expect(await longitudeContainer!.textContent()).toBe('22.492348');
63+
});

packages/web-api/src/geolocation.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
sample,
1010
restore,
1111
attach,
12+
scopeBind,
1213
} from 'effector';
1314

1415
import { readonly } from './shared';
@@ -172,10 +173,30 @@ export function trackGeolocation(
172173
const $unsubscribe = restore(saveUnsubscribe, null);
173174

174175
const watchPositionFx = createEffect(() => {
175-
// TODO: real code
176-
newPosition({} as any);
177-
failed({} as any);
178-
saveUnsubscribe(() => null);
176+
const boundNewPosition = scopeBind(newPosition, { safe: true });
177+
const boundFailed = scopeBind(failed, { safe: true });
178+
const boundSaveUnsubscribe = scopeBind(saveUnsubscribe, { safe: true });
179+
180+
const unwatchMap = new Map<(id: number) => void, number>();
181+
182+
for (const provider of providres) {
183+
if (isDefaultProvider(provider)) {
184+
const watchId = provider.watchPosition(
185+
boundNewPosition,
186+
boundFailed,
187+
params
188+
);
189+
190+
unwatchMap.set((id: number) => provider.clearWatch(id), watchId);
191+
}
192+
}
193+
194+
boundSaveUnsubscribe(() => {
195+
for (const [unwatch, id] of unwatchMap) {
196+
unwatch(id);
197+
unwatchMap.delete(unwatch);
198+
}
199+
});
179200
});
180201

181202
const unwatchPositionFx = attach({

0 commit comments

Comments
 (0)