Skip to content

Commit

Permalink
feat(quest-details): add claim in quest page (#1132)
Browse files Browse the repository at this point in the history
* wip: quest page

* tech(quest-details): add play click

* chore: add npm packages

* feat(quest-details): add reward claim toast

* chore(i18n): add missing quest translations

* chore(i18n): align comments

* chore(i18n): align comments

* chore(i18n): add missing translation keys

* chore(claim-reward): remove auto claim

* chore(quest-detail): no longer needed hook

* fix(i18n): bad translation

* fix(i18n): bad translation

* tech(quest-details): remove empty file

* tech(quest-details): replace hook with mobx class

* tech(quest-detail): remove claim toast timeout

* tech(quest-detail): make claimed toast observer

* tech(quest-details): add on show metamask

* tech(quest-detail): use claimedRewardToastState from quest-ui

* chore: use latest ui package

* tech(quest-details): show popup only if MM

* tech(quest-detail): add missing change

* tech(quest-detail): use latest quest-ui package

* refactor(quest-detail): remove claim toast from overlay

* chore: add ts-expect error link

* chore: use stable quest-ui version
  • Loading branch information
eliobricenov authored Nov 14, 2024
1 parent 9c5375e commit 0fb9df3
Show file tree
Hide file tree
Showing 16 changed files with 417 additions and 378 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@hyperplay/chains": "^0.3.0",
"@hyperplay/check-disk-space": "^3.5.2",
"@hyperplay/quests-ui": "^0.0.38",
"@hyperplay/ui": "^1.8.9",
"@hyperplay/quests-ui": "^0.1.0",
"@hyperplay/ui": "^1.8.18",
"@hyperplay/utils": "^0.3.4",
"@mantine/carousel": "^7.12.0",
"@mantine/core": "^7.12.0",
Expand Down Expand Up @@ -310,6 +310,7 @@
"@lavamoat/allow-scripts": "^3.2.0",
"@lavamoat/preinstall-always-fail": "^2.1.0",
"@playwright/test": "^1.46.0",
"@tanstack/react-query-devtools": "^5.59.20",
"@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^6.4.8",
"@testing-library/react": "^14.3.1",
Expand Down Expand Up @@ -366,8 +367,8 @@
"@hyperplay/extension-importer": "^0.0.4",
"@hyperplay/extension-provider": "^0.0.8",
"@hyperplay/mock-backend": "^0.0.1",
"@hyperplay/patcher": "^0.0.17",
"@hyperplay/overlay": "^0.0.7",
"@hyperplay/patcher": "^0.0.17",
"@hyperplay/providers": "^0.0.6",
"@hyperplay/proxy-server": "^0.0.11"
},
Expand Down
35 changes: 30 additions & 5 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -737,21 +737,40 @@
"quest": {
"active": "Active",
"associatedGames": "Associated games",
"claimAll": "Claim all",
"claim": "Claim",
"claimed": "Claimed",
"claimFailed": "Claim failed",
"claimFailedMessage": "Please try once more. If it still doesn't work, create a Discord support ticket.",
"claimWarning": {
"body": "<bold>IMPORTANT:</bold> Please ensure that you are allocating enough gas on the {{networkName}} network for the transaction to be successfully confirmed <bold>within 7 days.</bold>",
"body2": "Otherwise, the Quest Reward <bold>will expire and will no longer be claimable.</bold>",
"cancel": "Cancel",
"confirm": "Confirm"
},
"connectSteamAccount": "Connect Steam account",
"createDiscordTicket": "Create Discord Ticket",
"g7Numclaimed": "Total Claimed G7 Credits",
"linkAccount": "Link your Steam account to check eligibility.",
"needMoreAchievements": "You need to have completed {{percent}}% of the achievements in one of these games.",
"noG7ConnectionClaim": "You need to have a Game7 account linked to {{email}} to claim your rewards.",
"noG7ConnectionSync": "You need to have a Game7 account linked to {{email}} to resync your tasks.",
"notEnoughGas": "Insufficient wallet balance to claim your reward due to gas fees. Try a different wallet or replenish this one before retrying.",
"noG7ConnectionSync": {
"message": "You need to have a Game7 account linked to {{email}} to resync your tasks.",
"title": "No G7 account linked"
},
"notEligible": {
"message": "You have not completed the required play streak days and can not claim your reward at this time.",
"title": "Not eligible yet"
},
"notEnoughBalance": {
"title": "Low balance"
},
"notEnoughGas": {
"message": "Insufficient wallet balance to claim your reward due to gas fees. Try a different wallet or replenish this one before retrying."
},
"notSignedIn": {
"message": "You need to be signed in to claim your reward.",
"title": "Not signed in"
},
"playstreak": {
"dayResets": "Day resets:",
"days": "days",
Expand All @@ -766,16 +785,22 @@
},
"points": "Points",
"pointsClaimed": "Points Claimed",
"questAvailable": "Quest available!",
"questComplete": "Quest complete!",
"quests": "Quests",
"readyForClaim": "Ready for claim",
"reputation": "Reputation",
"reward": "Reward",
"rewardClaimed": "Claim successful",
"signIn": "Log in",
"sync": "Sync",
"toClaimReward": "to claim your reward.",
"toSeeDetails": "to see details.",
"type": {
"playstreak": "Play Streak"
"playstreak": "Play Streak",
"reputation": "Reputation"
},
"View Game": "View Game"
"youHaveClaimed": "You have claimed {{totalRewards}} reward{{plural}}."
},
"quests": {
"g7CreditsModal": {
Expand Down
1 change: 1 addition & 0 deletions src/frontend/OverlayManager/Overlay/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
flex-direction: column;
gap: var(--space-2lg);
padding: var(--space-2lg-fixed) var(--space-xl-fixed);
align-items: flex-end;
}

.hideOverlay {
Expand Down
1 change: 1 addition & 0 deletions src/frontend/OverlayManager/Overlay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const Overlay = observer(function ({
runner
}: BrowserGameProps) {
const flags = useFlags()

const txnToastContainerStyle = {} as React.CSSProperties
if (OverlayState.title === 'HyperPlay Toasts') {
txnToastContainerStyle.bottom = 'unset'
Expand Down
154 changes: 154 additions & 0 deletions src/frontend/components/UI/QuestDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import React, { useCallback } from 'react'
import {
QuestDetailsWrapper,
claimedRewardToastState,
useGetUserPlayStreak
} from '@hyperplay/quests-ui'
import { Reward, Quest } from '@hyperplay/utils'
import useAuthSession from 'frontend/hooks/useAuthSession'
import authState from 'frontend/state/authState'
import { useFlags } from 'launchdarkly-react-client-sdk'
import { useTranslation } from 'react-i18next'
import { useAccount } from 'wagmi'
import { useSyncPlayStreakWithExternalSource } from 'frontend/hooks/useSyncPlayStreakWithExternalSource'
import extensionState from 'frontend/state/ExtensionState'

/**
* Don't delete this comment block since it's used for translation parsing for keys that are on the quests-ui library.
* As a heads up, everytime you add a new key on any library, you need to add it as a block comment anywhere in the code as well.
*
* t("quest.noG7ConnectionClaim", "You need to have a Game7 account linked to {{email}} to claim your rewards.")
* t("quest.noG7ConnectionSync", "You need to have a Game7 account linked to {{email}} to resync your tasks.")
* t("quest.notEnoughGas", "Insufficient wallet balance to claim your reward due to gas fees. Try a different wallet or replenish this one before retrying.")
* t("quest.playstreak.syncSuccess", "Progress synced")
* t("quest.claim", "Claim")
* t('quest.notSignedIn.title', 'Not signed in')
* t('quest.notSignedIn.message', 'You need to be signed in to claim your reward.')
* t('quest.notEligible.title', 'Not eligible yet')
* t('quest.notEligible.message', 'You have not completed the required play streak days and can not claim your reward at this time.')
* t('quest.playstreak.sync', 'Sync Progress')
* t('quest.noG7ConnectionSync.title', 'No G7 account linked')
* t('quest.noG7ConnectionSync.message', 'You need to have a Game7 account linked to {{email}} to claim your rewards.')
* t('quest.notEnoughBalance.title', 'Low balance')
* t('quest.notEnoughGas.message', 'Insufficient wallet balance to claim your reward due to gas fees. Try a different wallet or replenish this one before retrying.')
* t('quest.claimFailed', 'Claim failed')
* t('quest.claimFailedMessage', 'Please try once more. If it still doesn\'t work, create a Discord support ticket.')
* t('quest.createDiscordTicket', 'Create Discord Ticket')
* t('quest.reward', 'Rewards')
* t('quest.associatedGames', 'Associated games')
* t('quest.linkAccount', 'Link your Steam account to check eligibility.')
* t('quest.needMoreAchievements', 'You need to have completed {{percent}}% of the achievements in one of these games.')
* t('quest.claim', 'Claim')
* t('quest.signIn', 'Sign in')
* t('quest.connectSteamAccount', 'Connect Steam account')
* t('quest.type.reputation', 'Reputation')
* t('quest.type.playstreak', 'Play Streak')
* t('quest.sync', 'Sync')
* t('quest.playstreak.streakProgress', 'Streak Progress')
* t('quest.playstreak.days', 'days')
* t('quest.playstreak.playToStart', 'Play this game to start your streak!')
* t('quest.playstreak.playEachDay', 'Play each day so your streak won\'t reset!')
* t('quest.playstreak.streakCompleted', 'Streak completed! Claim your rewards now.')
* t('quest.playstreak.now', 'Now')
* t('quest.playstreak.dayResets', 'Day resets:')
* t('quest.playstreak.progressTowardsStreak', 'progress towards today\'s streak.')
* t('quest.points', 'Points')
* t('quest.claimWarning.body', '<bold>IMPORTANT:</bold> Please ensure that you are allocating enough gas on the {{networkName}} network for the transaction to be successfully confirmed <bold>within 7 days.</bold>')
* t('quest.claimWarning.body2', 'Otherwise, the Quest Reward <bold>will expire and will no longer be claimable.</bold>')
* t('quest.claimWarning.cancel', 'Cancel')
* t('quest.claimWarning.confirm', 'Confirm')
*/

export default function QuestDetails({
questId,
className,
isQuestsPage,
onPlayClick
}: {
questId: number | null
className?: string
isQuestsPage?: boolean
onPlayClick?: (quest: Quest) => void
}) {
const { address } = useAccount()
const { isSignedIn, data } = useAuthSession()
const { t } = useTranslation()
const flags = useFlags()
const sessionEmail = data?.linkedAccounts.get('email')
const { invalidateQuery } = useGetUserPlayStreak(
questId,
window.api.getUserPlayStreak
)

const getPendingExternalSync = useCallback(async () => {
if (!address || !questId || !isSignedIn) return false
return window.api.checkPendingSync({
questId,
wallet: address
})
}, [address, questId, isSignedIn])

const { syncPlayStreakWithExternalSource } =
useSyncPlayStreakWithExternalSource({
refreshPlayStreak: invalidateQuery
})

return (
<QuestDetailsWrapper
// @ts-expect-error - see: https://github.com/qmhc/vite-plugin-dts/issues/330
onRewardClaimed={(reward) =>
claimedRewardToastState.showClaimedReward(reward)
}
onShowMetaMaskPopup={async () => {
const currentProvider = await window.api.getConnectedProvider()
if (currentProvider === 'MetaMaskExtension') {
extensionState.showPopup()
}
}}
onPlayClick={onPlayClick}
getPendingExternalSync={getPendingExternalSync}
syncPlayStreakWithExternalSource={syncPlayStreakWithExternalSource}
tOverride={t}
sessionEmail={sessionEmail}
className={className}
checkG7ConnectionStatus={window.api.checkG7ConnectionStatus}
logInfo={window.api.logInfo}
logError={window.api.logError}
flags={{
rewardTypeClaimEnabled: {
ERC20: flags.erc20RewardsClaim,
ERC721: flags.erc721RewardsClaim,
ERC1155: flags.erc1155RewardsClaim,
POINTS: flags.pointsRewardsClaim,
'EXTERNAL-TASKS': flags.externalTasksRewardsClaim
},
questsOverlayClaimCtaEnabled: flags.questsOverlayClaimCtaEnabled
}}
trackEvent={window.api.trackEvent}
signInWithSteamAccount={() => window.api.signInWithProvider('steam')}
openDiscordLink={window.api.openDiscordLink}
selectedQuestId={questId}
getQuest={window.api.getQuest}
getUserPlayStreak={window.api.getUserPlayStreak}
getSteamGameMetadata={window.api.getSteamGameMetadata}
claimPoints={async (reward: Reward) =>
window.api.claimQuestPointsReward(reward.id.toString())
}
completeExternalTask={async (reward: Reward) =>
window.api.completeExternalTask(reward.id.toString())
}
getQuestRewardSignature={window.api.getQuestRewardSignature}
confirmRewardClaim={window.api.confirmRewardClaim}
getExternalTaskCredits={window.api.getExternalTaskCredits}
syncPlaySession={window.api.syncPlaySession}
getDepositContracts={window.api.getDepositContracts}
openSignInModal={authState.openSignInModal}
resyncExternalTask={async (rewardId: string) => {
window.api.resyncExternalTask(rewardId)
}}
isSignedIn={isSignedIn}
isQuestsPage={isQuestsPage}
key={'questDetailsLoading'}
/>
)
}
50 changes: 50 additions & 0 deletions src/frontend/components/UI/QuestRewardClaimedToast/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'
import { ToastQuest } from '@hyperplay/ui'
import Draggable from 'react-draggable'
import { useTranslation } from 'react-i18next'
import { observer } from 'mobx-react-lite'
import { claimedRewardToastState } from '@hyperplay/quests-ui'

type QuestRewardClaimedToastProps = {
draggable?: boolean
className?: string
}

export const QuestRewardClaimedToast = observer(
({ draggable = true, className }: QuestRewardClaimedToastProps) => {
const { t } = useTranslation()

if (!claimedRewardToastState.claimedReward) {
return null
}

const toast = (
<div className={className}>
<ToastQuest
i18n={{
overlayToggleKey: 'X',
overlayToggleModKey: 'option',
plus: '+',
questAvailable: t('quest.questAvailable', 'Quest available!'),
questComplete: t('quest.questComplete', 'Quest complete!'),
rewardClaimed: t('quest.rewardClaimed', 'Claim successful'),
toClaimReward: t('quest.toClaimReward', 'to claim your reward.'),
toSeeDetails: t('quest.toSeeDetails', 'to see details.'),
youHaveClaimed: t(
'quest.youHaveClaimed',
'You have claimed {{totalRewards}} reward{{plural}}.',
{
totalRewards: 1,
plural: ''
}
)
}}
onCloseClick={() => claimedRewardToastState.clearReward()}
status="claimed"
/>
</div>
)

return draggable ? <Draggable>{toast}</Draggable> : toast
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
margin: 0 var(--space-sm) 0 0;
min-width: 320px;
max-width: 400px;
width: 100%;
}
Loading

0 comments on commit 0fb9df3

Please sign in to comment.