]> cat aescling's git repositories - mastodon.git/commitdiff
[Glitch] Fix timeline markers in Firefox
authorThibG <thib@sitedethib.com>
Fri, 29 May 2020 17:25:57 +0000 (19:25 +0200)
committerThibaut Girka <thib@sitedethib.com>
Fri, 29 May 2020 18:02:30 +0000 (20:02 +0200)
Port cc650bc023e00d07c5796b7602d86597bb437f45 to glitch-soc

Signed-off-by: Thibaut Girka <thib@sitedethib.com>
app/javascript/flavours/glitch/actions/markers.js

index b237d82ec00186b59d4b71d8aa3f898f2dbf974d..96e29accf405fe7a4c69ae4e30476bf506ec5456 100644 (file)
@@ -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
   }
 };