Skip to content

Commit

Permalink
Keep screen on while locate control is active
Browse files Browse the repository at this point in the history
  • Loading branch information
cdauth committed May 20, 2024
1 parent c715bc1 commit 5df3fe9
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
4 changes: 3 additions & 1 deletion docs/src/users/locate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ The cross-hair icon will be shown in one of these colours:
* **Orange:** Your location is shown on the map and the map will follow you as your location changes.
* **Blue:** Your location is shown on the map, but the map does not follow you.

Clicking the cross-hair icon will enable the orange mode. As soon as you move the map by hand, it will switch to blue mode. To go back to orange mode, first go back to black mode by clicking the icon once and then go to orange mode by clicking it again.
Clicking the cross-hair icon will enable the orange mode. As soon as you move the map by hand, it will switch to blue mode. To go back to orange mode, click the icon again.

While your location is visible on the map, FacilMap will try to prevent your screen from turning off, which would be disruptive during live navigation. It will depend on your browser and on your operating system whether this works and whether your browser will ask you for permission for this first.

Your location will be indicated as a blue circle with a blue dot at the center. Your location may be anywhere within the circle, it is not necessarily at its centre. If the circle is very small, it means that your browser could determine your location very accurately. If the circle is very big, it means that your browser had trouble to make an accurate guess about your location, and you may be anywhere within the circle.

Expand Down
20 changes: 20 additions & 0 deletions frontend/src/lib/components/leaflet-map/leaflet-map-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { type Optional } from "facilmap-utils";
import { getI18n, i18nResourceChangeCounter } from "../../utils/i18n";
import { AttributionControl } from "./attribution";
import { isNarrowBreakpoint } from "../../utils/bootstrap";
import { useWakeLock } from "../../utils/wake-lock";

type MapContextWithoutComponents = Optional<WritableMapContext, 'components'>;

Expand Down Expand Up @@ -239,8 +240,27 @@ function useLocateControl(map: Ref<Map>, context: FacilMapContext): Ref<Raw<Cont

locateControl.addTo(map);

const active = ref(false);
const handleActivate = () => {
active.value = true;
};
const handleDeactivate = () => {
active.value = false;
};
map.on("locateactivate", handleActivate);
map.on("locatedeactivate", handleDeactivate);

const wakeLockScope = effectScope();
wakeLockScope.run(() => {
useWakeLock(active);
});

onScopeDispose(() => {
handleDeactivate();
locateControl.remove();
map.off("locateactivate", handleActivate);
map.off("locatedeactivate", handleDeactivate);
wakeLockScope.stop();
});
}
}
Expand Down
67 changes: 67 additions & 0 deletions frontend/src/lib/utils/wake-lock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { onScopeDispose, ref, shallowRef, watch, type Ref } from "vue";
import { useDomEventListener } from "./utils";

/**
* Uses the Screen Wake Lock API (https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API) to keep
* the screen turned on while the provided "active" ref is true.
*/
export function useWakeLock(active: Ref<boolean>): void {
if (!("wakeLock" in navigator)) {
return;
}

const wakeLockPending = ref(false);
const wakeLock = shallowRef<WakeLockSentinel>();

const requestWakeLock = async () => {
if (!wakeLockPending.value && !wakeLock.value) {
wakeLockPending.value = true;
try {
console.log("wake lock activate");
wakeLock.value = await navigator.wakeLock.request("screen");
wakeLock.value.addEventListener("release", () => {
wakeLock.value = undefined;
});
} catch (err: any) {
console.warn("Error requesting wake lock", err);
} finally {
wakeLockPending.value = false;
}

if (!active.value) {
// Wake lock was disabled in the meantime
releaseWakeLock();
}
}
};

const releaseWakeLock = () => {
if (wakeLock.value) {
console.log("wake lock deactivate");
// Will call "release" event handler which sets wakeLock.value to undefined
wakeLock.value.release().catch((err) => {
console.warn("Error releasing wake lock", err);
});
}
};

watch(() => active.value, () => {
if (active.value) {
void requestWakeLock();
} else {
releaseWakeLock();
}
}, { immediate: true });

// Enable wake lock again if it was disabled by the browser because of moving out of the browser.
// See https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API#reacquiring_a_wake_lock
useDomEventListener(document, "visibilitychange", () => {
if (active.value && document.visibilityState === "visible") {
void requestWakeLock();
}
});

onScopeDispose(() => {
releaseWakeLock();
});
}

0 comments on commit 5df3fe9

Please sign in to comment.