Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HNT claimable rewards #850

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 73 additions & 31 deletions src/app/services/HotspotService/pages/ClaimTokensPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import { useTranslation } from 'react-i18next'
import { Image, RefreshControl } from 'react-native'
import MobileIcon from '@assets/svgs/mobileIconNew.svg'
import IotIcon from '@assets/svgs/iotIconNew.svg'
import HntIcon from '@assets/svgs/hntIconNew.svg'
import TouchableContainer from '@components/TouchableContainer'
import BalanceText from '@components/BalanceText'
import useHotspots from '@hooks/useHotspots'
import { toNumber } from '@helium/spl-utils'
import {
MOBILE_LAZY_KEY,
IOT_LAZY_KEY,
HNT_LAZY_KEY,
MIN_BALANCE_THRESHOLD,
} from '@utils/constants'
import useSubmitTxn from '@hooks/useSubmitTxn'
Expand All @@ -28,6 +30,7 @@ import { ReAnimatedBox } from '@components/AnimatedBox'
import { FadeIn, FadeOut } from 'react-native-reanimated'
import { RootState } from '@store/rootReducer'
import { useSelector } from 'react-redux'
import { useBottomSpacing } from '@hooks/useBottomSpacing'

const ClaimTokensPage = () => {
const { t } = useTranslation()
Expand All @@ -37,31 +40,39 @@ const ClaimTokensPage = () => {
const { showModal } = useModal()
const solBalance = useBN(useSolOwnedAmount(wallet).amount)
const colors = useColors()
const bottomSpacing = useBottomSpacing()

const hasEnoughSol = useMemo(() => {
return (solBalance || new BN(0)).gt(new BN(MIN_BALANCE_THRESHOLD))
}, [solBalance])

const {
pendingIotRewards,
pendingHntRewards,
pendingMobileRewards,
hotspotsWithMeta,
totalHotspots,
loading: hotspotsLoading,
fetchAll,
refresh,
} = useHotspots()

const contentContainerStyle = useMemo(() => {
return {
padding: spacing['2xl'],
paddingBottom: bottomSpacing,
}
}, [spacing])
}, [spacing, bottomSpacing])

const totalPendingIot = useMemo(() => {
if (!pendingIotRewards) return 0
return toNumber(pendingIotRewards, 6)
}, [pendingIotRewards])

const totalPendingHnt = useMemo(() => {
if (!pendingHntRewards) return 0
return toNumber(pendingHntRewards, 8)
}, [pendingHntRewards])

const totalPendingMobile = useMemo(() => {
if (!pendingMobileRewards) return 0
return toNumber(pendingMobileRewards, 6)
Expand All @@ -83,15 +94,23 @@ const ClaimTokensPage = () => {
return (
claiming ||
!hasEnoughSol ||
(totalPendingIot === 0 && totalPendingMobile === 0)
(totalPendingIot === 0 &&
totalPendingMobile === 0 &&
totalPendingHnt === 0)
)
}, [claiming, hasEnoughSol, totalPendingIot, totalPendingMobile])
}, [
claiming,
hasEnoughSol,
totalPendingIot,
totalPendingMobile,
totalPendingHnt,
])

const onClaim = useCallback(async () => {
try {
const claim = async () => {
await submitClaimAllRewards(
[IOT_LAZY_KEY, MOBILE_LAZY_KEY],
[IOT_LAZY_KEY, MOBILE_LAZY_KEY, HNT_LAZY_KEY],
hotspotsWithMeta,
totalHotspots,
)
Expand Down Expand Up @@ -122,7 +141,7 @@ const ClaimTokensPage = () => {
<RefreshControl
enabled
refreshing={hotspotsLoading}
onRefresh={fetchAll}
onRefresh={refresh}
title=""
tintColor={colors.primaryText}
/>
Expand All @@ -148,7 +167,7 @@ const ClaimTokensPage = () => {
{t('ClaimTokensPage.subtitle')}
</Text>
<Box
flexDirection="row"
flexDirection="column"
borderRadius="4xl"
overflow="hidden"
gap="1"
Expand All @@ -157,41 +176,64 @@ const ClaimTokensPage = () => {
<TouchableContainer
padding="xl"
gap="2.5"
backgroundColor="bg.brand-secondary"
backgroundColorPressed="blue.light-200"
backgroundColor="purple.100"
backgroundColorPressed="purple.200"
pressableStyles={{
flex: 1,
}}
>
<Box flexDirection="row" gap="2.5" alignItems="center">
<MobileIcon />
<HntIcon width={50} height={50} />
<Box flexDirection="column">
<BalanceText amount={totalPendingMobile} />
<Text variant="textXsMedium" color="blue.dark-500">
MOBILE
<BalanceText amount={totalPendingHnt} />
<Text variant="textXsMedium" color="purple.600">
HNT
</Text>
</Box>
</Box>
</TouchableContainer>
<TouchableContainer
padding="xl"
gap="2.5"
backgroundColor="bg.success-primary"
backgroundColorPressed="success.100"
pressableStyles={{
flex: 1,
}}
>
<Box flexDirection="row" gap="2.5" alignItems="center">
<IotIcon />
<Box flexDirection="column">
<BalanceText amount={totalPendingIot} />
<Text variant="textXsMedium" color="success.500">
IOT
</Text>
{totalPendingMobile > 0 && (
<TouchableContainer
padding="xl"
gap="2.5"
backgroundColor="bg.brand-secondary"
backgroundColorPressed="blue.light-200"
pressableStyles={{
flex: 1,
}}
>
<Box flexDirection="row" gap="2.5" alignItems="center">
<MobileIcon />
<Box flexDirection="column">
<BalanceText amount={totalPendingMobile} />
<Text variant="textXsMedium" color="blue.dark-500">
MOBILE
</Text>
</Box>
</Box>
</Box>
</TouchableContainer>
</TouchableContainer>
)}
{totalPendingIot > 0 && (
<TouchableContainer
padding="xl"
gap="2.5"
backgroundColor="bg.success-primary"
backgroundColorPressed="success.100"
pressableStyles={{
flex: 1,
}}
>
<Box flexDirection="row" gap="2.5" alignItems="center">
<IotIcon />
<Box flexDirection="column">
<BalanceText amount={totalPendingIot} />
<Text variant="textXsMedium" color="success.500">
IOT
</Text>
</Box>
</Box>
</TouchableContainer>
)}
</Box>
<ButtonPressable
marginTop="2xl"
Expand Down
16 changes: 13 additions & 3 deletions src/app/services/HotspotService/pages/ExplorerPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import { useEntityKey } from '@hooks/useEntityKey'
import { useIotInfo } from '@hooks/useIotInfo'
import { useMobileInfo } from '@hooks/useMobileInfo'
import { parseH3BNLocation } from '@utils/h3'
import CircleLoader from '@components/CircleLoader'
import { HotspotWithPendingRewards } from '../../../../types/solana'

const ExplorerPage = () => {
const { hotspotsWithMeta } = useHotspots()
const { hotspotsWithMeta, loading } = useHotspots()
const spacing = useSpacing()
const [userLocation, setUserLocation] = useState<Location>()
const [showTotalHotspotPuck, setShowTotalHotspotPuck] = useState(false)
Expand Down Expand Up @@ -67,12 +68,21 @@ const ExplorerPage = () => {
)
}, [showTotalHotspotPuck, hotspotsWithMeta, spacing])

if (loading) {
return (
<Box flex={1} justifyContent="center" alignItems="center">
<CircleLoader type="blue" loaderSize={60} />
</Box>
)
}

return (
<Box flex={1}>
<TotalHotspotPuckContainer />
<Map onCameraChanged={handleCameraChanged}>
<Camera
minZoomLevel={1}
zoomLevel={0}
minZoomLevel={0}
maxZoomLevel={22}
pitch={0}
centerCoordinate={[
Expand Down Expand Up @@ -117,7 +127,7 @@ const HotspotMarker = ({ hotspot }: { hotspot: HotspotWithPendingRewards }) => {
if (mobileInfoAcc) {
return parseH3BNLocation(mobileInfoAcc.info.location).reverse()
}
}, [hotspot])
}, [iotInfoAcc?.info?.location, mobileInfoAcc?.info?.location])

if (!result) return null

Expand Down
16 changes: 13 additions & 3 deletions src/app/services/ServiceSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { RootState } from '@store/rootReducer'
import StickersPage from '@features/stickers/StickersPage'
import { StickerProvider } from '@features/stickers/StickerContext'
import { useSwipe } from '@hooks/useSwipe'
import useHaptic from '@hooks/useHaptic'
import { ServiceSheetNavigationProp } from './serviceSheetTypes'

type ServiceSheetProps = {
Expand All @@ -62,14 +63,15 @@ const ServiceSheet = ({
const spacing = useSpacing()
const bottomSheetStyle = useBackgroundStyle('primaryText')
const borderRadii = useBorderRadii()
const { triggerImpact } = useHaptic()

const { rootSheetPosition } = useSelector((state: RootState) => state.app)

const onSwipeRight = useCallback((_: GestureResponderEvent) => {
setIsExpanded(true)
}, [])

const { onTouchStart, onTouchEnd } = useSwipe(undefined, onSwipeRight, 6)
const { onTouchStart, onTouchEnd } = useSwipe(undefined, onSwipeRight, 2.5)

const onRoute = useCallback(
(value: string) => {
Expand Down Expand Up @@ -108,13 +110,14 @@ const ServiceSheet = ({
)

const onDrawerPress = useCallback(() => {
triggerImpact('light')
setIsExpanded((s) => !s)
changeNavigationBarColor(
isExpanded ? colors.primaryText : colors.primaryBackground,
undefined,
true,
)
}, [colors, isExpanded])
}, [colors, isExpanded, triggerImpact])

const onWalletIconPress = useCallback(() => {
if (currentService === 'wallets' && bottomSheetOpen) {
Expand All @@ -123,9 +126,16 @@ const ServiceSheet = ({
return
}

triggerImpact('light')
serviceNav.replace('AccountsService')
bottomSheetRef.current?.expand()
}, [currentService, serviceNav, bottomSheetRef, bottomSheetOpen])
}, [
currentService,
serviceNav,
bottomSheetRef,
bottomSheetOpen,
triggerImpact,
])

const onCloseSheet = useCallback(() => {
// if (currentService === '') return
Expand Down
11 changes: 11 additions & 0 deletions src/assets/svgs/bluetoothOnboard.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/svgs/hntIconNew.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 10 additions & 15 deletions src/components/BalanceText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,17 @@ const BalanceText = ({
}) => {
const integral = useMemo(() => Math.floor(amount || 0), [amount])

const firstFractional = useMemo(() => {
const fractional = useMemo(() => {
if (amount === undefined) return 0
const decimal = amount - integral
const fraction = decimal.toString().split('.')[1]
// Fraction with max length of decimals
const fractionWithMaxDecimals = fraction?.slice(0, 1)
return fraction ? Number(fractionWithMaxDecimals) : 0
}, [amount, integral])

const secondFractional = useMemo(() => {
if (amount === undefined) return 0
const decimal = amount - integral
const fraction = decimal.toString().split('.')[1]
// Fraction with max length of decimals
const fractionWithMaxDecimals = fraction?.slice(1, 2)
return fraction ? Number(fractionWithMaxDecimals) : 0
const decimalFixed = decimal.toFixed(9)
const fraction = decimalFixed.toString().split('.')[1]
const decimalWithoutTrailingZeroes = decimalFixed.replace(/0+$/, '')
const decimalsLength = decimalWithoutTrailingZeroes
.toString()
.split('.')[1].length
const fractionWithMaxDecimals = fraction?.slice(1, decimalsLength)
return fraction ? fractionWithMaxDecimals : 0
}, [amount, integral])

return (
Expand All @@ -37,7 +32,7 @@ const BalanceText = ({
{`${integral.toLocaleString()}`}
</Text>
<Text adjustsFontSizeToFit variant={variant} color="text.placeholder">
{`.${firstFractional}${secondFractional}`}
{`.${fractional}`}
</Text>
</Box>
</Box>
Expand Down
5 changes: 4 additions & 1 deletion src/components/SegmentedControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { GestureResponderEvent, LayoutChangeEvent } from 'react-native'
import { SvgProps } from 'react-native-svg'
import { useColors } from '@config/theme/themeHooks'
import { useAnimatedStyle, withTiming } from 'react-native-reanimated'
import useHaptic from '@hooks/useHaptic'
import { Theme } from '../config/theme/theme'
import { Box, ReAnimatedBox, Text } from '.'
import TouchableOpacityBox from './TouchableOpacityBox'
Expand Down Expand Up @@ -119,6 +120,7 @@ const SegmentedControl = forwardRef(
) => {
const [selectedIndex, setSelectedIndex] = useState(0)
const [hasTouched, setHasTouched] = useState(false)
const { triggerImpact } = useHaptic()

useImperativeHandle(ref, () => ({ selectedIndex }))

Expand All @@ -133,11 +135,12 @@ const SegmentedControl = forwardRef(

const handleItemSelected = useCallback(
(index: number) => () => {
triggerImpact('light')
setHasTouched(true)
setSelectedIndex(index)
onItemSelected(index)
},
[onItemSelected],
[onItemSelected, triggerImpact],
)

const leftPosition = useMemo(() => {
Expand Down
Loading
Loading