diff --git a/webapp/public/coi-serviceworker.min.js b/webapp/public/coi-serviceworker.min.js new file mode 100644 index 0000000..e1fb9a7 --- /dev/null +++ b/webapp/public/coi-serviceworker.min.js @@ -0,0 +1,2 @@ +/*! coi-serviceworker v0.1.7 - Guido Zuidhof and contributors, licensed under MIT */ +let coepCredentialless=!1;"undefined"==typeof window?(self.addEventListener("install",(()=>self.skipWaiting())),self.addEventListener("activate",(e=>e.waitUntil(self.clients.claim()))),self.addEventListener("message",(e=>{e.data&&("deregister"===e.data.type?self.registration.unregister().then((()=>self.clients.matchAll())).then((e=>{e.forEach((e=>e.navigate(e.url)))})):"coepCredentialless"===e.data.type&&(coepCredentialless=e.data.value))})),self.addEventListener("fetch",(function(e){const r=e.request;if("only-if-cached"===r.cache&&"same-origin"!==r.mode)return;const s=coepCredentialless&&"no-cors"===r.mode?new Request(r,{credentials:"omit"}):r;e.respondWith(fetch(s).then((e=>{if(0===e.status)return e;const r=new Headers(e.headers);return r.set("Cross-Origin-Embedder-Policy",coepCredentialless?"credentialless":"require-corp"),coepCredentialless||r.set("Cross-Origin-Resource-Policy","cross-origin"),r.set("Cross-Origin-Opener-Policy","same-origin"),new Response(e.body,{status:e.status,statusText:e.statusText,headers:r})})).catch((e=>console.error(e))))}))):(()=>{const e={shouldRegister:()=>!0,shouldDeregister:()=>!1,coepCredentialless:()=>!(window.chrome||window.netscape),doReload:()=>window.location.reload(),quiet:!1,...window.coi},r=navigator;r.serviceWorker&&r.serviceWorker.controller&&(r.serviceWorker.controller.postMessage({type:"coepCredentialless",value:e.coepCredentialless()}),e.shouldDeregister()&&r.serviceWorker.controller.postMessage({type:"deregister"})),!1===window.crossOriginIsolated&&e.shouldRegister()&&(window.isSecureContext?r.serviceWorker&&r.serviceWorker.register(window.document.currentScript.src).then((s=>{!e.quiet&&console.log("COOP/COEP Service Worker registered",s.scope),s.addEventListener("updatefound",(()=>{!e.quiet&&console.log("Reloading page to make use of updated COOP/COEP Service Worker."),e.doReload()})),s.active&&!r.serviceWorker.controller&&(!e.quiet&&console.log("Reloading page to make use of COOP/COEP Service Worker."),e.doReload())}),(r=>{!e.quiet&&console.error("COOP/COEP Service Worker failed to register:",r)})):!e.quiet&&console.log("COOP/COEP Service Worker not registered, a secure context is required."))})(); \ No newline at end of file diff --git a/webapp/public/index.html b/webapp/public/index.html index edbc6ea..a58c3f1 100644 --- a/webapp/public/index.html +++ b/webapp/public/index.html @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> + @@ -20,21 +21,13 @@ - + LEStrADE - +
diff --git a/webapp/src/App.vue b/webapp/src/App.vue index 7aa6cc9..a078d16 100644 --- a/webapp/src/App.vue +++ b/webapp/src/App.vue @@ -25,6 +25,9 @@ limitations under the License. + + + @@ -44,19 +47,43 @@ import EventBus from './event-bus.js' import { initShutdownDetection } from '@/utils/shutdownDetection.js' import DemoOverlay from '@/components/Demo/DemoOverlay.vue' import CompareEventsDialog from '@/components/Events/CompareEventsDialog.vue' +import OpfsCompatibilityDialog from '@/components/OpfsCompatibilityDialog.vue' export default { name: 'app', components: { DemoOverlay, CompareEventsDialog, + OpfsCompatibilityDialog, + }, + data: function() { + return { + opfsDialog: false, + } }, computed: { snackbar() { return this.$store.state.snackbar }, }, + watch: { + $route: function() { + if (this.checkOpfsIncompatibility()) { + this.opfsDialog = true + } + } + }, methods: { + checkOpfsIncompatibility: function() { + if (window.crossOriginIsolated) return false + + const sabMissing = typeof SharedArrayBuffer === 'undefined' + const reloadAttempted = !!sessionStorage.getItem('coi_reload_attempted') + const currentRoute = this.$route + const routeRequiresOpfs = currentRoute && currentRoute.meta && currentRoute.meta.requiresOpfs + + return sabMissing || reloadAttempted || routeRequiresOpfs + }, setErrorSnackBar: function (message) { const snackbar = { message: message, @@ -72,6 +99,12 @@ export default { mounted() { // Listen on errors from REST API calls EventBus.$on('errorSnackBar', this.setErrorSnackBar) + // Show modal if DB layer or router guard emits opfsUnavailable + EventBus.$on('opfsUnavailable', function() { this.opfsDialog = true; }.bind(this)) + + if (window.opfsUnavailable || this.checkOpfsIncompatibility()) { + this.opfsDialog = true; + } const isDark = localStorage.getItem('isDarkTheme') if (isDark) { @@ -88,6 +121,7 @@ export default { }, beforeDestroy() { EventBus.$off('errorSnackBar') + EventBus.$off('opfsUnavailable') }, } diff --git a/webapp/src/components/Import/PlatformSelector.vue b/webapp/src/components/Import/PlatformSelector.vue index cecbaa3..1ab3f19 100644 --- a/webapp/src/components/Import/PlatformSelector.vue +++ b/webapp/src/components/Import/PlatformSelector.vue @@ -82,6 +82,7 @@ Added for WISPR Lab / data-export-gui project import { PLATFORM_METADATA } from '../../utils/uploadFormUtils.js' import DiscordIcon from '../DiscordIcon.vue' import ImportZone from './ImportZone.vue' +import EventBus from '@/event-bus.js' export default { name: 'PlatformSelector', @@ -96,6 +97,14 @@ export default { selectedPlatformId: null, } }, + watch: { + dialog(val) { + if (val && !window.crossOriginIsolated) { + this.dialog = false + EventBus.$emit('opfsUnavailable') + } + } + }, computed: { platforms() { return Object.entries(PLATFORM_METADATA).map(([id, meta]) => ({ id, ...meta })) diff --git a/webapp/src/components/OpfsCompatibilityDialog.vue b/webapp/src/components/OpfsCompatibilityDialog.vue new file mode 100644 index 0000000..8a41d92 --- /dev/null +++ b/webapp/src/components/OpfsCompatibilityDialog.vue @@ -0,0 +1,160 @@ + + + diff --git a/webapp/src/components/SafeExitButton.vue b/webapp/src/components/SafeExitButton.vue index 87b9962..9862702 100644 --- a/webapp/src/components/SafeExitButton.vue +++ b/webapp/src/components/SafeExitButton.vue @@ -27,6 +27,7 @@