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

feat(quest-details): add support for play-streak progress sync #16

Merged
merged 14 commits into from
Oct 7, 2024

Conversation

eliobricenov
Copy link
Contributor

No description provided.

@eliobricenov eliobricenov marked this pull request as draft October 1, 2024 18:26
@eliobricenov eliobricenov changed the title feat(quest-details): extend QuestDetailsProps feat(quest-details): add support for play-streak progress sync Oct 2, 2024
@eliobricenov eliobricenov self-assigned this Oct 2, 2024
@eliobricenov eliobricenov marked this pull request as ready for review October 2, 2024 22:34
@@ -8,7 +8,7 @@ export function getPlaystreakArgsFromQuestData(
questMeta: Quest,
questPlayStreakData: UserPlayStreak | undefined | null,
useModuleInitTimeForSessionStartTime?: boolean
): PlayStreakEligibility {
): Omit<PlayStreakEligibility, 'onSync'> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm purposely omitting this because I don't think we should return the sync handler here. We'd have to include all the props from UseSyncPlayStreakProps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the implementation on the client:

const { syncPlayStreak } = useSyncPlayStreak({
    refreshPlayStreak: questPlayStreakResult.invalidateQuery
})

<QuestDetails
  ...
    playStreak: {
    ...getPlaystreakArgsFromQuestData(questMeta, questPlayStreakData),
        onSync: async () => syncPlayStreak(selectedQuestId)
    }
/>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add useSyncPlayStreak directly to the quest details wrapper component above? This way the re-renders are contained to just the wrapper component.

This fits the existing pattern like for:

  useSyncPlaySession(
    projectId,
    questPlayStreakResult.invalidateQuery,
    syncPlaySession
  )

where we pass in the syncPlaySession function as a prop. (which is window.api on client and a fetch elsewhere).

so you would just take in

syncPlayStreakWithExternalSource: (params: {
    quest_id: number
    signature: string
  }) => Promise<unknown>

as a quest details wrapper prop and pass it to useSyncPlayStreak

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you also wouldn't need to pass in all the props in this case. just the mutation fxn call returned from useSyncPlayStreak

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main target was to prevent having to include another required prop to the QuestRewardWrapper props because this is technically a prop that won't be used unless the quest type is play streak.

The play streak prop is optional and only used for play streak quests, so that was my main reason for choosing this place.

On second thought, it's fine to add it. I don't love its API, but it's fine, this is a pretty niche and complex implementation that won't be used elsewhere.

Copy link
Contributor

@BrettCleary BrettCleary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can make a few changes to match the existing patterns a bit better

src/components/QuestDetailsWrapper/index.tsx Outdated Show resolved Hide resolved
@@ -8,7 +8,7 @@ export function getPlaystreakArgsFromQuestData(
questMeta: Quest,
questPlayStreakData: UserPlayStreak | undefined | null,
useModuleInitTimeForSessionStartTime?: boolean
): PlayStreakEligibility {
): Omit<PlayStreakEligibility, 'onSync'> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add useSyncPlayStreak directly to the quest details wrapper component above? This way the re-renders are contained to just the wrapper component.

This fits the existing pattern like for:

  useSyncPlaySession(
    projectId,
    questPlayStreakResult.invalidateQuery,
    syncPlaySession
  )

where we pass in the syncPlaySession function as a prop. (which is window.api on client and a fetch elsewhere).

so you would just take in

syncPlayStreakWithExternalSource: (params: {
    quest_id: number
    signature: string
  }) => Promise<unknown>

as a quest details wrapper prop and pass it to useSyncPlayStreak

@@ -8,7 +8,7 @@ export function getPlaystreakArgsFromQuestData(
questMeta: Quest,
questPlayStreakData: UserPlayStreak | undefined | null,
useModuleInitTimeForSessionStartTime?: boolean
): PlayStreakEligibility {
): Omit<PlayStreakEligibility, 'onSync'> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you also wouldn't need to pass in all the props in this case. just the mutation fxn call returned from useSyncPlayStreak

Comment on lines 599 to 607
onSync: async() => {
if (questsWithExternalPlayStreakSync.includes(questMeta.id)) {
syncPlayStreakWithExternalSource(questMeta.id)
} else {
await syncPlaySession(projectId, 'hyperplay')
questPlayStreakResult.invalidateQuery()
}
}
})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that the logic of when to execute an external sync is here. The drawback is the need of questsWithExternalPlayStreakSync but I think that's ok

Copy link
Contributor

@BrettCleary BrettCleary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one small comment

if (questsWithExternalPlayStreakSync.includes(questMeta.id)) {
await syncPlayStreakWithExternalSource(questMeta.id)
} else {
await syncPlaySession(projectId, 'hyperplay')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to also call resetSessionStartedTime if you're going to call syncPlaySession here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and you may need a delay between the syncPlaySession call and the invalidate query like in the hook:

      await syncPlaySession(projectId, 'hyperplay')
      // allow for some time before read
      await wait(5000)
      await invalidateQuery()
      resetSessionStartedTime()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, I'll try not to add the wait to check if we truly need it. I tested without it, and it's working fine

@eliobricenov eliobricenov merged commit 33f36ef into main Oct 7, 2024
1 check passed
@eliobricenov eliobricenov deleted the feat/sync-external branch October 7, 2024 22:54
@eliobricenov eliobricenov restored the feat/sync-external branch October 8, 2024 15:55
@eliobricenov eliobricenov deleted the feat/sync-external branch October 8, 2024 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants