Skip to content

Commit

Permalink
Merge branch 'points-clicker' of https://github.com/dappforce/grillchat
Browse files Browse the repository at this point in the history
… into deploy/epic
  • Loading branch information
teodorus-nathaniel committed Jun 12, 2024
2 parents 581da2c + fd8d31b commit 28081ea
Show file tree
Hide file tree
Showing 21 changed files with 19,760 additions and 95 deletions.
13,394 changes: 13,394 additions & 0 deletions src/assets/animations/cat-clicker.json

Large diffs are not rendered by default.

5,882 changes: 5,882 additions & 0 deletions src/assets/animations/dog-click.json

Large diffs are not rendered by default.

Binary file added src/assets/graphics/clicker-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions src/components/CatClicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import CatClickerAnimation from '@/assets/animations/cat-clicker.json'
import Lottie, { LottieProps } from 'react-lottie'

export type HamsterLoadingProps = Omit<LottieProps, 'options'>

export default function CatClicker({ ...props }: HamsterLoadingProps) {
const defaultOptions: LottieProps = {
...props,
options: {
loop: true,
autoplay: true,
animationData: CatClickerAnimation,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
},
}

return (
<Lottie
{...defaultOptions}
height={300 || props.height}
width={300 || props.width}
isClickToPauseDisabled={true}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import NewCommunityModal from '@/components/community/NewCommunityModal'
import useGetTheme from '@/hooks/useGetTheme'
import { useConfigContext } from '@/providers/config/ConfigProvider'
import { getLinkedTelegramAccountsQuery } from '@/services/api/notifications/query'
import { getBalanceQuery } from '@/services/datahub/balances/query'
import { getBalanceQuery } from '@/services/datahub/leaderboard/points-balance/query'
import { getProfileQuery } from '@/services/datahub/profiles/query'
import { useSendEvent } from '@/stores/analytics'
import { useMyMainAddress } from '@/stores/my-account'
Expand Down
2 changes: 1 addition & 1 deletion src/modules/chat/HomePage/MissingRewards.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Button from '@/components/Button'
import useLinkedEvmAddress from '@/hooks/useLinkedEvmAddress'
import { getBalanceQuery } from '@/services/datahub/balances/query'
import { getBalanceQuery } from '@/services/datahub/leaderboard/points-balance/query'
import { useMyMainAddress } from '@/stores/my-account'
import { cx } from '@/utils/class-names'
import { IoWarning } from 'react-icons/io5'
Expand Down
2 changes: 1 addition & 1 deletion src/modules/points/PointsWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import Button from '@/components/Button'
import Card from '@/components/Card'
import { Skeleton } from '@/components/SkeletonFallback'
import useIsMounted from '@/hooks/useIsMounted'
import { getBalanceQuery } from '@/services/datahub/balances/query'
import { getTodaySuperLikeCountQuery } from '@/services/datahub/content-staking/query'
import { getBalanceQuery } from '@/services/datahub/leaderboard/points-balance/query'
import { useSendEvent } from '@/stores/analytics'
import { useMyAccount, useMyMainAddress } from '@/stores/my-account'
import { cx } from '@/utils/class-names'
Expand Down
2 changes: 1 addition & 1 deletion src/modules/telegram/StatsPage/tmpData.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const myAddressIndex = 10001
const myAddressIndex = 50

const myAddressTmp = '0x3C66e2cE7B0d28415A0Ad1A0C4837E03ca407071'

Expand Down
103 changes: 74 additions & 29 deletions src/modules/telegram/TapPage/PointsClicker.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import WaiterImage from '@/assets/graphics/waiter.png'
import CatClicker from '@/components/CatClicker'
import {
decreaseEnergyValue,
increasePointsBalance,
} from '@/services/datahub/leaderboard/points-balance/optimistic'
import { getEnergyStateQuery } from '@/services/datahub/leaderboard/points-balance/query'
import { useMyMainAddress } from '@/stores/my-account'
import { cx } from '@/utils/class-names'
import { useQueryClient } from '@tanstack/react-query'
import { useHapticFeedbackRaw } from '@tma.js/sdk-react'
import Image from 'next/image'
import { TouchEvent, TouchList, useEffect, useRef, useState } from 'react'

type PointsClickerProps = {
Expand All @@ -13,6 +19,28 @@ const PointsClicker = ({ className }: PointsClickerProps) => {
const [isTouched, setIsTouched] = useState(false)
const [touches, setTouches] = useState<TouchList>()
const haptic = useHapticFeedbackRaw(true)
const client = useQueryClient()
const myAddress = useMyMainAddress()
const { data, isLoading } = getEnergyStateQuery.useQuery(myAddress || '')
const [startAnimation, setStartAnimation] = useState(false)

const { energyValue } = data || {}

const isEmptyEnergy = energyValue === 0

useEffect(() => {
let timeout: NodeJS.Timeout

if (startAnimation && !isTouched) {
timeout = setTimeout(() => {
setStartAnimation(false)
}, 1000)
}

return () => {
clearTimeout(timeout)
}
}, [startAnimation, isTouched])

useEffect(() => {
const refCurrent = ref.current
Expand All @@ -31,20 +59,24 @@ const PointsClicker = ({ className }: PointsClickerProps) => {
e.preventDefault()
}
}
refCurrent?.addEventListener('touchstart', onTouchStart, {

ref.current?.addEventListener('touchstart', onTouchStart, {
passive: false,
})
refCurrent?.addEventListener('touchmove', onTouchMove, {
passive: false,
})

return () => {
refCurrent?.removeEventListener('touchstart', onTouchStart)
refCurrent?.removeEventListener('touchmove', onTouchMove)
if (refCurrent) {
refCurrent.removeEventListener('touchstart', onTouchStart)
refCurrent.removeEventListener('touchmove', onTouchMove)
}
}
}, [])

const onMouseDown = (event: TouchEvent<HTMLDivElement>) => {
setStartAnimation(true)
setIsTouched(true)
setTouches(event.touches)
}
Expand All @@ -58,13 +90,26 @@ const PointsClicker = ({ className }: PointsClickerProps) => {
if (ref.current && touch) {
const word = document.createElement('div')
word.classList.add('floating-word')
word.textContent = 'Soon'
word.textContent = '+1'

word.style.left = touch.clientX - 110 + 'px'
word.style.top = touch.clientY - 130 + 'px'
word.style.left = touch.clientX - 70 + 'px'
word.style.top = touch.clientY - 190 + 'px'

ref.current.appendChild(word)

if (myAddress && !isEmptyEnergy) {
increasePointsBalance({
client,
address: myAddress,
pointsByClick: 1,
})

decreaseEnergyValue({
client,
address: myAddress,
energyValuePerClick: 1,
})
}
setTimeout(() => {
ref.current?.removeChild(word)
}, 3000)
Expand All @@ -77,28 +122,28 @@ const PointsClicker = ({ className }: PointsClickerProps) => {
}

return (
<div
ref={ref}
className={cx('relative max-h-[242px] max-w-[242px]', className)}
onTouchStart={onMouseDown}
onTouchEnd={onMouseUp}
>
<>
<div
className={cx(
'absolute z-0 h-[175px] w-[175px] bg-[#5E81EA] blur-[102px]',
'bottom-0 left-0 right-0 top-0 m-auto'
)}
style={{ transform: 'translate3d(0, 0, 0)' }}
></div>
<Image
src={WaiterImage}
alt=''
className={cx(
'h-fullw-full relative z-10',
isTouched && 'scale-95 transform'
)}
/>
</div>
ref={ref}
className={cx('relative max-h-[300px] max-w-[300px]', className)}
onTouchStart={isEmptyEnergy ? undefined : onMouseDown}
onTouchEnd={isEmptyEnergy ? undefined : onMouseUp}
>
<div
className={cx(
'absolute z-0 h-[175px] w-[175px] bg-[#5E81EA] blur-[102px]',
'bottom-0 left-0 right-0 top-0 m-auto'
)}
style={{ transform: 'translate3d(0, 0, 0)' }}
></div>
<CatClicker
isPaused={!startAnimation || isEmptyEnergy}
style={{
filter: isEmptyEnergy ? 'brightness(0.7) grayscale(0.8)' : '',
}}
/>
</div>
</>
)
}

Expand Down
71 changes: 50 additions & 21 deletions src/modules/telegram/TapPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import TapFromMobileImage from '@/assets/graphics/tap-from-mobile.png'
import Button from '@/components/Button'
import SkeletonFallback from '@/components/SkeletonFallback'
import LayoutWithBottomNavigation from '@/components/layouts/LayoutWithBottomNavigation'
import ProgressModal from '@/components/modals/RewardPerDayModal'
import WelcomeModal from '@/components/modals/WelcomeModal'
import useTgNoScroll from '@/hooks/useTgNoScroll'
import PointsWidget from '@/modules/points/PointsWidget'
import { cx, mutedTextColorStyles } from '@/utils/class-names'
import { increaseEnergyValue } from '@/services/datahub/leaderboard/points-balance/optimistic'
import {
FULL_ENERGY_VALUE,
getEnergyStateQuery,
} from '@/services/datahub/leaderboard/points-balance/query'
import { useMyMainAddress } from '@/stores/my-account'
import { isTouchDevice } from '@/utils/device'
import { useQueryClient } from '@tanstack/react-query'
import { useMiniAppRaw } from '@tma.js/sdk-react'
import Image from 'next/image'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import PointsClicker from './PointsClicker'

const TapPage = () => {
useTgNoScroll()

return (
<LayoutWithBottomNavigation
className='relative'
style={{ minHeight: '100dvh' }}
>
<PointsWidget className='sticky top-0' />
<PointsWidget isNoTgScroll className='sticky top-0' />
<TapPageContent />
<WelcomeModal />
<ProgressModal />
Expand All @@ -28,34 +37,54 @@ const TapPage = () => {
const TapPageContent = () => {
const app = useMiniAppRaw(true)
const isMobile = isTouchDevice()
const router = useRouter()

if (app?.result && !isMobile) {
return <MobileDeviceForBetterExp />
}

return (
<div className='grid flex-1 grid-rows-[70%,30%] items-center'>
<div className='flex flex-1 flex-col items-center justify-center gap-14'>
<PointsClicker className='justify-self-center' />
<div className='flex flex-col items-center gap-[22px] px-4'>
<span className={cx('text-center', mutedTextColorStyles)}>
Tap2Earn is coming soon! While you wait, start earning points today by
creating and liking memes.
</span>

<Button
variant='primary'
size={'md'}
className='w-fit'
onClick={() => router.replace('/tg/memes')}
>
Try Meme to Earn
</Button>
</div>
<EnergyState />
</div>
)
}

const EnergyState = () => {
const myAddress = useMyMainAddress()
const client = useQueryClient()

const { data, isLoading } = getEnergyStateQuery.useQuery(myAddress || '')

const { energyValue } = data || {}

useEffect(() => {
const interval = setInterval(() => {
if (energyValue === FULL_ENERGY_VALUE) return
increaseEnergyValue({
client,
address: myAddress || '',
energyValuePerClick: 1,
})
}, 2000)

return () => clearInterval(interval)
})

return (
<span className='text-base font-bold leading-[22px]'>
🔋{' '}
<SkeletonFallback
className='relative -top-0.5 inline-block w-16 align-middle'
isLoading={isLoading}
>
{energyValue}
</SkeletonFallback>{' '}
/{FULL_ENERGY_VALUE}
</span>
)
}

const MobileDeviceForBetterExp = () => {
return (
<div className='relative flex flex-1 justify-center'>
Expand Down
34 changes: 23 additions & 11 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import { SDKProvider } from '@tma.js/sdk-react'
import { SessionProvider } from 'next-auth/react'
import { ThemeProvider } from 'next-themes'
import type { AppProps } from 'next/app'
// import { GoogleAnalytics } from 'nextjs-google-analytics'
import Script from 'next/script'
import { useEffect, useRef } from 'react'
import { Toaster } from 'sonner'
Expand All @@ -39,6 +38,10 @@ export type AppCommonProps = {
}

export default function App(props: AppProps<AppCommonProps>) {
useEffect(() => {
import('eruda').then((lib) => lib.default.init())
}, [])

return (
<SessionProvider
basePath={
Expand Down Expand Up @@ -94,6 +97,19 @@ function Styles({
)
}

const changeBodyStyle = (webApp: any, e: any) => {
console.log('isExpanded and isStable', webApp.isExpanded, e.isStateStable)

// if (webApp.isExpanded) {

// document.body.style.overflow = 'hidden'
// document.body.style.height = `${webApp.viewportStableHeight}px`
// document.body.style.maxHeight = `${webApp.viewportStableHeight}px`
// } else {
// document.body.style.overflow = 'auto'
// }
}

function AppContent({ Component, pageProps }: AppProps<AppCommonProps>) {
const { head, dehydratedState, ...props } = pageProps

Expand All @@ -110,7 +126,11 @@ function AppContent({ Component, pageProps }: AppProps<AppCommonProps>) {

const webApp = telegram?.WebApp

webApp?.expand()
if (webApp) {
webApp.ready()

webApp.expand()
}
})

return (
Expand All @@ -121,11 +141,6 @@ function AppContent({ Component, pageProps }: AppProps<AppCommonProps>) {
<DatahubSubscriber />
<ToasterConfig />
<ReferralUrlChanger />
{/* <NextNProgress
color='#eb2f95'
options={{ showSpinner: false }}
showOnShallow={false}
/> */}
<HeadConfig {...head} />
<Script id='gtm' strategy='afterInteractive'>
{`
Expand All @@ -136,10 +151,7 @@ function AppContent({ Component, pageProps }: AppProps<AppCommonProps>) {
})(window,document,'script','dataLayer','GTM-MQZ9PG2W');
`}
</Script>
{/* <GoogleAnalytics
trackPageViews
gaMeasurementId={getAugmentedGaId()}
/> */}

<GlobalModals />
<SessionAccountChecker />
<OauthLoadingModal />
Expand Down
Loading

0 comments on commit 28081ea

Please sign in to comment.