diff --git a/src/components/AppVersionRedirectDialog.svelte b/src/components/AppVersionRedirectDialog.svelte
new file mode 100644
index 000000000..e0de1049c
--- /dev/null
+++ b/src/components/AppVersionRedirectDialog.svelte
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+ {$t('popup.appVersionRedirect.header')}
+
+
+
+
{$t('popup.appVersionRedirect.explain')}
+
+ {$t('popup.appVersionRedirect.button.redirect')}
+ {$t('popup.appVersionRedirect.button.stay')}
+
+
{$t('popup.appVersionRedirect.uk')}
+
+
+
diff --git a/src/messages/ui.en.json b/src/messages/ui.en.json
index fd31ba5e2..43caa2605 100644
--- a/src/messages/ui.en.json
+++ b/src/messages/ui.en.json
@@ -285,6 +285,12 @@
"popup.outdatedmicrobit.button.update": "Update now",
"popup.outdatedmicrobit.button.update.mkcd": "Open MakeCode",
+ "popup.appVersionRedirect.header": "Are you a UK* primary school teacher?",
+ "popup.appVersionRedirect.explain": "If you are not a UK* primary school teacher, you will be redirected to our prototype version of this tool. This version is only for the UK's BBC micro:bit playground survey.",
+ "popup.appVersionRedirect.button.redirect": "I'm not a UK primary school teacher",
+ "popup.appVersionRedirect.button.stay": "I'm a UK primary school teacher",
+ "popup.appVersionRedirect.uk": "*includes crown dependencies Jersey, Guernsey and the Isle of Man",
+
"arrowIconRight.altText": "arrow pointing right",
"arrowIconDown.altText": "arrow pointing down",
diff --git a/src/script/stores/uiStore.ts b/src/script/stores/uiStore.ts
index 8491bc21e..8ed378c60 100644
--- a/src/script/stores/uiStore.ts
+++ b/src/script/stores/uiStore.ts
@@ -14,6 +14,7 @@ import MBSpecs from '../microbit-interfacing/MBSpecs';
import { gestures } from './Stores';
import { HexOrigin } from '../../StaticConfiguration';
import { DeviceRequestStates } from '../microbit-interfacing/MicrobitConnection';
+import { persistantWritable } from './storeUtil';
import { logError, logEvent } from '../utils/logging';
// TODO: Rename? Split up further?
@@ -42,6 +43,11 @@ if (compatibilityResult.bluetooth) {
export const isCompatibilityWarningDialogOpen = writable
(false);
+export const hasSeenAppVersionRedirectDialog = persistantWritable(
+ 'hasSeenAppVersionRedirectDialog',
+ false,
+);
+
export enum ModelView {
TILE,
STACK,
diff --git a/src/script/utils/api.ts b/src/script/utils/api.ts
new file mode 100644
index 000000000..45f1054bc
--- /dev/null
+++ b/src/script/utils/api.ts
@@ -0,0 +1,36 @@
+import { logError } from './logging';
+
+/**
+ * (c) 2023, Center for Computational Thinking and Design at Aarhus University and contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+interface BrowserInfo {
+ country?: string;
+ region?: string;
+}
+
+const isBrowserInfo = (v: unknown): v is BrowserInfo => {
+ return typeof v === 'object' && v !== null;
+};
+
+/**
+ * Best effort attempt to fetch browser info.
+ * On error it returns empty browser info.
+ */
+export const fetchBrowserInfo = async (): Promise => {
+ try {
+ // Note this API is not available if you're running locally without configuring API_PROXY in .env
+ const response = await fetch('/api/v1/browser/info');
+ if (!response.ok) {
+ return {};
+ }
+ const json = await response.json();
+ if (isBrowserInfo(json)) {
+ return json;
+ }
+ } catch (e) {
+ logError('Failed to fetch browser info', e);
+ }
+ return {};
+};
diff --git a/vite.config.ts b/vite.config.ts
index b8d756e67..48f3dca48 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -4,48 +4,66 @@
*
* SPDX-License-Identifier: MIT
*/
-import { defineConfig } from 'vite';
+import { defineConfig, loadEnv } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import WindiCSS from 'vite-plugin-windicss';
import { preprocessMeltUI, sequence } from '@melt-ui/pp';
import { sveltePreprocess } from 'svelte-preprocess/dist/autoProcess';
import Icons from 'unplugin-icons/vite';
-export default defineConfig({
- base: process.env.BASE_URL ?? '/',
- plugins: [
- svelte({
- preprocess: sequence([sveltePreprocess({ typescript: true }), preprocessMeltUI()]),
+export default defineConfig(({ mode }) => {
+ const commonEnv = loadEnv(mode, process.cwd(), '');
- onwarn(warning, defaultHandler) {
- if (warning.code.includes('a11y')) return; // Ignores the a11y warnings when compiling. This does not apply to the editor, see comment at bottom for vscode instructions
+ return {
+ base: process.env.BASE_URL ?? '/',
+ plugins: [
+ svelte({
+ preprocess: sequence([
+ sveltePreprocess({ typescript: true }),
+ preprocessMeltUI(),
+ ]),
- // handle all other warnings normally
- defaultHandler!(warning);
+ onwarn(warning, defaultHandler) {
+ if (warning.code.includes('a11y')) return; // Ignores the a11y warnings when compiling. This does not apply to the editor, see comment at bottom for vscode instructions
+
+ // handle all other warnings normally
+ defaultHandler!(warning);
+ },
+ }),
+ WindiCSS(),
+ Icons({ compiler: 'svelte' }),
+ ],
+ define: {
+ 'import.meta.env.VITE_APP_VERSION': JSON.stringify(process.env.npm_package_version),
+ },
+ build: {
+ target: 'es2017',
+ rollupOptions: {
+ input: 'index.html',
},
- }),
- WindiCSS(),
- Icons({ compiler: 'svelte' }),
- ],
- define: {
- 'import.meta.env.VITE_APP_VERSION': JSON.stringify(process.env.npm_package_version),
- },
- build: {
- target: 'es2017',
- rollupOptions: {
- input: 'index.html',
},
- },
- test: {
- globals: true,
- setupFiles: ['./src/setup_tests.ts'],
- poolOptions: {
- threads: {
- // threads disabled for now due to https://github.com/vitest-dev/vitest/issues/1982
- singleThread: true,
+ server: commonEnv.API_PROXY
+ ? {
+ port: 5172,
+ proxy: {
+ '/api/v1': {
+ target: commonEnv.API_PROXY,
+ changeOrigin: true,
+ },
+ },
+ }
+ : undefined,
+ test: {
+ globals: true,
+ setupFiles: ['./src/setup_tests.ts'],
+ poolOptions: {
+ threads: {
+ // threads disabled for now due to https://github.com/vitest-dev/vitest/issues/1982
+ singleThread: true,
+ },
},
},
- },
+ };
});
/**