-
Notifications
You must be signed in to change notification settings - Fork 3
Initial state of PermissionsController for geolocation doesn't seem to reflect its real state on pageload #32
Description
Hi there!
I was just about to use the PermissionController to be able to work with the geolocations or to display the UI in a slightly different way depending on the state. I'm not sure if I'm doing something wrong or not, but the initial state doesn't seem to correspond to the actual state. I followed the demo in the docs and added some UI with help from lit/task, both in Chrome and Firefox the initial state after I open the page is “prompt” no matter if the permission was granted or denied.
I've got a reproduction repository (you can just run npm run dev) and also a github page with a demo
gps-permission-2024-07-24_22.29.10.mp4
and also my code inline here:
import { html, LitElement, TemplateResult } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { PermissionsController } from 'relit';
import { Task } from '@lit/task';
import { choose } from 'lit/directives/choose.js';
type coords = Pick<GeolocationCoordinates, 'latitude' | 'longitude'>;
@customElement('app-permission')
export class AppHome extends LitElement {
@state()
latitude: number | undefined = 52.522138048058856;
@state()
longitude: number | undefined = 13.394977670545542;
private _geoPermissionController = new PermissionsController(
this,
'geolocation'
);
private _getGpsPosition(
options: PositionOptions = { enableHighAccuracy: true }
): Promise<coords> {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
(position) => {
const { latitude, longitude } = position.coords;
resolve({ latitude, longitude });
},
(error) => reject(error),
options
);
});
}
private _gpsPositionTask = new Task(this, {
task: () => this._getGpsPosition(),
onComplete: (coords) => {
this.latitude = coords.latitude;
this.longitude = coords.longitude;
},
autoRun: false,
args: () => [this.latitude, this.longitude] as const,
});
private _permissionPending = () => {
return html`
<sl-button
@click=${() => {
this._gpsPositionTask.run();
}}
>
Ask for location permission
</sl-button>
`;
};
private _permissionDenied = () => html`
<sl-button variant="warning">we got a problem</sl-button>
`;
private _permissionGranted = () => html`
<sl-button @click=${() => this._gpsPositionTask.run()} variant="primary">
Get GPS Position
</sl-button>
`;
private _gpsButtonTemplate = (state: PermissionState) => html`
${choose<PermissionState, TemplateResult>(state, [
['prompt', () => this._permissionPending()],
['granted', () => this._permissionGranted()],
['denied', () => this._permissionDenied()],
])}
`;
render() {
return html`
<h2>Permission works</h2>
<p>${this._geoPermissionController.state}</p>
${'geolocation' in navigator
? this._gpsButtonTemplate(this._geoPermissionController.state)
: null}
`;
}
}btw it doesn't seem to matter where or when the state is obtained.
I'm sorry if I misunderstood or misused something, thanks for the help :) and let me know if I can provide more details!
Edit: added a demo