Skip to content

Commit 339f86c

Browse files
Add UI for micro:bit reconnection attempts (#214)
1 parent 1c2a42f commit 339f86c

25 files changed

+521
-414
lines changed

src/App.svelte

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
import {
1111
compatibility,
1212
isCompatibilityWarningDialogOpen,
13-
state,
1413
} from './script/stores/uiStore';
1514
import { checkCompatibility } from './script/compatibility/CompatibilityChecker';
1615
import IncompatiblePlatformView from './views/IncompatiblePlatformView.svelte';
1716
import CompatibilityWarningDialog from './components/CompatibilityWarningDialog.svelte';
18-
import CookieManager from './script/CookieManager';
1917
import Router from './router/Router.svelte';
2018
import ControlBar from './components/control-bar/ControlBar.svelte';
2119
import { t } from './i18n';
@@ -29,13 +27,6 @@
2927
import ConnectDialogContainer from './components/connection-prompt/ConnectDialogContainer.svelte';
3028
import { Paths, currentPath, getTitle, navigate } from './router/paths';
3129
import HomeIcon from 'virtual:icons/ri/home-2-line';
32-
import { DeviceRequestStates } from './script/microbit-interfacing/MicrobitConnection';
33-
34-
if (CookieManager.isReconnectFlagSet()) {
35-
$state.offerReconnect = true;
36-
$state.reconnectState = DeviceRequestStates.INPUT;
37-
CookieManager.unsetReconnectFlag();
38-
}
3930
4031
onMount(() => {
4132
const { bluetooth, usb } = get(compatibility);

src/components/LoadingSpinner.svelte

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
.loader:before,
1111
.loader:after {
1212
border-radius: 50%;
13-
width: 2.5em;
14-
height: 2.5em;
13+
width: 25px;
14+
height: 25px;
1515
-webkit-animation-fill-mode: both;
1616
animation-fill-mode: both;
1717
-webkit-animation: load7 1.8s infinite ease-in-out;
1818
animation: load7 1.8s infinite ease-in-out;
1919
}
2020
.loader {
2121
font-size: 10px;
22-
position: relative;
22+
position: absolute;
23+
top: -25px;
2324
text-indent: -9999em;
2425
-webkit-transform: translateZ(0);
2526
-ms-transform: translateZ(0);
@@ -63,6 +64,6 @@
6364
}
6465
</style>
6566

66-
<div class="flex justify-center items-center self-center m-auto h-20">
67+
<div class="flex justify-center h-25px w-full relative">
6768
<div class="loader text-secondary" />
6869
</div>

src/components/PleaseConnectFirst.svelte

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,20 @@
66

77
<script lang="ts">
88
import { t } from '../i18n';
9+
import { DeviceRequestStates } from '../script/microbit-interfacing/MicrobitConnection';
10+
import Microbits from '../script/microbit-interfacing/Microbits';
911
import { startConnectionProcess } from '../script/stores/connectDialogStore';
12+
import { state } from '../script/stores/uiStore';
13+
import { reconnect } from '../script/utils/reconnect';
1014
import StandardButton from './StandardButton.svelte';
15+
16+
const handleInputConnect = async () => {
17+
if ($state.showReconnectHelp || Microbits.getInputMicrobit()) {
18+
reconnect();
19+
} else {
20+
startConnectionProcess();
21+
}
22+
};
1123
</script>
1224

1325
<div>
@@ -18,6 +30,13 @@
1830
{$t('menu.trainer.notConnected2')}
1931
</p>
2032
<div class="text-center ml-auto mr-auto mb-2 mt-10" />
21-
<StandardButton type="primary" onClick={startConnectionProcess}
22-
>{$t('footer.connectButton')}</StandardButton>
33+
<StandardButton
34+
type="primary"
35+
disabled={$state.reconnectState.reconnecting}
36+
onClick={handleInputConnect}
37+
>{$t(
38+
$state.showReconnectHelp || Microbits.getInputMicrobit()
39+
? 'actions.reconnect'
40+
: 'footer.connectButton',
41+
)}</StandardButton>
2342
</div>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<!--
2+
(c) 2023, Center for Computational Thinking and Design at Aarhus University and contributors
3+
4+
SPDX-License-Identifier: MIT
5+
-->
6+
7+
<script lang="ts">
8+
import ExternalLinkIcon from 'virtual:icons/ri/external-link-line';
9+
import StandardButton from './StandardButton.svelte';
10+
import { t } from '../i18n';
11+
import { state } from '../script/stores/uiStore';
12+
import { reconnect } from '../script/utils/reconnect';
13+
import StandardDialog from './dialogs/StandardDialog.svelte';
14+
import { stateOnHideReconnectHelp } from '../script/microbit-interfacing/state-updaters';
15+
16+
export let isOpen: boolean = false;
17+
18+
$: content = (() => {
19+
switch ($state.reconnectState.connectionType) {
20+
case 'bluetooth': {
21+
return {
22+
heading:
23+
$state.showReconnectHelp === 'userTriggered'
24+
? 'reconnectFailed.bluetoothHeading'
25+
: 'disconnectedWarning.bluetoothHeading',
26+
subtitle:
27+
$state.showReconnectHelp === 'userTriggered'
28+
? 'reconnectFailed.bluetooth1'
29+
: 'disconnectedWarning.bluetooth1',
30+
listHeading: 'disconnectedWarning.bluetooth2',
31+
bulletOne: 'disconnectedWarning.bluetooth3',
32+
bulletTwo: 'disconnectedWarning.bluetooth4',
33+
};
34+
}
35+
case 'bridge': {
36+
return {
37+
heading:
38+
$state.showReconnectHelp === 'userTriggered'
39+
? 'reconnectFailed.bridgeHeading'
40+
: 'disconnectedWarning.bridgeHeading',
41+
subtitle:
42+
$state.showReconnectHelp === 'userTriggered'
43+
? 'reconnectFailed.bridge1'
44+
: 'disconnectedWarning.bridge1',
45+
listHeading: 'connectMB.usbTryAgain.replugMicrobit2',
46+
bulletOne: 'connectMB.usbTryAgain.replugMicrobit3',
47+
bulletTwo: 'connectMB.usbTryAgain.replugMicrobit4',
48+
};
49+
}
50+
case 'remote': {
51+
return {
52+
heading:
53+
$state.showReconnectHelp === 'userTriggered'
54+
? 'reconnectFailed.remoteHeading'
55+
: 'disconnectedWarning.remoteHeading',
56+
subtitle:
57+
$state.showReconnectHelp === 'userTriggered'
58+
? 'reconnectFailed.remote1'
59+
: 'disconnectedWarning.remote1',
60+
listHeading: 'disconnectedWarning.bluetooth2',
61+
bulletOne: 'disconnectedWarning.bluetooth3',
62+
bulletTwo: 'disconnectedWarning.bluetooth4',
63+
};
64+
}
65+
default: {
66+
return {
67+
heading: '',
68+
subtitle: '',
69+
listHeading: '',
70+
bulletOne: '',
71+
bulletTwo: '',
72+
};
73+
}
74+
}
75+
})();
76+
</script>
77+
78+
{#if $state.reconnectState.connectionType !== 'none'}
79+
<StandardDialog {isOpen} onClose={stateOnHideReconnectHelp} class="w-150 space-y-5">
80+
<svelte:fragment slot="heading">
81+
{$t(content.heading)}
82+
</svelte:fragment>
83+
<svelte:fragment slot="body">
84+
<p>{$t(content.subtitle)}</p>
85+
<div>
86+
<p>{$t(content.listHeading)}</p>
87+
<ul class="list-disc pl-10">
88+
<li>{$t(content.bulletOne)}</li>
89+
<li>{$t(content.bulletTwo)}</li>
90+
</ul>
91+
</div>
92+
93+
<div class="flex justify-end gap-x-5">
94+
<a
95+
class="inline-flex mr-auto gap-x-1 items-center text-link outline-none focus-visible:ring-4 focus-visible:ring-offset-1 focus-visible:ring-ring"
96+
href=""
97+
target="_blank"
98+
rel="noopener">
99+
{$t('connectMB.troubleshooting')}
100+
<ExternalLinkIcon />
101+
</a>
102+
<StandardButton onClick={stateOnHideReconnectHelp}
103+
>{$t('actions.cancel')}</StandardButton>
104+
<StandardButton type="primary" onClick={() => reconnect(true)}
105+
>{$t('actions.reconnect')}</StandardButton>
106+
</div>
107+
</svelte:fragment>
108+
</StandardDialog>
109+
{/if}

src/components/ReconnectPrompt.svelte

Lines changed: 0 additions & 131 deletions
This file was deleted.

0 commit comments

Comments
 (0)