Open Noam-Bendelac opened 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.
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:
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).
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).
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?
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.