Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start over if the initial connection fails twice #500

Merged
merged 6 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/connection-stage-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,6 @@ export class ConnectionStageActions {
};
};

private handleConnectFail = () => {
this.setFlowStep(ConnectionFlowStep.ConnectFailed);
};

private onConnected = () => {
this.setFlowStep(ConnectionFlowStep.None);
this.dataCollectionMicrobitConnected();
Expand All @@ -242,7 +238,11 @@ export class ConnectionStageActions {
);
}
case ConnectionStatus.FailedToConnect: {
return this.handleConnectFail();
return this.setStage({
...this.stage,
flowType,
flowStep: ConnectionFlowStep.ConnectFailed,
});
}
case ConnectionStatus.FailedToReconnectTwice: {
return this.setStage({
Expand Down
35 changes: 27 additions & 8 deletions src/get-next-connection-state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ describe("getNextConnectionState for radio connection", () => {
type: "radioRemote",
},
initialOnFirstConnectAttempt: true,
expectedOnFirstConnectAttempt: true,
expectedOnFirstConnectAttempt: false,
initialHasAttemptedReconnect: false,
expectedHasAttemptedReconnect: false,
expectedHasAttemptedReconnect: true,
expectedNextConnectionState: {
status: ConnectionStatus.FailedToConnect,
flowType: ConnectionFlowType.ConnectRadioRemote,
Expand Down Expand Up @@ -217,6 +217,25 @@ describe("getNextConnectionState for radio connection", () => {
},
});
});
test("radio reconnecting automatically (changing tabs) and the link micro:bit gets unplugged", () => {
testGetNextConnectionState({
input: {
currConnType: "radio",
currStatus: ConnectionStatus.ReconnectingAutomatically,
deviceStatus: DeviceConnectionStatus.NO_AUTHORIZED_DEVICE,
prevDeviceStatus: DeviceConnectionStatus.DISCONNECTED,
type: "radioRemote",
},
initialOnFirstConnectAttempt: false,
expectedOnFirstConnectAttempt: false,
initialHasAttemptedReconnect: false,
expectedHasAttemptedReconnect: false,
expectedNextConnectionState: {
status: ConnectionStatus.ConnectionLost,
flowType: ConnectionFlowType.ConnectRadioBridge,
},
});
});
test("radio bridge device connection lost by unplugging device", () => {
testGetNextConnectionState({
input: {
Expand Down Expand Up @@ -342,9 +361,9 @@ describe("getNextConnectionState for radio connection", () => {
type: "radioRemote",
},
initialOnFirstConnectAttempt: false,
expectedOnFirstConnectAttempt: false,
expectedOnFirstConnectAttempt: true,
initialHasAttemptedReconnect: true,
expectedHasAttemptedReconnect: true,
expectedHasAttemptedReconnect: false,
expectedNextConnectionState: {
status: ConnectionStatus.FailedToReconnectTwice,
flowType: ConnectionFlowType.ConnectRadioRemote,
Expand Down Expand Up @@ -456,9 +475,9 @@ describe("getNextConnectionState for bluetooth connection", () => {
type: "bluetooth",
},
initialOnFirstConnectAttempt: true,
expectedOnFirstConnectAttempt: true,
expectedOnFirstConnectAttempt: false,
initialHasAttemptedReconnect: false,
expectedHasAttemptedReconnect: false,
expectedHasAttemptedReconnect: true,
expectedNextConnectionState: {
status: ConnectionStatus.FailedToConnect,
flowType: ConnectionFlowType.ConnectBluetooth,
Expand Down Expand Up @@ -548,9 +567,9 @@ describe("getNextConnectionState for bluetooth connection", () => {
type: "bluetooth",
},
initialOnFirstConnectAttempt: false,
expectedOnFirstConnectAttempt: false,
expectedOnFirstConnectAttempt: true,
initialHasAttemptedReconnect: true,
expectedHasAttemptedReconnect: true,
expectedHasAttemptedReconnect: false,
expectedNextConnectionState: {
status: ConnectionStatus.FailedToReconnectTwice,
flowType: ConnectionFlowType.ConnectBluetooth,
Expand Down
52 changes: 38 additions & 14 deletions src/get-next-connection-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,22 @@ export type NextConnectionState =
| { status: ConnectionStatus; flowType: ConnectionFlowType }
| undefined;

export const getNextConnectionState = ({
currConnType,
currStatus,
deviceStatus,
prevDeviceStatus,
type,
hasAttempedReconnect,
setHasAttemptedReconnect,
onFirstConnectAttempt,
setOnFirstConnectAttempt,
isBrowserTabVisible,
}: GetNextConnectionStateInput): NextConnectionState => {
export const getNextConnectionState = (
input: GetNextConnectionStateInput
): NextConnectionState => {
const {
currConnType,
currStatus,
deviceStatus,
prevDeviceStatus,
type,
hasAttempedReconnect,
setHasAttemptedReconnect,
onFirstConnectAttempt,
setOnFirstConnectAttempt,
isBrowserTabVisible,
} = input;

if (currStatus === ConnectionStatus.Disconnected) {
// Do not update connection status when user explicitly disconnected connection
// until user reconnects explicitly
Expand All @@ -48,7 +52,8 @@ export const getNextConnectionState = ({
// status is already set to an error case.
if (
!isBrowserTabVisible &&
(currStatus === ConnectionStatus.ConnectionLost ||
(currStatus === ConnectionStatus.FailedToConnect ||
currStatus === ConnectionStatus.ConnectionLost ||
currStatus === ConnectionStatus.FailedToReconnect ||
currStatus === ConnectionStatus.FailedToReconnectTwice)
) {
Expand Down Expand Up @@ -103,7 +108,6 @@ export const getNextConnectionState = ({
: ConnectionStatus.FailedToReconnect;
return { status, flowType };
}

if (
// If user starts or restarts connection flow.
// Disconnection happens for newly started / restarted
Expand All @@ -127,6 +131,11 @@ export const getNextConnectionState = ({
currStatus === ConnectionStatus.Connecting &&
deviceStatus === DeviceConnectionStatus.DISCONNECTED
) {
// We count this as the first connect failure.
// If we fail a second time, we should prompt the user to start over.
// Set the fields below appropriately to acheive this.
setOnFirstConnectAttempt(false);
setHasAttemptedReconnect(true);
return { status: ConnectionStatus.FailedToConnect, flowType };
}
if (
Expand All @@ -143,6 +152,9 @@ export const getNextConnectionState = ({
hasAttempedReconnect &&
deviceStatus === DeviceConnectionStatus.DISCONNECTED
) {
// Reset connection state fields so that the next connection attempt is clean.
setOnFirstConnectAttempt(true);
setHasAttemptedReconnect(false);
return { status: ConnectionStatus.FailedToReconnectTwice, flowType };
}
if (
Expand Down Expand Up @@ -177,5 +189,17 @@ export const getNextConnectionState = ({
) {
return { status: ConnectionStatus.ReconnectingAutomatically, flowType };
}
if (
deviceStatus === DeviceConnectionStatus.NO_AUTHORIZED_DEVICE &&
currStatus === ConnectionStatus.ReconnectingAutomatically &&
currConnType === "radio"
) {
// The link micro:bit was unplugged while the user was viewing another tab.
// On return, show failed to reconnect.
return {
status: ConnectionStatus.ConnectionLost,
flowType: ConnectionFlowType.ConnectRadioBridge,
};
}
return undefined;
};
Loading