digidem / comapeo-mobile

The next version of Mapeo mobile
GNU General Public License v3.0
5 stars 1 forks source link

feat: notified on canceled invited #366

Closed ErikSin closed 2 months ago

ErikSin commented 3 months ago

Sorry for the long explanation, but I think it is necessary to understand the architectural decisions that were made

Creates notification when invite has been cancelled.

I had to refactor the invite listeners to account for some of the peculiarities of this flow.

When an invitor cancels an invite, it is only relevant to the invitee if the invitee has been notified of the invite. For example, if the invitee receives an invite, they will be notified of that invite and a bottom sheet will pop up asking them if they would like to accept an invite. Before they have chosen to accept or decline this invite, if they receive another invite, this second invite is queued, and the second invite is only shown if they decline the first invite. But if the invitor of the second invite cancels the invite, and the invitee has not even seen this invite yet, we don't want to notify the invitee it has been cancelled. Otherwise they might think the first invite has been cancelled. So we want to make sure that they only received the notification that it is being cancelled when the user is actively interacting with the invite.

We know a user is actively interacting with a cancelled invite when:

  1. the project invite bottoms sheet is open
  2. the cancelled invite is the oldest invite (because it is designed that invites are dealt with chronologically)

Previous implementation (and why it didn't work for canceling)

Invite listener was set up at the root of the app. This listener listened for invites being added and removed. When an invite was added or removed, we invalidated the cache which retrieved all invites. This meant the client state was always updated according to the server state.

If we kept this architecture, when an invite was cancelled, the list of invites would be updated, and would not contain the cancelled invite. Due to the declarative nature of react, this would mean the invite would disappear and the invite bottom sheet would be closed (or the next queued invite would be shown). Obviously we want the user to be notified that their invite was cancelled, so this wouldn't work.

New architectural decisions

On first glance it would seem that the easy way would be to intercept all cancelled invites and notify the user. But again we do not want to notify the user of all cancelled invites, only the ones that the user is already interacting with. In order to do that we need to 1.intercept all removed invites 2a.If reason !== 'cancelled' invalidate the cache as normal 2b.if reason === 'cancelled' determine if the user is actively interacting with the invite that was cancelled (based on the 2 criteria above) 3a.If the user is not interacting with the cancelled invite, invalidate cache as normal 3b.If the IS interacting with the cancelled invite, do not invalidate the cache (again, the bottom sheet is declarative so if the invite list gets updated the bottom sheet will close or show the next invite). 4.Notify the user (by updating the UI of the bottom sheet) 5.User acknowledges that the invite has been cancelled, the cache is imperatively invalidated, and the client side list of invites now matches the server side list of invites-where the cancelled invite has been removed.

https://github.com/digidem/comapeo-mobile/assets/67773827/e14a13dd-571f-4fe1-ac0e-f51c4085ef47