From 8ac7d00befc030dc9ddfe4b9ebb0253ae22bc5c4 Mon Sep 17 00:00:00 2001
From: Jed Fox <git@jedfox.com>
Date: Thu, 9 Feb 2023 14:21:49 -0500
Subject: [PATCH] Allow bypassing SharedArrayBuffer override (#644)

* Allow bypassing SharedArrayBuffer override

* Make an attempt to avoid merging budgets

* Update FatalError.js

* s/allowBuggyFallback/isSharedArrayBufferOverrideEnabled/

Co-Authored-By: Matiss Janis Aboltins <886567+MatissJanis@users.noreply.github.com>

---------

Co-authored-by: Matiss Janis Aboltins <886567+MatissJanis@users.noreply.github.com>
---
 .../src/browser-preload.browser.js            |  9 +++-
 packages/desktop-client/src/browser-server.js |  2 +-
 .../src/components/FatalError.js              | 54 ++++++++++++++++++-
 .../loot-core/src/client/actions/budgets.js   |  3 ++
 4 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/packages/desktop-client/src/browser-preload.browser.js b/packages/desktop-client/src/browser-preload.browser.js
index 714ff4a8c..5886a6b2c 100644
--- a/packages/desktop-client/src/browser-preload.browser.js
+++ b/packages/desktop-client/src/browser-preload.browser.js
@@ -18,11 +18,18 @@ function createBackendWorker() {
   worker = new BackendWorker();
   initSQLBackend(worker);
 
+  if (window.SharedArrayBuffer) {
+    localStorage.removeItem('SharedArrayBufferOverride');
+  }
+
   worker.postMessage({
     type: 'init',
     version: ACTUAL_VERSION,
     isDev: IS_DEV,
-    hash: process.env.REACT_APP_BACKEND_WORKER_HASH
+    hash: process.env.REACT_APP_BACKEND_WORKER_HASH,
+    isSharedArrayBufferOverrideEnabled: localStorage.getItem(
+      'SharedArrayBufferOverride'
+    )
   });
 
   if (IS_DEV || IS_PERF_BUILD) {
diff --git a/packages/desktop-client/src/browser-server.js b/packages/desktop-client/src/browser-server.js
index 98159b3dd..1093cd819 100644
--- a/packages/desktop-client/src/browser-server.js
+++ b/packages/desktop-client/src/browser-server.js
@@ -10,7 +10,7 @@ self.addEventListener('message', e => {
       let version = msg.version;
       let hash = msg.hash;
 
-      if (!self.SharedArrayBuffer) {
+      if (!self.SharedArrayBuffer && !msg.isSharedArrayBufferOverrideEnabled) {
         self.postMessage({
           type: 'app-init-failure',
           SharedArrayBufferMissing: true
diff --git a/packages/desktop-client/src/components/FatalError.js b/packages/desktop-client/src/components/FatalError.js
index 4c816ed0b..32b7869fb 100644
--- a/packages/desktop-client/src/components/FatalError.js
+++ b/packages/desktop-client/src/components/FatalError.js
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useState } from 'react';
 
 import {
   View,
@@ -10,6 +10,7 @@ import {
   Link,
   Button
 } from 'loot-design/src/components/common';
+import { Checkbox } from 'loot-design/src/components/forms';
 import { colors } from 'loot-design/src/style';
 
 class FatalError extends React.Component {
@@ -38,7 +39,7 @@ class FatalError extends React.Component {
           <a href="https://actualbudget.github.io/docs/Troubleshooting/SharedArrayBuffer">
             our troubleshooting documentation
           </a>{' '}
-          for more information.
+          to learn more. <SharedArrayBufferOverride />
         </Text>
       );
     } else {
@@ -140,3 +141,52 @@ class FatalError extends React.Component {
   }
 }
 export default FatalError;
+
+function SharedArrayBufferOverride() {
+  let [expanded, setExpanded] = useState(false);
+  let [understand, setUnderstand] = useState(false);
+
+  return expanded ? (
+    <>
+      <P style={{ marginTop: 10 }}>
+        Actual uses <code>SharedArrayBuffer</code> to allow usage from multiple
+        tabs at once and to ensure correct behavior when switching files. While
+        it can run without access to <code>SharedArrayBuffer</code>, you may
+        encounter data loss or notice multiple budget files being merged with
+        each other.
+      </P>
+      <label
+        style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}
+      >
+        <Checkbox checked={understand} onChange={setUnderstand} /> I understand
+        the risks, run Actual in the unsupported fallback mode
+      </label>
+      <Button
+        disabled={!understand}
+        onClick={() => {
+          window.localStorage.setItem('SharedArrayBufferOverride', 'true');
+          window.location.reload();
+        }}
+      >
+        Open Actual
+      </Button>
+    </>
+  ) : (
+    <Link
+      onClick={() => setExpanded(true)}
+      style={{
+        color: `inherit !important`,
+        marginLeft: 5,
+        border: 'none !important',
+        background: 'none !important',
+        padding: '0 !important',
+        textDecoration: 'underline !important',
+        boxShadow: 'none !important',
+        display: 'inline !important',
+        font: 'inherit !important'
+      }}
+    >
+      Advanced options
+    </Link>
+  );
+}
diff --git a/packages/loot-core/src/client/actions/budgets.js b/packages/loot-core/src/client/actions/budgets.js
index 675d25e49..ec395f950 100644
--- a/packages/loot-core/src/client/actions/budgets.js
+++ b/packages/loot-core/src/client/actions/budgets.js
@@ -119,6 +119,9 @@ export function closeBudget() {
       dispatch(setAppState({ loadingText: 'Closing...' }));
       await send('close-budget');
       dispatch(setAppState({ loadingText: null }));
+      if (localStorage.getItem('SharedArrayBufferOverride')) {
+        location.reload();
+      }
     }
   };
 }
-- 
GitLab