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

Case Dismissed: Forcibly show DAppConnectionInfoBar popover on first dApp connection #3464

Merged
merged 4 commits into from
Jun 16, 2023

Conversation

Shadowfiend
Copy link
Contributor

@Shadowfiend Shadowfiend commented Jun 10, 2023

Draft until #3451 lands.

Adds a DismissableItem concept and related functionality to the
PreferencesService and to the UI slice, providing a common pattern
for things that should be shown to the user exactly once, e.g. new
feature banners and related functions.

This PR will complete the work on updated dApp connections.

Latest build: extension-builds-3464 (as of Fri, 16 Jun 2023 17:51:17 GMT).

@Shadowfiend Shadowfiend force-pushed the cable-connection branch 2 times, most recently from c7f12f3 to d16131a Compare June 12, 2023 20:27
@Shadowfiend Shadowfiend force-pushed the case-dismissed branch 2 times, most recently from 5529ecb to 3940cf6 Compare June 12, 2023 21:07
Base automatically changed from cable-connection to main June 13, 2023 21:38
These are items that are displayed to the user either exactly once, or
once until the user closes them. The default connection popover is
supported, but not yet hooked up.

This is designed to be a useful primitive for any new-feature banner, or
first-time-use banner. Like many items in preferences, the current list
of already-shown dismissable items is initialized when the extension
starts, and then updated along the way based on UI actions.
The first connection after a version with the info bar enabled is used
will show the popover, then future connections will not.

Uses the dismissable item functionality in the preferences service.
The default toggle was being rendered with "Taho as default" being on
the left. After some discussion, the fact that it was reversed compared
to other toggles (where "on" is on the right) isn't ideal. This commit
puts "Taho as default" on the right, and drops the `leftToRight`
parameter added to `SharedToggleButton` to make that possible in the
first place.
@Shadowfiend Shadowfiend marked this pull request as ready for review June 15, 2023 20:56
@Shadowfiend
Copy link
Contributor Author

Finally ready to go here I think.

Copy link
Contributor

@hyphenized hyphenized left a comment

Choose a reason for hiding this comment

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

Tested and looks good! Left a few comments

)

this.preferenceService.emitter.on(
"dismissableItemMarkedAsShown",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the benefit to this rather than doing it in the method below that calls markDismissableItemAsShown is that within the preference service we can decide when we dispatch the event and thus update the store, hence we have more flexibility. Though this could turn quite verbose if we use it for everything.

* be used for tours, or for popups that can be retriggered but will not
* auto-display more than once.
*/
export type SingleShotItem = "default-connection-popover"
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about OneTimeDismissableItem?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the distinction I'm trying to draw here, and I think I've done a pretty poor job of it lol, is between items that are dismissed through a user's “please don't show this to me again”-type action, or a banner that needs to be explicitly closed but doesn't block content, and items that are dismissed automatically. I think SingleShotItem is actually a decent name for the latter, but DismissableItem as the umbrella type doesn't reflect that very well.

Maybe it's just AutomaticallyDismissableItem as a counterpart to ManuallyDismissableItem though? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok then I think this is fine as it is 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Happy to see/hear ideas for a better name here. Fortunately it's in the type, so it doesn't get persisted, so we can deliberate a little without blocking the merge.

@@ -24,7 +29,7 @@ function DefaultConnectionPopover({ close }: PopoverProps): ReactElement {
return (
<div
className={classNames("bg", {
fadeIn: !isClosing,
fade_in: !isClosing,
Copy link
Contributor

Choose a reason for hiding this comment

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

This will break the animation because we haven't made this change yet 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oiiiii how did it sneak innnnnn.

Since this is in the new stuff and I have these changes, how about we keep it and I open the follow-up PR that fixes the fade_in?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Went ahead and dropped this into #3485 .

] = useState(shouldImmediatelyShowPopover)

const closeDefaultConnectionPopover = useCallback(() => {
if (shouldImmediatelyShowPopover && isShowingDefaultConnectionPopover) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can remove the check for isShowingDefaultConnectionPopover here. Is there a reason we're using useCallback on these functions?

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 have to tell you that my radar for when useCallback is the right move and when it's the wrong one is as broken as the tree that was used to make my desk.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I missed the first part of the note—why do you think that? It seems like the correct condition, no? If it's not showing and we're set to immediately show it, we shouldn't dispatch anything, because that means it's closing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Because this only runs when the popover is open right?

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 always assume propagation delays for stuff like this, not least because there are cases where we delay rendering changes to wait on animations, etc. We can always case by case those, but it's easier to just consistently get the condition right so reasoning is localized rather than requiring global knowledge of caller behavior.

@@ -203,6 +211,8 @@ export default class PreferenceService extends BaseService<Events> {
)
}

// FIXME This should not be publicly accessible, but triggered by observing
// FIXME an event on the signer service.
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Comment on lines +1578 to +1579
// FIXME Both of these should be done as observations of the preference
// FIXME service event rather than being managed by `main`.
Copy link
Contributor

Choose a reason for hiding this comment

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

This pattern seems great but I reckon the logic is going to get a bit hard to follow 🤔. Do we want to only execute calls to other services on events emitted by services as reactions to mutations?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definitely yes for cross-service stuff. No reason Main should be deciding what the ProviderBridgeService should be doing with an event—that is the ProviderBridgeService's responsibility. The only such triggers from Main should be directly due to redux actions, and in any such action we should be asking “is the service reacting to the user's change, or is the service reacting to a system change”. In this case, the preferences service reacts to the user's change, and that system then becomes a system change that triggers other adjustments. This is just separation of responsibilities, but we haven't done a great job of following it everywhere.

The short articulation is: services are responsible for their own state and for reacting to the state of other services. This is another reason why Main really needs to be renamed to ReduxService; it's charged with mediating with redux, it is NOT some sort of superservice meant to mediate between many services, unless there's some redux-based thing that needs to intervene. Similarly, this is why settings need to make it into PreferencesService—that allows it to be the source of truth for settings, not the redux store, which should generally not be the source of truth for anything.

This opens up the possibility of further paring down the redux store by only storing “recent” things in it, and fetching async from the backend for less recent things (e.g. transactions). I think that's months away, and it won't make sense for everything, but it's what the overall architectural approach is rooted in.

@hyphenized hyphenized merged commit 1a8e79a into main Jun 16, 2023
@hyphenized hyphenized deleted the case-dismissed branch June 16, 2023 17:51
@Shadowfiend Shadowfiend mentioned this pull request Jun 20, 2023
2 tasks
this.version(17).stores({
preferences: "++id",
signersSettings: "&id",
shownDismissableItems: "&id,shown",
Copy link
Contributor

Choose a reason for hiding this comment

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

Boolean can't be indexed, so adding a shown here does not make much sense.

https://dexie.org/docs/Version/Version.stores()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Bah, yeah. I'd rather not add a migration here but maybe it won't be necessary given we haven't shipped this yet.

@jagodarybacka jagodarybacka mentioned this pull request Jun 22, 2023
jagodarybacka added a commit that referenced this pull request Jun 23, 2023
## What's Changed
* Repeater Connection: Forward requests to new default when default is
switched off during dApp connection flow by @Shadowfiend in
#3462
* Auto-Not-So-Matic: Fix two matic.network URLs to polygon.technology by
@Shadowfiend in #3483
* v0.38.0 by @kkosiorowska in
#3480
* Case Dismissed: Forcibly show DAppConnectionInfoBar popover on first
dApp connection by @Shadowfiend in
#3464
* Add Hardhat Fork Functionality by @0xDaedalus in
#3247
* Faded Jeans: Rename fadeIn class to fade_in by @Shadowfiend in
#3485
* Fix issue for discovery transaction hash by @kkosiorowska in
#3458
* Full Sweep: Drop the USE_UPDATED_SIGNING_UI feature flag by
@Shadowfiend in #3475
* Token Discovery - Remap redux asset balances by @hyphenized in
#3195
* Make specific warnings for adding custom asset by @kkosiorowska in
#3478
* Run NFTs e2e tests on a controlled wallet address by
@michalinacienciala in #3487
* v0.38.1 by @jagodarybacka in
#3484


**Full Changelog**:
v0.38.1...v0.39.0
Latest build:
[extension-builds-3496](https://github.com/tahowallet/extension/suites/13792957673/artifacts/764738599)
(as of Thu, 22 Jun 2023 14:27:32 GMT).
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.

3 participants