feat: watch position
This commit is contained in:
parent
cdcf08898f
commit
730f5e9715
61
package-lock.json
generated
61
package-lock.json
generated
|
@ -12,8 +12,8 @@
|
|||
"@astrojs/react": "^3.0.9",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-separator": "^1.0.3",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@types/leaflet": "^1.9.8",
|
||||
"@types/react": "^18.2.47",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"astro": "^4.1.2",
|
||||
|
@ -1102,6 +1102,52 @@
|
|||
"react": "^16.x || ^17.x || ^18.x"
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-primitive": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
|
||||
"integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-slot": "1.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-separator": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz",
|
||||
"integrity": "sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-primitive": "1.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
|
||||
|
@ -1326,11 +1372,6 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz",
|
||||
"integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ=="
|
||||
},
|
||||
"node_modules/@types/google.maps": {
|
||||
"version": "3.54.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.10.tgz",
|
||||
|
@ -1345,14 +1386,6 @@
|
|||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.8.tgz",
|
||||
"integrity": "sha512-EXdsL4EhoUtGm2GC2ZYtXn+Fzc6pluVgagvo2VC1RHWToLGlTRwVYoDpqS/7QXa01rmDyBjJk3Catpf60VMkwg==",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdast": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz",
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
"@astrojs/react": "^3.0.9",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-separator": "^1.0.3",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@types/leaflet": "^1.9.8",
|
||||
"@types/react": "^18.2.47",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"astro": "^4.1.2",
|
||||
|
|
|
@ -1,81 +1,94 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import distance from "@/utils/distance";
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
import distance from "@/utils/distance"
|
||||
|
||||
import { LockClosedIcon, LockOpen1Icon } from "@radix-ui/react-icons";
|
||||
import { useEffect, useState } from "react";
|
||||
import { LockClosedIcon, LockOpen1Icon } from "@radix-ui/react-icons"
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import "../styles/locked-content.css";
|
||||
import "../styles/locked-content.css"
|
||||
|
||||
const LocationButton = () => {
|
||||
const [isLocked, setIsLocked] = useState(true);
|
||||
const [atTarget, setAtTarget] = useState(false)
|
||||
const [contentVisible, setContentVisible] = useState(false)
|
||||
const [hasPermission, setHasPermission] = useState(false)
|
||||
|
||||
const startWatchingLocation = () => {
|
||||
setHasPermission(true)
|
||||
navigator.geolocation.watchPosition(
|
||||
(position: GeolocationPosition) => {
|
||||
const pos = {
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude
|
||||
}
|
||||
|
||||
const totalDistanceInKM = distance(pos.lat, pos.lng, pos.lat, pos.lng).toFixed(0)
|
||||
|
||||
if (totalDistanceInKM === "0") {
|
||||
setAtTarget(true)
|
||||
}
|
||||
},
|
||||
() => null,
|
||||
{ enableHighAccuracy: true, maximumAge: 30000, timeout: 27000 }
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setInterval(
|
||||
() =>
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(position: GeolocationPosition) => {
|
||||
const pos = {
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude,
|
||||
};
|
||||
navigator.permissions.query({ name: "geolocation" }).then(permissionStatus => {
|
||||
if (permissionStatus.state === "granted") {
|
||||
setHasPermission(true)
|
||||
startWatchingLocation()
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
const totalDistanceInKM = distance(
|
||||
pos.lat,
|
||||
pos.lng,
|
||||
pos.lat,
|
||||
pos.lng
|
||||
).toFixed(0);
|
||||
|
||||
if (totalDistanceInKM === "0") {
|
||||
setIsLocked(false);
|
||||
}
|
||||
}
|
||||
),
|
||||
3000
|
||||
);
|
||||
}, []);
|
||||
|
||||
if (isLocked) {
|
||||
return (
|
||||
<div className="module w-full h-[450px] p-4">
|
||||
<div className="module-inside flex flex-col justify-center items-center gap-2">
|
||||
<div>
|
||||
<Button size={"lg"}>
|
||||
<LockClosedIcon className="mr-2 h-4 w-4" /> İçerik Kilitli
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Card className="p-2">
|
||||
<CardContent className="pb-0 text-center">
|
||||
İçeriği görmek için konuma gitmelisin!
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
if (contentVisible) {
|
||||
return <div className='module-unlocked w-full h-[450px] p-4'></div>
|
||||
} else {
|
||||
return (
|
||||
<div className="module w-full h-[450px] p-4">
|
||||
<div className="module-inside flex flex-col justify-center items-center gap-2">
|
||||
<div>
|
||||
<Button size={"lg"} asChild>
|
||||
<a href="/unlocked">
|
||||
<LockOpen1Icon className="mr-2 h-4 w-4" />
|
||||
<div className='module w-full h-[450px] p-4'>
|
||||
{atTarget ? (
|
||||
<div className='module-inside flex flex-col justify-center items-center gap-2'>
|
||||
<div>
|
||||
<Button size={"lg"} onClick={() => setContentVisible(true)}>
|
||||
<LockOpen1Icon className='mr-2 h-4 w-4' />
|
||||
İçeriğin Kilidi Açıldı
|
||||
</a>
|
||||
</Button>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Card className='p-2'>
|
||||
<CardContent className='pb-0 text-center'>İçeriği görmek için butona bas!</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
) : (
|
||||
<div className='module-inside flex flex-col justify-center items-center gap-4'>
|
||||
<Button size={"lg"}>
|
||||
<LockClosedIcon className='mr-2 h-4 w-4' /> İçerik Kilitli
|
||||
</Button>
|
||||
|
||||
<Card className="p-2">
|
||||
<CardContent className="pb-0 text-center">
|
||||
İçeriği görmek için butona bas!
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
<Card className='p-2'>
|
||||
{hasPermission ? (
|
||||
<CardContent className='pb-0 text-center'>İçeriği görmek için konuma gitmelisin!</CardContent>
|
||||
) : (
|
||||
<div className='flex flex-col gap-2'>
|
||||
<CardContent className='pb-0 text-center'>
|
||||
Ne kadar yaklaştığını görmek için aşağıdaki butona bas.
|
||||
</CardContent>
|
||||
|
||||
<Button
|
||||
size={"sm"}
|
||||
className='bg-green-700 hover:bg-green-600'
|
||||
onClick={() => startWatchingLocation()}
|
||||
>
|
||||
Konum İzni Ver
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default LocationButton;
|
||||
export default LocationButton
|
||||
|
|
29
src/components/ui/separator.tsx
Normal file
29
src/components/ui/separator.tsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
import * as React from "react"
|
||||
import * as SeparatorPrimitive from "@radix-ui/react-separator"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Separator = React.forwardRef<
|
||||
React.ElementRef<typeof SeparatorPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
|
||||
>(
|
||||
(
|
||||
{ className, orientation = "horizontal", decorative = true, ...props },
|
||||
ref
|
||||
) => (
|
||||
<SeparatorPrimitive.Root
|
||||
ref={ref}
|
||||
decorative={decorative}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"shrink-0 bg-border",
|
||||
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
)
|
||||
Separator.displayName = SeparatorPrimitive.Root.displayName
|
||||
|
||||
export { Separator }
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
const googleSdkKey = import.meta.env.MAPS_SDK_KEY;
|
||||
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
|
@ -23,7 +23,7 @@ const googleSdkKey = import.meta.env.MAPS_SDK_KEY;
|
|||
<meta name="generator" content={Astro.generator} />
|
||||
<title>Konulu Konum</title>
|
||||
</head>
|
||||
<body class="bg-purple-50 container">
|
||||
<body class="container my-8">
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -13,17 +13,36 @@ import {
|
|||
import { CalendarIcon } from '@radix-ui/react-icons';
|
||||
|
||||
import '../styles/locked-page.css';
|
||||
import LocationButton from '@/components/LockedContent';
|
||||
import LockedContent from '@/components/LockedContent';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<main class="flex flex-col gap-3 my-4 items-center">
|
||||
<main class="flex flex-col gap-4">
|
||||
<div>
|
||||
<h1
|
||||
class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl"
|
||||
>
|
||||
Konulu Konum
|
||||
</h1>
|
||||
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||
Arkadaşınız size bir fotoğraf ve bir not bıraktı. Fakat fotoğrafı
|
||||
görebilmeniz için aşağıdaki konuma gitmeniz gerekiyor. Konuma
|
||||
yaklaştığınızda butona basıp fotoğrafı görüntüleyebilirsiniz.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<Card className="w-full">
|
||||
<CardHeader>
|
||||
<CardTitle>Abdurrahman</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p>Aşağıdaki konuma gitmen gerekiyor.</p>
|
||||
<p>
|
||||
Hacı sana çok özel bir sürpriz hazırladık, aşağıdaki konuma muhakak
|
||||
git.
|
||||
</p>
|
||||
</CardContent>
|
||||
<CardFooter className="gap-2">
|
||||
<CalendarIcon />
|
||||
|
@ -31,11 +50,16 @@ import LocationButton from '@/components/LockedContent';
|
|||
</CardFooter>
|
||||
</Card>
|
||||
|
||||
<div id="map" class="w-full h-[450px]"></div>
|
||||
<LockedContent client:load />
|
||||
|
||||
<LocationButton client:load />
|
||||
<div id="map" class="w-full h-[450px] rounded"></div>
|
||||
|
||||
<Button className="w-full">Paylaş</Button>
|
||||
<div class="flex justify-center">
|
||||
<p class="text-muted-foreground">
|
||||
Fotoğrafın kilidi şu ana dek <b>2</b> kez açıldı
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Button className="w-full">Paylaş</Button>
|
||||
<script src="../scripts/initMap.js"></script>
|
||||
</Layout>
|
||||
|
|
|
@ -15,6 +15,13 @@ var targetLocationIcon = L.icon({
|
|||
|
||||
L.marker(TARGET_LOCATION, { icon: targetLocationIcon }).addTo(map);
|
||||
|
||||
var circle = L.circle(TARGET_LOCATION, {
|
||||
color: 'blue',
|
||||
fillColor: '#30f',
|
||||
fillOpacity: 0.2,
|
||||
radius: 50
|
||||
}).addTo(map);
|
||||
|
||||
var currentLocationIcon = L.icon({
|
||||
iconUrl: 'blue-dot.png',
|
||||
iconSize: [32, 32],
|
||||
|
@ -92,3 +99,39 @@ L.control.targetLocation = function (opts) {
|
|||
L.control.currentLocation({ position: 'bottomleft' }).addTo(map);
|
||||
|
||||
L.control.targetLocation({ position: 'bottomleft' }).addTo(map);
|
||||
|
||||
navigator.permissions
|
||||
.query({ name: "geolocation" })
|
||||
.then((permissionStatus) => {
|
||||
if (permissionStatus === 'granted') {
|
||||
navigator.geolocation.watchPosition(
|
||||
(position) => {
|
||||
const pos = {
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude
|
||||
}
|
||||
|
||||
console.log('The map location is' + pos)
|
||||
},
|
||||
() => null,
|
||||
{ enableHighAccuracy: true, maximumAge: 60000, timeout: 57000 }
|
||||
)
|
||||
} else {
|
||||
permissionStatus.onchange = () => {
|
||||
if (permissionStatus.state === 'granted') {
|
||||
navigator.geolocation.watchPosition(
|
||||
(position) => {
|
||||
const pos = {
|
||||
lat: position.coords.latitude,
|
||||
lng: position.coords.longitude
|
||||
}
|
||||
|
||||
console.log('The map location is' + pos)
|
||||
},
|
||||
() => null,
|
||||
{ enableHighAccuracy: true, maximumAge: 60000, timeout: 57000 }
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.module-unlocked {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.module::before {
|
||||
content: "";
|
||||
top: 0;
|
||||
|
@ -18,6 +25,18 @@
|
|||
filter: blur(20px);
|
||||
}
|
||||
|
||||
.module-unlocked::before {
|
||||
content: "";
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-image: url("/sample-selfie.webp");
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.module-inside {
|
||||
position: relative;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user