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

[UI/UX] Add completed quests tab #1124

Merged
merged 16 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@hyperplay/chains": "^0.3.0",
"@hyperplay/check-disk-space": "^3.5.2",
"@hyperplay/quests-ui": "^0.0.28",
"@hyperplay/quests-ui": "^0.0.38",
"@hyperplay/ui": "^1.8.9",
"@hyperplay/utils": "^0.3.3",
"@mantine/carousel": "^7.12.0",
Expand Down Expand Up @@ -401,7 +401,8 @@
"classic-level": false,
"i18next-parser>esbuild": false,
"wagmi>@wagmi/connectors>@metamask/sdk>@metamask/sdk-communication-layer>utf-8-validate": true,
"@hyperplay/providers>@metamask/sdk>@metamask/sdk-communication-layer>utf-8-validate": true
"@hyperplay/providers>@metamask/sdk>@metamask/sdk-communication-layer>utf-8-validate": true,
"@hyperplay/overlay>electron": false
}
}
}
25 changes: 1 addition & 24 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { Channel, ContractMetadata } from '@valist/sdk/dist/typesApi'
import { IconDefinition } from '@fortawesome/free-solid-svg-icons'
import { DropdownItemType } from '@hyperplay/ui'
export type { Quest } from '@hyperplay/utils'

export type {
Listing as HyperPlayRelease,
Expand Down Expand Up @@ -932,30 +933,6 @@ export interface Reward {
numClaimsLeft: string
}

export interface Quest {
id: number
project_id: string
name: string
type: 'REPUTATIONAL-AIRDROP' | 'PLAYSTREAK'
status: string
description: string
rewards?: Reward[]
/* eslint-disable-next-line */
deposit_contracts: any[]
eligibility?: {
completion_threshold?: number
steam_games: { id: string }[]
play_streak: {
required_playstreak_in_days: number
minimum_session_time_in_seconds: number
}
}
quest_external_game: null | {
runner: Runner
store_redirect_url: string
}
}

export interface RewardClaimSignature {
signature: `0x${string}`
nonce: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.questLog {
margin: 0 var(--space-sm) 0 0;
min-width: 280px;
min-width: 320px;
max-width: 400px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {
} from '@hyperplay/ui'
import styles from './index.module.scss'
import { useTranslation } from 'react-i18next'
import { Quest } from 'common/types'
import useGetG7UserCredits from 'frontend/hooks/useGetG7UserCredits'
import useGetPointsBalancesForProject from 'frontend/hooks/useGetPointsBalances'
import useGetQuests from 'frontend/hooks/useGetQuests'
import { useGetQuestStates } from 'frontend/hooks/useGetQuestStates'

export interface QuestLogWrapperProps {
questsResults: ReturnType<typeof useGetQuests>
Expand All @@ -31,6 +31,27 @@ export function QuestLogWrapper({
const pointsBalancesQuery = useGetPointsBalancesForProject(appName)
const pointsBalances = pointsBalancesQuery?.data?.data
const { t } = useTranslation()
const { questIdToQuestStateMap, isPending: isGetQuestStatesPending } =
useGetQuestStates({
quests
})

const questsUi =
quests?.map((quest) => {
const questUi_i: QuestLogInfo = {
questType: quest.type,
title: quest.name,
state: Object.hasOwn(questIdToQuestStateMap, quest.id)
? questIdToQuestStateMap[quest.id]
: 'ACTIVE',
onClick: () => {
setSelectedQuestId(quest.id)
},
selected: selectedQuestId === quest.id,
id: quest.id
}
return questUi_i
}) ?? []

const i18n: QuestLogTranslations = {
quests: t('quest.quests', 'Quests'),
Expand Down Expand Up @@ -68,38 +89,19 @@ export function QuestLogWrapper({
}

let questLog = null
if (Array.isArray(quests)) {
const questsUi = quests.map((val: Quest) => {
const questUi_i: QuestLogInfo = {
questType: val.type,
title: val.name,
state: 'ACTIVE',
onClick: () => {
setSelectedQuestId(val.id)
},
selected: selectedQuestId === val.id,
id: val.id
}
return questUi_i
})
questLog = (
<QuestLog
quests={questsUi}
className={styles.questLog}
i18n={i18n}
pointsProps={pointsBalanceProps}
/>
)
} else if (questsResults?.data.isLoading || questsResults?.data.isFetching) {
questLog = (
<QuestLog
quests={[]}
className={styles.questLog}
loading={true}
i18n={i18n}
/>
)
}
const isLoading =
questsResults?.data.isLoading ||
questsResults?.data.isFetching ||
isGetQuestStatesPending
questLog = (
<QuestLog
quests={questsUi ?? []}
className={styles.questLog}
i18n={i18n}
pointsProps={pointsBalanceProps}
loading={isLoading}
/>
)

if (!quests?.length) {
return null
Expand Down
9 changes: 5 additions & 4 deletions src/frontend/components/UI/QuestsViewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import styles from './index.module.scss'
import { QuestLogWrapper } from './components/QuestLogWrapper'
import { Alert } from '@hyperplay/ui'
import { useTranslation } from 'react-i18next'
import { QuestDetailsWrapper } from '@hyperplay/quests-ui'
import { QuestDetailsWrapper, useGetUserPlayStreak } from '@hyperplay/quests-ui'
import { useFlags } from 'launchdarkly-react-client-sdk'
import authState from 'frontend/state/authState'
import useAuthSession from 'frontend/hooks/useAuthSession'
import '@hyperplay/quests-ui/style.css'
import { Reward } from 'common/types'
import useGetQuests from 'frontend/hooks/useGetQuests'
import useGetUserPlayStreak from 'frontend/hooks/useGetUserPlayStreak'
import { useSyncPlayStreakWithExternalSource } from 'frontend/hooks/useSyncPlayStreakWithExternalSource'
import { useAccount } from 'wagmi'

Expand All @@ -29,7 +28,10 @@ export function QuestsViewer({ projectId: appName }: QuestsViewerProps) {
const initialQuestId = quests?.[0]?.id ?? null
const visibleQuestId = selectedQuestId ?? initialQuestId
const sessionEmail = data?.linkedAccounts.get('email')
const { invalidateQuery } = useGetUserPlayStreak(visibleQuestId)
const { invalidateQuery } = useGetUserPlayStreak(
visibleQuestId,
window.api.getUserPlayStreak
)

const getPendingExternalSync = useCallback(async () => {
if (!address || !visibleQuestId || !isSignedIn) return false
Expand Down Expand Up @@ -123,7 +125,6 @@ export function QuestsViewer({ projectId: appName }: QuestsViewerProps) {
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) => {
Expand Down
26 changes: 0 additions & 26 deletions src/frontend/hooks/useGetQuest.ts

This file was deleted.

74 changes: 74 additions & 0 deletions src/frontend/hooks/useGetQuestStates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
getPlaystreakQuestStatus,
getUserPlaystreakQueryOptions,
getQuestQueryOptions
} from '@hyperplay/quests-ui'
import { QuestLogInfo } from '@hyperplay/ui'
import { Quest } from '@hyperplay/utils'
import { useQueries } from '@tanstack/react-query'
import useAuthSession from './useAuthSession'

export interface UseGetQuestLogInfosProps {
quests?: Quest[] | null
}

type getQuestQueryOptionsType = ReturnType<typeof getQuestQueryOptions>
type getUserPlaystreakQueryOptionsType = ReturnType<
typeof getUserPlaystreakQueryOptions
>
export function useGetQuestStates({ quests }: UseGetQuestLogInfosProps) {
const { isSignedIn } = useAuthSession()
let getQuestQueries: getQuestQueryOptionsType[] = []
if (isSignedIn) {
getQuestQueries =
quests?.map((quest) =>
getQuestQueryOptions(quest.id, window.api.getQuest)
) ?? []
}
const getQuestQuery = useQueries({
queries: getQuestQueries
})

let getUserPlaystreakQueries: getUserPlaystreakQueryOptionsType[] = []
if (isSignedIn) {
getUserPlaystreakQueries =
quests?.map((quest) =>
getUserPlaystreakQueryOptions(quest.id, window.api.getUserPlayStreak)
) ?? []
}
const getUserPlaystreakQuery = useQueries({
queries: getUserPlaystreakQueries
})

const questMap: Record<number, Quest> = {}
getQuestQuery
.filter((val) => !!val.data)
.forEach((val) => {
if (!val.data) {
return
}
questMap[val.data.id] = val.data
})

const questIdToQuestStateMap: Record<number, QuestLogInfo['state']> = {}

getUserPlaystreakQuery.forEach((val) => {
if (!val.data || !Object.hasOwn(questMap, val.data.questId)) {
return
}
const questId = val.data.questId
const questData = questMap[questId]
return (questIdToQuestStateMap[questId] = getPlaystreakQuestStatus(
questData,
val.data.userPlayStreak
))
})

const allQueries = [...getQuestQuery, ...getUserPlaystreakQuery]

return {
isPending: allQueries.some((val) => val.status === 'pending'),
isLoading: allQueries.some((val) => val.isLoading || val.isFetching),
questIdToQuestStateMap
}
}
4 changes: 2 additions & 2 deletions src/frontend/hooks/useGetRewards.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'
import useGetQuest from './useGetQuest'
import { getDecimalNumberFromAmount } from '@hyperplay/utils'
import { getRewardCategory } from 'frontend/helpers/getRewardCategory'
import { useTranslation } from 'react-i18next'
import { QuestReward } from '@hyperplay/ui'
import { useGetQuest } from '@hyperplay/quests-ui'

export function useGetRewards(questId: number | null) {
const questResult = useGetQuest(questId)
const questResult = useGetQuest(questId, window.api.getQuest)
const questMeta = questResult.data.data

const queryClient = useQueryClient()
Expand Down
31 changes: 0 additions & 31 deletions src/frontend/hooks/useGetUserPlayStreak.ts

This file was deleted.

22 changes: 0 additions & 22 deletions src/frontend/hooks/useSyncInterval.ts

This file was deleted.

Loading
Loading