From 9707dbee6fbbf8a5fa3c92762588a5405364acc6 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 29 May 2020 19:25:57 +0200 Subject: [PATCH] [Glitch] Fix timeline markers in Firefox Port cc650bc023e00d07c5796b7602d86597bb437f45 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/actions/markers.js | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/markers.js b/app/javascript/flavours/glitch/actions/markers.js index b237d82ec..96e29accf 100644 --- a/app/javascript/flavours/glitch/actions/markers.js +++ b/app/javascript/flavours/glitch/actions/markers.js @@ -16,7 +16,10 @@ export const synchronouslySubmitMarkers = () => (dispatch, getState) => { return; } - if (window.fetch) { + // The Fetch API allows us to perform requests that will be carried out + // after the page closes. But that only works if the `keepalive` attribute + // is supported. + if (window.fetch && 'keepalive' in new Request('')) { fetch('/api/v1/markers', { keepalive: true, method: 'POST', @@ -26,13 +29,31 @@ export const synchronouslySubmitMarkers = () => (dispatch, getState) => { }, body: JSON.stringify(params), }); - } else { + return; + } else if (navigator && navigator.sendBeacon) { + // Failing that, we can use sendBeacon, but we have to encode the data as + // FormData for DoorKeeper to recognize the token. + const formData = new FormData(); + formData.append('bearer_token', accessToken); + for (const [id, value] of Object.entries(params)) { + formData.append(`${id}[last_read_id]`, value.last_read_id); + } + if (navigator.sendBeacon('/api/v1/markers', formData)) { + return; + } + } + + // If neither Fetch nor sendBeacon worked, try to perform a synchronous + // request. + try { const client = new XMLHttpRequest(); client.open('POST', '/api/v1/markers', false); client.setRequestHeader('Content-Type', 'application/json'); client.setRequestHeader('Authorization', `Bearer ${accessToken}`); client.SUBMIT(JSON.stringify(params)); + } catch (e) { + // Do not make the BeforeUnload handler error out } };