konulu-konum/src/pages/x/index.astro
log101 1d06a06697
All checks were successful
/ Build (push) Successful in 34s
feat: stop geoloaction callback after user has arrived
feat: automatically start watching if gelocation permission is given
2024-09-03 10:54:09 +03:00

189 lines
6.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
// Styles
import "@/styles/globals.css"
import "@/styles/locked-page.css"
import "@/styles/locked-content.css"
// Components
import Layout from "@/layouts/Layout.astro"
import ShareButton from "@/components/ShareButton"
import {
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { CalendarIcon } from "@radix-ui/react-icons"
---
<Layout>
<main class='flex flex-col gap-4'>
<div class='flex flex-col'>
<h1
class='scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl hover:underline'>
<a href=`${import.meta.env.SITE}`> Konulu Konum</a>
</h1>
<p class='[&:not(:first-child)]:mt-6 text-2xl'>
Size bir konulu konum bırakıldı, görüntüleyebilmek için haritadaki
konuma gitmeniz gerekiyor.
</p>
</div>
<Card className='w-full'>
<CardHeader>
<CardTitle className='text-2xl' id='card-title' />
</CardHeader>
<CardContent className='text-xl'>
<p id='card-description'></p>
</CardContent>
<CardFooter className='gap-2 text-lg'>
<CalendarIcon />
<p id='card-footer'></p>
</CardFooter>
</Card>
<div
id='locked-content-container'
class='w-full h-[475px] overflow-hidden border border-zinc-200 shadow-sm p-4 rounded'>
<div class='flex flex-col justify-center items-center image-wrapper'>
<img
id='content'
src='#'
class='h-[450px] blur-2xl transition-all duration-1000'
/>
<div
id='unlock-button-container'
class='flex flex-col justify-center gap-4 overlay'>
<button
id='unlock-content-button'
class='transition-[background-color] duration-1000 inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-11 rounded-md text-lg p-6 text-md'>
<svg
id='lock-icon'
xmlns='http://www.w3.org/2000/svg'
width='28'
height='28'
fill='#ffffff'
viewBox='0 0 256 256'>
<path
d='M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Zm-68-56a12,12,0,1,1-12-12A12,12,0,0,1,140,152Z'
></path>
</svg>
<svg
id='unlock-icon'
class='hidden'
xmlns='http://www.w3.org/2000/svg'
width='24'
height='24'
fill='#ffffff'
viewBox='0 0 256 256'>
<path
d='M208,80H96V56a32,32,0,0,1,32-32c15.37,0,29.2,11,32.16,25.59a8,8,0,0,0,15.68-3.18C171.32,24.15,151.2,8,128,8A48.05,48.05,0,0,0,80,56V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80Zm0,128H48V96H208V208Zm-68-56a12,12,0,1,1-12-12A12,12,0,0,1,140,152Z'
></path>
</svg>
<p id='button-text' class='text-xl'>İçerik Kilitli</p>
</button>
<div
class='rounded-lg border bg-card text-card-foreground shadow-sm p-2'>
<div class='pb-0 text-center flex flex-col gap-4'>
<p id='locked-content-description' class='text-xl'>
Ne kadar yaklaştığını görmek için aşağıdaki butona bas.
</p>
<button
id='location-permission-button'
class='text-xl inline-flex items-center justify-center whitespace-nowrap font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 text-primary-foreground h-10 rounded-md px-3 bg-green-700 hover:bg-green-600 text-md'>
Konum İzni Ver
</button>
</div>
</div>
</div>
</div>
</div>
<div id='map' class='w-full h-[450px] rounded'></div>
<ShareButton client:only />
<div class='flex justify-center'>
<p class='text-muted-foreground'>
Fotoğrafın kilidi şu ana dek <b id='counter'></b> kez açıldı
</p>
</div>
</main>
<script>
import type { ContentTable } from "@/lib/db"
import { updateText } from "@/lib/domUtils"
// Dayjs
import dayjs from "dayjs"
import relativeTime from "dayjs/plugin/relativeTime"
import utc from "dayjs/plugin/utc"
import "dayjs/locale/tr"
// Map
import { initMap } from "@/scripts/initMap"
import { startWatchingLocation } from "@/scripts/lockedContent"
const url = new URL(document.URL).searchParams
const id = url.get("id")
type Content = ContentTable
const res = await fetch(
`${import.meta.env.PUBLIC_BACKEND_URL}/api/location/${id}`
)
const data: Content | null = res.status === 200 ? await res.json() : null
dayjs.extend(relativeTime)
dayjs.extend(utc)
dayjs.locale("tr")
const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc())
updateText("card-title", data?.author ?? "")
updateText("card-description", data?.description ?? "")
updateText("card-footer", dateFromNow)
const lockedContentContainer = document.getElementById(
"locked-content-container"
)
if (lockedContentContainer) {
lockedContentContainer.dataset.targetPosition = data?.loc
}
const leafletMap = document.getElementById("map")
if (leafletMap) {
leafletMap.dataset.targetLocation = data?.loc
leafletMap.dataset.targetRadius = data?.radius.toString() ?? "50"
}
initMap()
const content = document.getElementById(
"content"
) as HTMLImageElement | null
if (content)
content.src = `${import.meta.env.PUBLIC_BACKEND_URL}/images/${data?.blob_url}`
const counter = document.getElementById("counter")
if (counter) counter.innerText = data?.unlocked_counter.toString() ?? ""
// When the web page is loaded, check if user has given geolocation
// permission before
navigator.permissions
.query({ name: "geolocation" })
.then((permissionStatus) => {
switch (permissionStatus.state) {
case "granted":
startWatchingLocation()
break
case "denied":
case "prompt":
default:
break
}
})
</script>
<script src='@/scripts/initMap.ts'></script>
<script src='@/scripts/lockedContent.ts'></script>
</Layout>