echo-lab / collab-playlist

A full stack app developed for research on Collaborative Playlists.
2 stars 0 forks source link

Behavior after submitting #26

Open Noam-Bendelac opened 4 years ago

Noam-Bendelac commented 4 years ago

What should happen after submitting? Obviously send the message and action to the backend, and the backend will update the database and Spotify. But what happens in the frontend? Options:

  1. For addition, song disappears; for removal/chat, song stays but message disappears. Either way this is caused by a dispatch to take us back to the view state and SongChat is unmounted. Once backend responds with success, call some kind of invalidateResource given by the PlaylistEditor's data hook that makes it fetch the playlist again (and the setter will make the playlist rerender).

    • This might not work if the new playlist data fetched from Spotify is stale because Spotify hasn't updated its database yet or something along those lines.
    • That might be solved if we get a snapshot id of the new version of the playlist in the response from Spotify (forwarded by the backend), then somehow tell Spotify to give us that snapshot/any snapshot after it/somehow wait for that snapshot to be available (if that feature even exists).
    • Even if it works, it might not look good to the user to see their message and/or song disappear intermittently.
    • Also this is not resilient to error. If the message or song is not successfully saved by both backends, it is lost because the client doesn't save them.
  2. Don't dispatch to go to the view state until a successful response from the backend. During that time remember (store state) that there is a pendingNonidempotentRequest meaning (when rerendering) don't allow the user to make any other nonidempotent actions (including cancelling the current draft message). Upon any response, set pendingNonidempotentRequest to false. Upon error, notify user and keep state the same, meaning the draft message is still there. Upon success, possibly now or after another step to fetch the playlist, dispatch to go to the view state (draft message will disappear) which causes rerender. Either make PlaylistEditor reload the playlist resource through a dedicated callback which will then cause rerender or somehow get the already rerendering PlaylistEditor to reload the playlist resource by giving the useEffect a dependency like the playlist snapshot (hopefully given by Spotify's response and forwarded by the backend).

    • This would be more error prone by keeping the draft in the client so the user can retry if there's an error.
    • This would also make more sense to the user as the message doesn't intermittently disappear, but it would still look weird that the message stays in the editor/song stays a draft and doesn't immediately move to the chat history/become a saved song. Hopefully the pendingNonidempotentRequest that disables other buttons and could also show a loader/spinner somewhere will make it clear to the user that they just need to wait a little for the server to respond, then their action will be shown as complete.
    • Still depends on spotify giving a snapshot id and allowing us to request a particular snapshot.
  3. Store the user's action intermittently as a pending action, and dispatch to the view state. The playlist will rerender with the pending action shown as if it has been successfully completed already, maybe with some kind of signifier that it's not official yet, sort of like speculative execution. This would be like the feature in Facebook Messenger and Whatsapp that shows your recent message as if it were sent but shows an icon for whether it has been received by the server or not yet (this is the icon that eventually shows whether it has been read yet). Upon successful response, forget about the pending action and rerender using the actual newly fetched data (still requires snapshot id stuff). Upon failure, inform user and maybe bring back the message/action as a draft? Still show the pending action with a signifier that it failed and an option to retry?

    • Pretty complicated to implement and possibly not worth the effort.
    • This would probably make the most sense to users as it mirrors other popular messaging apps.

Option 2 might be the best trade-off between implementation and user experience, so I might use that for the long term app. For the short term app, I might go with option 1.

Noam-Bendelac commented 4 years ago

That might be solved if we get a snapshot id of the new version of the playlist in the response from Spotify (forwarded by the backend), then somehow tell Spotify to give us that snapshot/any snapshot after it/somehow wait for that snapshot to be available (if that feature even exists).

Seems like that's not a feature in the Spotify API; snapshots are for a different purpose. But I'm thinking it's safe to assume that after we get a response from our playlist modification request, if we request the playlist data again it will be up to date. Meaning this hopefully won't be a problem:

This might not work if the new playlist data fetched from Spotify is stale because Spotify hasn't updated its database yet or something along those lines.

I'm planning on implementing method 2 for the first user study.