-
Notifications
You must be signed in to change notification settings - Fork 155
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: make tour provider tour steps dynamic #1428
base: main
Are you sure you want to change the base?
feat: make tour provider tour steps dynamic #1428
Conversation
Signed-off-by: fc-santos <[email protected]>
Signed-off-by: fc-santos <[email protected]>
Signed-off-by: fc-santos <[email protected]>
@bryce-mcmath, I see you're the person who worked in the TourProvider implementation. If you could take a lot at this, it'd be greatly appreciated. To explain a little bit more why I have done this, in Quebec, we have other screens where we would like to have the tour guide, but the current implementation won't allow this. This PR will allows us to add a guided tour for the Activities screen and the More screen here: ![]() |
Signed-off-by: fc-santos <[email protected]>
@fc-santos I'm still reading through it, but so far I love it, nice work! It's much more extensible this way (and I'm glad someone was able to understand the code for this feature.) This is a small thing, but could we follow the SonarCloud optional chaining suggestion? The other two SonarCloud issues are fine as is, but the optional chaining one is a good and easy change I think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly small things related to constants. There are some great improvements here though, good work so far
@@ -137,17 +132,14 @@ export const ORIGIN_SPOT: LayoutRectangle = { | |||
} | |||
|
|||
export const TourContext = createContext<TourCtx>({ | |||
currentTour: TourID.HomeTour, | |||
currentTour: 'homeTourSteps', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use constants for these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
nativeDriver = false, | ||
} = props | ||
|
||
const [currentTour, setCurrentTour] = useState<TourID>(TourID.HomeTour) | ||
const [currentTour, setCurrentTour] = useState<TourID>('homeTourSteps') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
(currentTour === TourID.CredentialOfferTour && credentialOfferTourSteps[index] !== undefined) || | ||
(currentTour === TourID.ProofRequestTour && proofRequestTourSteps[index] !== undefined) | ||
) { | ||
if (currentTour && tours[currentTour] && tours[currentTour][index] !== undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice simplification! We could also add the suggested optional chaining here too to clean it up even further
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
if (currentTour && currentStep !== undefined && tours[currentTour]) { | ||
return tours[currentTour][currentStep] ?? { Render: () => <></> } | ||
} | ||
|
||
stepToRender = currentStep !== undefined ? steps[currentStep] : undefined | ||
return stepToRender ?? { Render: () => <></> } | ||
}, [homeTourSteps, currentTour, credentialsTourSteps, credentialOfferTourSteps, proofRequestTourSteps, currentStep]) | ||
return { Render: () => <></> } | ||
}, [currentTour, currentStep, tours]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think with this refactoring we could simplify it further to just one conditional and won't need both returns (won't need two { Render: () => ... }
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
@@ -203,7 +202,7 @@ const ProofRequest: React.FC<ProofRequestProps> = ({ navigation, proofId }) => { | |||
const shouldShowTour = enableToursConfig && store.tours.enableTours && !store.tours.seenProofRequestTour | |||
|
|||
if (shouldShowTour && screenIsFocused) { | |||
start(TourID.ProofRequestTour) | |||
start('proofRequestTourSteps') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"
CredentialOfferTour, | ||
ProofRequestTour, | ||
} | ||
export type TourID = `${string}TourSteps` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this an extensible type so that we can use it for constants throughout Bifold as well as extensions (like the Quebec or BC apps?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean by making an extensible type. Could you please explain ? Thanks!
P.S: All other comments should have been resolved, if you can review it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking something like this:
// in Bifold
export enum BifoldTourIds {
HomeTour = "homeTourSteps",
ProofRequestTour = "proofRequestTourSteps"
...
}
// in Quebec Wallet
enum QuebecTourIds {
QuebecSpecificATour = "quebecSpecificATourSteps",
QuebecSpecificBTour = "quebecSpecificBTourSteps"
...
}
// in Quebec Wallet
type TourIds = BifoldTourIds | QuebecTourIds
// in Quebec Wallet when you want to start a tour for a screen that's unique to Quebec
start(TourIds.QuebecTourA)
// in Quebec Wallet when you want to start a tour for a Bifold screen that Quebec is injecting their own custom version
start(TourIds.HomeTour)
And we could then use those TourIds
where you are using TourIDKeys
now (I'm not picky about the naming as long as it's clear. Whether we use as const
or enum
doesn't really matter to me either but we should export some kind of BifoldTourIds
that we can extend so we can use that constant / enum everywhere in both Bifold and Quebec Wallet (or any other Bifold based wallet.) No plain strings like tourID={'homeTourSteps'}
> | ||
<AttachTourStep index={0} tourID={TourID.HomeTour}> | ||
<TourProvider tours={tours} overlayColor={'gray'} overlayOpacity={0.7}> | ||
<AttachTourStep index={0} tourID={'homeTourSteps'}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use constant as mentioned above
<TourBox | ||
title={'Title'} | ||
leftText={'Left'} | ||
rightText={'Right'} | ||
onLeft={previous} | ||
onRight={next} | ||
currentTour={TourID.HomeTour} | ||
currentTour={'homeTourSteps'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"
<TourOverlay | ||
color={'grey'} | ||
currentStep={0} | ||
currentTour={TourID.HomeTour} | ||
currentTour={'homeTourSteps'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"
Signed-off-by: fc-santos <[email protected]>
Signed-off-by: fc-santos <[email protected]>
Signed-off-by: fc-santos <[email protected]>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good improvements, added a comment above explaining the small change requested. Wasn't very clear the first time, sorry about that
Summary of Changes
This PR makes the tour steps more dynamic. The base tours still exist (homeTourSteps, credentialsTourSteps, etc), but a wallet will be able to add other tours if needed it.
Breaking change: The TourProvider will accept a
tours
prop instead of the homeTourSteps, credentialsTourSteps.Here is the type definition of Tours:
Screenshots, videos, or gifs
N/A
Breaking change guide
The Tour Provider will be defined as following in App.tsx:
Related Issues
Replace this text with issue #'s that are relevant to this PR. If there are none, simply enter N/A
Pull Request Checklist
Tick all boxes below to demonstrate that you have completed the respective task. If the item does not apply to your this PR check it anyway to make it apparent that there's nothing to do.
Signed-off-by
line (we use the DCO GitHub app to enforce this)If you have any questions to any of the points above, just submit and ask! This checklist is here to help you, not to deter you from contributing!
Pro Tip 🤓