ITADN

Initial state of PermissionsController for geolocation doesn't seem to reflect its real state on pageload

#32OpenTonySpegel 创建于 2024-07-24
T
TonySpegelcommented
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](https://github.com/TonySpegel/gps-permission-demo) (you can just run `npm run dev`) and also a [github page with a demo](https://tonyspegel.github.io/gps-permission-demo/) https://github.com/user-attachments/assets/f559ce12-d6f9-46c9-a145-648e6e33d0c8 and also my code inline here: ```typescript 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
2 条评论