Skip to content

Commit 254bb4c

Browse files
Improve compatibility with older browsers (#227)
- Avoid using top-level await to improve compatibility with older browsers. - Change build target for better browser support. - Fix i18n tests - Check Bluetooth availability asynchronously
1 parent 17c9ea8 commit 254bb4c

File tree

6 files changed

+73
-58
lines changed

6 files changed

+73
-58
lines changed

src/App.svelte

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
ConnectDialogStates,
3131
connectionDialogState,
3232
} from './script/stores/connectDialogStore';
33+
import { isLoading } from 'svelte-i18n';
3334
3435
onMount(() => {
3536
const { bluetooth, usb } = $compatibility;
@@ -51,50 +52,51 @@
5152
}
5253
</script>
5354

54-
<Router>
55-
<div class="sr-only" bind:this={routeAnnouncementEl} aria-live="polite" />
56-
{#if !$compatibility.platformAllowed}
57-
<!-- Denies mobile users access to the platform -->
58-
<IncompatiblePlatformView />
59-
{:else}
60-
<div class="h-full w-full m-0 relative flex">
61-
<OverlayView />
62-
<!-- Wait for consent dialog to avoid a clash -->
63-
{#if $consent}
64-
<CompatibilityWarningDialog />
65-
{/if}
66-
67-
<div class="w-full flex flex-col bg-backgrounddark">
68-
<ControlBar>
69-
<div class="flex items-center divide-x h-full">
70-
<div class="h-32px flex items-center">
71-
<img class="pr-3 w-166px" src={microbitLogoImage} alt="micro:bit" />
55+
{#if !$isLoading}
56+
<Router>
57+
<div class="sr-only" bind:this={routeAnnouncementEl} aria-live="polite" />
58+
{#if !$compatibility.platformAllowed}
59+
<!-- Denies mobile users access to the platform -->
60+
<IncompatiblePlatformView />
61+
{:else}
62+
<div class="h-full w-full m-0 relative flex">
63+
<OverlayView />
64+
<!-- Wait for consent dialog to avoid a clash -->
65+
{#if $consent}
66+
<CompatibilityWarningDialog />
67+
{/if}
68+
<div class="w-full flex flex-col bg-backgrounddark">
69+
<ControlBar>
70+
<div class="flex items-center divide-x h-full">
71+
<div class="h-32px flex items-center">
72+
<img class="pr-3 w-166px" src={microbitLogoImage} alt="micro:bit" />
73+
</div>
74+
<div class="h-32px flex items-center">
75+
<img
76+
class="pl-3 mt-2px w-253px"
77+
src={appNameImage}
78+
alt={$t('content.index.title')} />
79+
</div>
7280
</div>
73-
<div class="h-32px flex items-center">
74-
<img
75-
class="pl-3 mt-2px w-253px"
76-
src={appNameImage}
77-
alt={$t('content.index.title')} />
81+
<div class="flex gap-5">
82+
<a
83+
class="text-xl p-2 rounded-full outline-none focus-visible:ring-ringBright focus-visible:ring-4 focus-visible:ring-offset-1"
84+
href={Paths.HOME}
85+
on:click|preventDefault={() => navigate(Paths.HOME)}>
86+
<span class="sr-only">{$t('homepage.Link')}</span>
87+
<HomeIcon class="text-white" aria-hidden />
88+
</a>
89+
<SettingsMenu />
90+
<HelpMenu />
7891
</div>
79-
</div>
80-
<div class="flex gap-5">
81-
<a
82-
class="text-xl p-2 rounded-full outline-none focus-visible:ring-ringBright focus-visible:ring-4 focus-visible:ring-offset-1"
83-
href={Paths.HOME}
84-
on:click|preventDefault={() => navigate(Paths.HOME)}>
85-
<span class="sr-only">{$t('homepage.Link')}</span>
86-
<HomeIcon class="text-white" aria-hidden />
87-
</a>
88-
<SettingsMenu />
89-
<HelpMenu />
90-
</div>
91-
</ControlBar>
92+
</ControlBar>
9293

93-
<div class="relative flex-1 flex-row">
94-
<PageContentView />
94+
<div class="relative flex-1 flex-row">
95+
<PageContentView />
96+
</div>
9597
</div>
9698
</div>
97-
</div>
98-
{/if}
99-
</Router>
100-
<ConnectDialogContainer />
99+
{/if}
100+
</Router>
101+
<ConnectDialogContainer />
102+
{/if}

src/__tests__/i18n.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ describe('Initialization tests', () => {
3232
search: '',
3333
},
3434
}));
35-
const i18n = await import('../i18n');
36-
const getText = get(i18n.t);
35+
const { t, waitLocale } = await import('../i18n');
36+
await waitLocale();
37+
const getText = get(t);
3738

3839
const translatedText = getText('alert.isRecording');
39-
4040
expect(translatedText).toBe("Rydych chi'n recordio ar hyn o bryd!");
4141
});
4242

@@ -49,11 +49,11 @@ describe('Initialization tests', () => {
4949
search: '',
5050
},
5151
}));
52-
const i18n = await import('../i18n');
53-
const getText = get(i18n.t);
52+
const { t, waitLocale } = await import('../i18n');
53+
await waitLocale();
54+
const getText = get(t);
5455

5556
const translatedText = getText('alert.isRecording');
56-
5757
expect(translatedText).toBe('You are currently recording!');
5858
});
5959

@@ -66,11 +66,11 @@ describe('Initialization tests', () => {
6666
search: '?l=cy',
6767
},
6868
}));
69-
const i18n = await import('../i18n');
70-
const getText = get(i18n.t);
69+
const { t, waitLocale } = await import('../i18n');
70+
await waitLocale();
71+
const getText = get(t);
7172

7273
const translatedText = getText('alert.isRecording');
73-
7474
expect(translatedText).toBe("Rydych chi'n recordio ar hyn o bryd!");
7575
});
7676
});

src/i18n.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { FormatXMLElementFn } from 'intl-messageformat';
99
import { getLocaleFromQueryString, init, locale, register } from 'svelte-i18n';
1010
import { get } from 'svelte/store';
1111
import { persistantWritable } from './script/stores/storeUtil';
12-
export { t } from 'svelte-i18n';
12+
// waitLocale is exported for testing.
13+
export { t, waitLocale } from 'svelte-i18n';
1314

1415
type InterpolationValues =
1516
| Record<
@@ -69,7 +70,7 @@ locale.subscribe(newLocal => {
6970
}
7071
});
7172

72-
await init({
73+
init({
7374
fallbackLocale: 'en',
7475
initialLocale: get(persistantLocale),
7576
// Needed to format <link> style tags.

src/script/compatibility/CompatibilityChecker.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type CompatibilityStatus = {
1515
webGL: boolean;
1616
};
1717

18-
export async function checkCompatibility(): Promise<CompatibilityStatus> {
18+
export function checkCompatibility(): CompatibilityStatus {
1919
if (localStorage.getItem('isTesting')) {
2020
return { bluetooth: true, usb: true, platformAllowed: true, webGL: true };
2121
}
@@ -37,10 +37,9 @@ export async function checkCompatibility(): Promise<CompatibilityStatus> {
3737
platformType = 'desktop';
3838
}
3939
const isPlatformAllowed = isDevMode || !nonAllowedPlatforms.includes(platformType);
40-
const bluetooth = navigator.bluetooth && (await navigator.bluetooth.getAvailability());
4140

4241
return {
43-
bluetooth,
42+
bluetooth: !!navigator.bluetooth,
4443
usb: !!navigator.usb,
4544
platformAllowed: isPlatformAllowed,
4645
webGL: webGL,

src/script/stores/uiStore.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,26 @@ import MBSpecs from '../microbit-interfacing/MBSpecs';
1414
import { gestures } from './Stores';
1515
import { HexOrigin } from '../../StaticConfiguration';
1616
import { DeviceRequestStates } from '../microbit-interfacing/MicrobitConnection';
17+
import { logError } from '../utils/logging';
1718

1819
// TODO: Rename? Split up further?
1920

2021
let text: (key: string, vars?: object) => string;
2122
t.subscribe(t => (text = t));
2223

23-
export const compatibility = writable<CompatibilityStatus>(await checkCompatibility());
24+
const compatibilityResult = checkCompatibility();
25+
export const compatibility = writable<CompatibilityStatus>(compatibilityResult);
26+
if (compatibilityResult.bluetooth) {
27+
navigator.bluetooth
28+
.getAvailability()
29+
.then(bluetoothAvailable => {
30+
compatibility.update(s => {
31+
s.bluetooth = s.bluetooth && bluetoothAvailable;
32+
return s;
33+
});
34+
})
35+
.catch(e => logError('Failed to get Bluetooth availability', e));
36+
}
2437

2538
export const isCompatibilityWarningDialogOpen = writable<boolean>(false);
2639

vite.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default defineConfig({
3131
'import.meta.env.VITE_APP_VERSION': JSON.stringify(process.env.npm_package_version),
3232
},
3333
build: {
34-
target: 'esnext',
34+
target: 'es2017',
3535
rollupOptions: {
3636
input: 'index.html',
3737
},

0 commit comments

Comments
 (0)