about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2020-05-29 19:25:57 +0200
committerThibaut Girka <thib@sitedethib.com>2020-05-29 20:02:30 +0200
commit9707dbee6fbbf8a5fa3c92762588a5405364acc6 (patch)
tree3e58e945222e0335ef618bedd64cea0283a51182
parent9bd30b8dd563d1c7066060ccfa456ea350a7fb01 (diff)
[Glitch] Fix timeline markers in Firefox
Port cc650bc023e00d07c5796b7602d86597bb437f45 to glitch-soc

Signed-off-by: Thibaut Girka <thib@sitedethib.com>
-rw-r--r--app/javascript/flavours/glitch/actions/markers.js25
1 files 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
   }
 };