From 5ea7471678b450f3118230b16e418d2164d4a290 Mon Sep 17 00:00:00 2001 From: log101 Date: Wed, 17 Jul 2024 13:02:51 +0300 Subject: [PATCH] feat: add templates and geolocation callbacks to lit component --- bun.lockb | Bin 258182 -> 258182 bytes src/components/WebComponentWrapper.astro | 4 +- src/components/locked-content-lit.ts | 177 ++++++++++++++++++++++- 3 files changed, 175 insertions(+), 6 deletions(-) diff --git a/bun.lockb b/bun.lockb index 6b9e673f3ce6a95cf8cd07703e08737a0a138534..c523d85d1e1fb7d2b348462e29ceb710a052e44b 100755 GIT binary patch delta 31 ncmZpB$lvymzoCV33)Au??2K{7dWL!??dz5>ZC|&9`Gz+D#mfv= delta 31 kcmZpB$lvymzoCV33)Au?>`V+`(7tX7)An^sm~VIk0JEA41^@s6 diff --git a/src/components/WebComponentWrapper.astro b/src/components/WebComponentWrapper.astro index b937e2f..f4c0a72 100644 --- a/src/components/WebComponentWrapper.astro +++ b/src/components/WebComponentWrapper.astro @@ -106,12 +106,14 @@ const { contentId = "", imageUrl = "#", location = "" } = Astro.props; + + diff --git a/src/components/locked-content-lit.ts b/src/components/locked-content-lit.ts index 229587c..7f33071 100644 --- a/src/components/locked-content-lit.ts +++ b/src/components/locked-content-lit.ts @@ -1,13 +1,32 @@ -import { LitElement, html } from "lit"; +import { LitElement, html, unsafeCSS, type CSSResultGroup } from "lit"; import { customElement, property, state } from "lit/decorators.js"; +import L, { type LatLngTuple } from "leaflet"; +import Toastify from "toastify-js"; + +import globalStyles from "@/styles/globals.css?inline"; +import lockedContentStyles from "../styles/locked-content.css?inline"; + @customElement("locked-content-lit") export class LockedContent extends LitElement { + // Constants + geolocationOptions = { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0, + }; + + // Styling + static styles: CSSResultGroup | undefined = [ + unsafeCSS(globalStyles), + unsafeCSS(lockedContentStyles), + ]; + // Static properties @property() readonly imageId?: string; @property() readonly imageURL?: string; @property({ type: Object }) - readonly targetPosition?: [lat: number, lng: number]; + readonly targetPosition?: LatLngTuple; // Reactive state @state() @@ -16,12 +35,160 @@ export class LockedContent extends LitElement { protected _unlocked = false; @state() protected _targetProximity?: number; + @state() + protected _watchId?: number; + + // This callback will be fired when geolocation info is available + successCallback(position: GeolocationPosition) { + const pos = { + lat: position.coords.latitude, + lng: position.coords.longitude, + }; + + if (!this.targetPosition) return; + + const targetLatLng = L.latLng(this.targetPosition); + + const currentLatLng = L.latLng(pos); + + const betweenMeters = currentLatLng.distanceTo(targetLatLng); + + if (betweenMeters > 1000) { + // this.changeDescription(`${(betweenMeters / 1000).toFixed()} KM`); + } else if (betweenMeters > 100) { + // this.changeDescription(`${betweenMeters.toFixed(0)} M`); + } else { + if (this._watchId) { + navigator.geolocation.clearWatch(this._watchId); + // this.unlockContent(); + } + } + } + + // This callback will be fired on geolocation error + errorCallback(err: GeolocationPositionError) { + let errorMessage; + switch (err.code) { + case GeolocationPositionError.PERMISSION_DENIED: + errorMessage = + "Konum izni alınamadı, lütfen tarayıcınızın ve cihazınızın gizlilik ayarlarını kontrol edin."; + break; + case GeolocationPositionError.POSITION_UNAVAILABLE: + errorMessage = + "Konumunuz tespit edilemedi, lütfen biraz sonra tekrar deneyiniz."; + break; + case GeolocationPositionError.TIMEOUT: + errorMessage = + "Konum isteği zaman aşımına uğradı, lütfen sayfayı yenileyip tekrar deneyiniz."; + break; + default: + errorMessage = + "Konum izni alınamadı, lütfen tarayıcınızın ve cihazınızın gizlilik ayarlarını kontrol edin."; + break; + } + + Toastify({ + text: errorMessage, + duration: 3000, + gravity: "top", // `top` or `bottom` + position: "center", // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + background: "black", + borderRadius: "6px", + margin: "16px", + }, + onClick: function () {}, // Callback after click + }).showToast(); + } + + permissionButtonTemplate() { + return html` +
+ +
+
+

+ Ne kadar yaklaştığını görmek için aşağıdaki butona bas. +

+ +
+
+
+ `; + } + + lockedButtonTemplate() { + return html`
+ +
+
+

+ İçeriği görmek için konuma gitmelisin! +

+
+
+
`; + } + + unlockedButtonTemplate() { + return html`
+ + +
+
+

İçeriği görmek için butona bas!

+
+
+
`; + } + + connectedCallback(): void { + super.connectedCallback(); + + // start geolocation services + const id = navigator.geolocation.watchPosition( + this.successCallback.bind(this), + this.errorCallback, + this.geolocationOptions + ); + + this._watchId = id; + } render() { return html` -
- Hello from MyElement! ${this.imageId} -

${this.targetPosition}

+
+
+ + + ${this._watchId + ? this.lockedButtonTemplate() + : this.permissionButtonTemplate()} +
`; }