Skip to content

Commit

Permalink
Add basic permission management
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Aug 15, 2023
1 parent 266d60f commit 4e3323b
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 146 deletions.
5 changes: 5 additions & 0 deletions src/constants/permission-state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { StdPermissionState } from "../types/std.js";

export const PROMPT = "prompt" satisfies StdPermissionState;
export const GRANTED = "granted" satisfies StdPermissionState;
export const DENIED = "denied" satisfies StdPermissionState;
8 changes: 8 additions & 0 deletions src/geolocation-position-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ const TIMEOUT: StdGeolocationPositionError["TIMEOUT"] = 3;

let canConstruct = false;

export function createPermissionDeniedError(
message: string,
): StdGeolocationPositionError {
canConstruct = true;

return new GeolocationPositionError(PERMISSION_DENIED, message);
}

export function createPositionUnavailableError(
message: string,
): StdGeolocationPositionError {
Expand Down
7 changes: 6 additions & 1 deletion src/geolocation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { errorMessage } from "./error.js";
import {
createPermissionDeniedError,
createPositionUnavailableError,
createTimeoutError,
isGeolocationPositionError,
Expand Down Expand Up @@ -67,9 +68,13 @@ export class Geolocation {
throw new Error("Method not implemented clearWatch");
}

#readPosition({
async #readPosition({
timeout = Infinity,
}: StdPositionOptions): Promise<StdGeolocationPosition> {
if (!(await this.#locationServices.requestPermission())) {
throw createPermissionDeniedError("");
}

if (!Number.isFinite(timeout)) return this.#locationServices.getPosition();

return new Promise((resolve, reject) => {
Expand Down
19 changes: 17 additions & 2 deletions src/location-services.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
import { sleep } from "./async.js";
import { GRANTED, PROMPT } from "./constants/permission-state.js";
import { createPositionUnavailableError } from "./geolocation-position-error.js";
import { createPosition } from "./geolocation-position.js";
import { StdGeolocationPosition } from "./types/std.js";
import { StdGeolocationPosition, StdPermissionState } from "./types/std.js";

export interface LocationServices {
requestPermission(): Promise<boolean>;
getPosition(): Promise<StdGeolocationPosition>;
}

export interface MutableLocationServices extends LocationServices {
setPermissionState(state: StdPermissionState): void;
setPosition(position: StdGeolocationPosition | undefined): void;
}

export function createLocationServices(): LocationServices {
export function createLocationServices(): MutableLocationServices {
let permissionState: StdPermissionState = PROMPT;
let position: StdGeolocationPosition | undefined;

return {
async requestPermission() {
return permissionState === GRANTED;
},

setPermissionState(nextState) {
permissionState = nextState;
},

async getPosition() {
// systems should not rely on the position being available immediately
await sleep(0);
Expand Down
2 changes: 2 additions & 0 deletions src/types/std.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export type StdGeolocationPositionError = globalThis.GeolocationPositionError;
export type StdPositionCallback = globalThis.PositionCallback;
export type StdPositionErrorCallback = globalThis.PositionErrorCallback;
export type StdPositionOptions = globalThis.PositionOptions;

export type StdPermissionState = globalThis.PermissionState;
Loading

0 comments on commit 4e3323b

Please sign in to comment.