feat: add css transition for unlock buton

This commit is contained in:
log101 2024-07-23 22:32:26 +03:00
parent 4f5a437c7c
commit e6b140068b
3 changed files with 107 additions and 59 deletions

View File

@ -1,18 +1,18 @@
{ {
"endOfLine": "lf", "endOfLine": "lf",
"printWidth": 120, "printWidth": 80,
"arrowParens": "avoid", "arrowParens": "avoid",
"bracketSpacing": true, "bracketSpacing": true,
"htmlWhitespaceSensitivity": "css", "htmlWhitespaceSensitivity": "css",
"insertPragma": false, "insertPragma": false,
"bracketSameLine": true, "bracketSameLine": true,
"jsxSingleQuote": true, "jsxSingleQuote": true,
"proseWrap": "preserve", "proseWrap": "always",
"quoteProps": "as-needed", "quoteProps": "as-needed",
"requirePragma": false, "requirePragma": false,
"semi": false, "semi": true,
"singleQuote": false, "singleQuote": false,
"tabWidth": 2, "tabWidth": 2,
"trailingComma": "none", "trailingComma": "es5",
"useTabs": false "useTabs": false
} }

View File

@ -40,14 +40,13 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc());
--- ---
<Layout> <Layout>
<main class="flex flex-col gap-4"> <main class='flex flex-col gap-4'>
<div> <div>
<h1 <h1
class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl hover:underline" class='scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl hover:underline'>
>
<a href=`${import.meta.env.PUBLIC_HOME_URL}`> Konulu Konum</a> <a href=`${import.meta.env.PUBLIC_HOME_URL}`> Konulu Konum</a>
</h1> </h1>
<p class="leading-7 [&:not(:first-child)]:mt-6"> <p class='leading-7 [&:not(:first-child)]:mt-6'>
Arkadaşınız size bir fotoğraf ve bir not bıraktı. Fakat fotoğrafı 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 görebilmeniz için aşağıdaki konuma gitmeniz gerekiyor. Konuma
yaklaştığınızda butona basıp fotoğrafı görüntüleyebilirsiniz. yaklaştığınızda butona basıp fotoğrafı görüntüleyebilirsiniz.
@ -56,55 +55,74 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc());
<Separator /> <Separator />
<Card className="w-full"> <Card className='w-full'>
<CardHeader> <CardHeader>
<CardTitle>{data?.author}</CardTitle> <CardTitle>{data?.author}</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p>{data?.description}</p> <p>{data?.description}</p>
</CardContent> </CardContent>
<CardFooter className="gap-2"> <CardFooter className='gap-2'>
<CalendarIcon /> <CalendarIcon />
<p>{dateFromNow}</p> <p>{dateFromNow}</p>
</CardFooter> </CardFooter>
</Card> </Card>
<locked-content <locked-content
id="locked-content-component" id='locked-content-component'
imageId={data?.url} imageId={data?.url}
imageURL={`http://localhost:3000/images/${data?.blob_url}`} imageURL={`http://localhost:3000/images/${data?.blob_url}`}
targetPosition={data?.loc}></locked-content> targetPosition={data?.loc}></locked-content>
<div <div
id="locked-content-container" id='locked-content-container'
data-target-position={data?.loc} data-target-position={data?.loc}
class="w-full h-[475px] overflow-hidden border border-zinc-200 shadow-sm p-4 rounded" 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'>
<div class="flex flex-col justify-center items-center image-wrapper">
<img <img
id="content" id='content'
src={`http://localhost:3000/images/${data?.blob_url}`} src={`http://localhost:3000/images/${data?.blob_url}`}
class="h-[450px] blur-2xl" class='h-[450px] blur-2xl'
/> />
<div class="flex flex-col justify-center gap-4 overlay"> <div class='flex flex-col justify-center gap-4 overlay'>
<button <button
id="unlock-content-button" id='unlock-content-button'
class="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 bg-primary text-primary-foreground hover:bg-primary/90 h-11 rounded-md text-lg p-6 text-md" class='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
İçerik Kilitli id='lock-icon'
xmlns='http://www.w3.org/2000/svg'
width='24'
height='24'
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'>İçerik Kilitli</p>
</button> </button>
<div <div
class="rounded-lg border bg-card text-card-foreground shadow-sm p-2" class='rounded-lg border bg-card text-card-foreground shadow-sm p-2'>
> <div class='pb-0 text-center flex flex-col gap-4'>
<div class="pb-0 text-center flex flex-col gap-4"> <p id='locked-content-description'>
<p id="locked-content-description">
Ne kadar yaklaştığını görmek için aşağıdaki butona bas. Ne kadar yaklaştığını görmek için aşağıdaki butona bas.
</p> </p>
<button <button
id="location-permission-button" id='location-permission-button'
_="on click send askpermission to me" _='on click send askpermission to me'
class="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-9 rounded-md px-3 bg-green-700 hover:bg-green-600 text-md" class='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-9 rounded-md px-3 bg-green-700 hover:bg-green-600 text-md'>
>
Konum İzni Ver Konum İzni Ver
</button> </button>
</div> </div>
@ -114,20 +132,19 @@ const dateFromNow = dayjs.utc(data?.created_at).from(dayjs.utc());
</div> </div>
<div <div
id="map" id='map'
class="w-full h-[450px] rounded" class='w-full h-[450px] rounded'
data-target-location={data?.loc} data-target-location={data?.loc}>
>
</div> </div>
<ShareButton client:only /> <ShareButton client:only />
<div class="flex justify-center"> <div class='flex justify-center'>
<p class="text-muted-foreground"> <p class='text-muted-foreground'>
Fotoğrafın kilidi şu ana dek <b>{data?.unlocked_counter}</b> kez açıldı Fotoğrafın kilidi şu ana dek <b>{data?.unlocked_counter}</b> kez açıldı
</p> </p>
</div> </div>
</main> </main>
<script src="../components/locked-content.ts"></script> <script src='../components/locked-content.ts'></script>
<script src="../scripts/initMap.ts"></script> <script src='../scripts/initMap.ts'></script>
<script src="../scripts/lockedContent.ts"></script> <script src='../scripts/lockedContent.ts'></script>
</Layout> </Layout>

View File

@ -8,6 +8,8 @@ let watchId: number;
const targetLocation = document.getElementById("locked-content-container") const targetLocation = document.getElementById("locked-content-container")
?.dataset.targetPosition; ?.dataset.targetPosition;
// This element display the distance between the user and the
// target if geolocation permission is granted
const descriptionElement = document.getElementById( const descriptionElement = document.getElementById(
"locked-content-description" "locked-content-description"
); );
@ -16,8 +18,9 @@ const locationPermissionButton = document.getElementById(
"location-permission-button" "location-permission-button"
); );
// Generates a human readable destination text according to
// distance remaining
function generateDistanceText(distance: number) { function generateDistanceText(distance: number) {
// Update the proximity text according to the distance remaining
if (distance > 1000) { if (distance > 1000) {
return `${(distance / 1000).toFixed()} KM`; return `${(distance / 1000).toFixed()} KM`;
} else if (distance > 100) { } else if (distance > 100) {
@ -25,23 +28,53 @@ function generateDistanceText(distance: number) {
} }
} }
// Update the elements according to distance remaining
function updateCurrentLocation(position: GeolocationPosition) { function updateCurrentLocation(position: GeolocationPosition) {
const newPosition = position.coords; const newPosition = position.coords;
if (targetLocation) { if (targetLocation) {
// Calculate the distance remaining
const distance = calculateDistance( const distance = calculateDistance(
[newPosition.latitude, newPosition.longitude], [newPosition.latitude, newPosition.longitude],
JSON.parse(targetLocation) JSON.parse(targetLocation)
); );
if (distance < 100) {
// If user has arrived to destination
// Transform locked button to reveal button
const unlockButton = document.getElementById("unlock-content-button");
const unlockIcon = document.getElementById("unlock-icon");
const lockIcon = document.getElementById("lock-icon");
const buttonText = document.getElementById("button-text");
const distanceText = generateDistanceText(distance); if (unlockButton) {
if (buttonText) buttonText.innerText = "İçeriği Göster";
if (lockIcon) lockIcon.classList.add("hidden");
if (unlockIcon) unlockIcon.classList.remove("hidden");
unlockButton.classList.remove("bg-primary", "hover:bg-primary/90");
unlockButton.classList.add(
"transition-[background-color]",
"duration-1000"
);
unlockButton.classList.add(
"animate-pulse",
"bg-indigo-600",
"hover:bg-indigo-700",
"hover:animate-none",
"border-2",
"border-indigo-800"
);
}
} else {
const distanceText = generateDistanceText(distance);
if (descriptionElement) if (descriptionElement)
descriptionElement.innerText = `Kalan mesafe: ${distanceText}`; descriptionElement.innerText = `Kalan mesafe: ${distanceText}`;
}
if (locationPermissionButton) locationPermissionButton.remove(); if (locationPermissionButton) locationPermissionButton.remove();
} }
// Update leaflet controls
onLocationSuccess(position); onLocationSuccess(position);
} }
@ -63,21 +96,19 @@ lockedContentContainer?.addEventListener(
startWatchingLocation startWatchingLocation
); );
navigator.permissions navigator.permissions.query({ name: "geolocation" }).then(permissionStatus => {
.query({ name: "geolocation" }) switch (permissionStatus.state) {
.then((permissionStatus) => { case "granted":
switch (permissionStatus.state) { watchId = window.navigator.geolocation.watchPosition(
case "granted": updateCurrentLocation,
watchId = window.navigator.geolocation.watchPosition( errorCallback
updateCurrentLocation, );
errorCallback break;
); case "denied":
break; case "prompt":
case "denied": default:
case "prompt": break;
default: }
break; });
}
});
export { startWatchingLocation }; export { startWatchingLocation };