|
| 1 | +<template> |
| 2 | + <div ref="DOMbackground" class="fixed w-screen h-screen top-0 left-0 z-30 bg-darkblur backdrop-blur-sm invisible opacity-0"></div> |
| 3 | + <section |
| 4 | + ref="DOMpopup" |
| 5 | + class="popup fixed flex flex-col items-center rounded w-[90vw] max-w-[36rem] max-h-[90vh] justify-start bg-grey-300 top-[45%] left-1/2 -translate-x-1/2 -translate-y-1/2 z-[1000] md:justify-center text-grey-50 before:absolute before:top-0 before:bottom-0 before:left-0 before:right-0 before:rounded before:bg-500 before:z-min after:absolute after:top-px after:left-px after:bottom-px after:right-px after:bg-grey-500 after:rounded after:z-min" |
| 6 | + > |
| 7 | + <div ref="DOMFaucetRequest" class="p-20" v-if="selectedFaucetFromUrl"> |
| 8 | + <Recaptcha @validation="captchaValidation" :captchakey="selectedFaucetFromUrl.recaptcha" /> |
| 9 | + </div> |
| 10 | + </section> |
| 11 | +</template> |
| 12 | + |
| 13 | +<script setup lang="ts"> |
| 14 | +import { onMounted, ref, computed } from 'vue' |
| 15 | +import { gsap } from 'gsap' |
| 16 | +
|
| 17 | +import Recaptcha from '@/components/ui/Recaptcha.vue' |
| 18 | +
|
| 19 | +import { useFaucetDetail } from '@/stores/faucetDetail' |
| 20 | +
|
| 21 | +import { Faucet } from '@/types' |
| 22 | +
|
| 23 | +import { faucets as faucetJson } from '@/data/faucets.json' |
| 24 | +
|
| 25 | +const faucets = ref(faucetJson as Faucet[]) |
| 26 | +
|
| 27 | +const store = useFaucetDetail() |
| 28 | +
|
| 29 | +const DOMbackground = ref<HTMLElement | null>(null) |
| 30 | +const DOMpopup = ref<HTMLElement | null>(null) |
| 31 | +const DOMFaucetRequest = ref<HTMLElement | null>(null) |
| 32 | +
|
| 33 | +const captchaValid = ref(false) |
| 34 | +const captchaSecret = ref('') |
| 35 | +
|
| 36 | +const faucetUrl = new URLSearchParams(window.location.search).get('faucet_url') || null |
| 37 | +
|
| 38 | +const selectedFaucetFromUrl = computed(() => { |
| 39 | + return faucets.value.find(faucet => faucet.url === faucetUrl) || null |
| 40 | +}) |
| 41 | +
|
| 42 | +declare global { |
| 43 | + interface Window { |
| 44 | + ReactNativeWebView?: { |
| 45 | + postMessage: (message: string) => void; |
| 46 | + }; |
| 47 | + } |
| 48 | +} |
| 49 | +
|
| 50 | +const captchaValidation = ({ code = 'error', secret = '' }) => { |
| 51 | + captchaValid.value = code === 'success' |
| 52 | + captchaSecret.value = secret |
| 53 | + window.hasOwnProperty("ReactNativeWebView") ? window.ReactNativeWebView?.postMessage(secret) : null; |
| 54 | +} |
| 55 | +
|
| 56 | +const TLPending = ref<GSAPTimeline | null>(null) |
| 57 | +
|
| 58 | +onMounted(() => { |
| 59 | +
|
| 60 | +
|
| 61 | + if (selectedFaucetFromUrl.value) { |
| 62 | +
|
| 63 | + store.DOM.bg = DOMbackground.value |
| 64 | + store.DOM.popup = DOMpopup.value |
| 65 | +
|
| 66 | + store.selectedFaucet = selectedFaucetFromUrl.value |
| 67 | + store.popupToggle() |
| 68 | + } |
| 69 | +
|
| 70 | + TLPending.value = gsap |
| 71 | + .timeline({ repeat: -1, paused: true }) |
| 72 | + .fromTo('.popup', { '--mx': '0%' }, { '--mx': '100%', duration: 0.8, ease: 'none' }) |
| 73 | + .fromTo('.popup', { '--my': '100%' }, { '--my': '0%', duration: 0.8, ease: 'none' }) |
| 74 | + .fromTo('.popup', { '--mx': '100%' }, { '--mx': '0%', duration: 0.8, ease: 'none' }) |
| 75 | + .to('.popup', { '--my': '100%', duration: 0.8, ease: 'none' }) |
| 76 | +}) |
| 77 | +
|
| 78 | +</script> |
| 79 | + |
| 80 | +<style scoped> |
| 81 | +.popup { |
| 82 | + --op: 0; |
| 83 | + --mx: 0%; |
| 84 | + --my: 100%; |
| 85 | +
|
| 86 | + clip-path: polygon(0 0, 100% 0%, 100% 0, 0 0); |
| 87 | +} |
| 88 | +.popup::before { |
| 89 | + opacity: var(--op); |
| 90 | + background: radial-gradient(farthest-corner circle at var(--mx, 0%) var(--my, 100%), #aeffb6 0%, #121212 20%, #121212 100%); |
| 91 | +} |
| 92 | +</style> |
0 commit comments