Skip to content

Commit 90b459d

Browse files
committed
firmware/restoreOfficialDialog: add new dialog
1 parent bbd278b commit 90b459d

File tree

14 files changed

+152
-28
lines changed

14 files changed

+152
-28
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Added multi-step firmware flashing dialog.
1010
- Added support for flashing firmware via USB DFU ([support#659]).
1111
- Added an interactive introductory tour of the app.
12+
- Added restore official LEGO firmware dialog.
1213

1314
### Changed
1415
- Updated dependencies.

src/app/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ export const pybricksUsbDfuWindowsDriverInstallUrl =
4444
export const pybricksUsbLinuxUdevRulesUrl =
4545
'https://github.com/pybricks/support/discussions/688#discussioncomment-3239099';
4646

47+
export const pybricksBleFirmwareRestoreVideoUrl =
48+
'https://pybricks.com/install/technic-boost-city/#restoring-the-original-firmware';
49+
50+
export const pybricksDfuRestoreUrl = 'https://dfu.pybricks.com';
51+
4752
/** Pybricks copyright statement. */
4853
export const pybricksCopyright = 'Copyright (c) 2020-2022 The Pybricks Authors';
4954

src/firmware/actions.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -395,24 +395,3 @@ export const firmwareDidInstallPybricks = createAction(() => ({
395395
export const firmwareDidFailToInstallPybricks = createAction(() => ({
396396
type: 'firmware.action.didFailToInstallPybricks',
397397
}));
398-
399-
/**
400-
* Action that triggers the restore LEGO firmware saga.
401-
*/
402-
export const firmwareRestoreLego = createAction(() => ({
403-
type: 'firmware.action.restoreLego',
404-
}));
405-
406-
/**
407-
* Action that indicates {@link firmwareRestoreLego} succeeded.
408-
*/
409-
export const firmwareDidRestoreLego = createAction(() => ({
410-
type: 'firmware.action.didRestoreLego',
411-
}));
412-
413-
/**
414-
* Action that indicates {@link firmwareRestoreLego} failed.
415-
*/
416-
export const firmwareDidFailToRestoreLego = createAction(() => ({
417-
type: 'firmware.action.didFailToRestoreLego',
418-
}));

src/firmware/reducers.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ test('initial state', () => {
2121
"isOpen": false,
2222
},
2323
"progress": null,
24+
"restoreOfficialDialog": Object {
25+
"isOpen": false,
26+
},
2427
}
2528
`);
2629
});

src/firmware/reducers.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import { Reducer, combineReducers } from 'redux';
55
import { didFailToFinish, didFinish, didProgress, didStart } from './actions';
66
import installPybricksDialog from './installPybricksDialog/reducers';
7+
import restoreOfficialDialog from './restoreOfficialDialog/reducers';
78

89
const flashing: Reducer<boolean> = (state = false, action) => {
910
if (didStart.matches(action)) {
@@ -29,4 +30,9 @@ const progress: Reducer<number | null> = (state = null, action) => {
2930
return state;
3031
};
3132

32-
export default combineReducers({ installPybricksDialog, flashing, progress });
33+
export default combineReducers({
34+
installPybricksDialog,
35+
restoreOfficialDialog,
36+
flashing,
37+
progress,
38+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2022 The Pybricks Authors
3+
4+
import { Classes, Dialog } from '@blueprintjs/core';
5+
import classNames from 'classnames';
6+
import React from 'react';
7+
import { useDispatch } from 'react-redux';
8+
import {
9+
pybricksBleFirmwareRestoreVideoUrl,
10+
pybricksDfuRestoreUrl,
11+
} from '../../app/constants';
12+
import { useSelector } from '../../reducers';
13+
import ExternalLinkIcon from '../../utils/ExternalLinkIcon';
14+
import { firmwareRestoreOfficialDialogHide } from './actions';
15+
import { useI18n } from './i18n';
16+
17+
const RestoreOfficialDialog: React.VoidFunctionComponent = () => {
18+
const { isOpen } = useSelector((s) => s.firmware.restoreOfficialDialog);
19+
const dispatch = useDispatch();
20+
const i18n = useI18n();
21+
22+
return (
23+
<Dialog
24+
isOpen={isOpen}
25+
title={i18n.translate('title')}
26+
onClose={() => dispatch(firmwareRestoreOfficialDialogHide())}
27+
>
28+
<div className={classNames(Classes.DIALOG_BODY, Classes.RUNNING_TEXT)}>
29+
<h4>{i18n.translate('poweredUpHubs.title')}</h4>
30+
<p>{i18n.translate('poweredUpHubs.message')}</p>
31+
<p>
32+
<a
33+
href={pybricksBleFirmwareRestoreVideoUrl}
34+
target="_blank"
35+
rel="noreferrer"
36+
>
37+
{i18n.translate('poweredUpHubs.action')}
38+
</a>
39+
<ExternalLinkIcon />
40+
</p>
41+
<h4>{i18n.translate('spikeHubs.title')}</h4>
42+
<p>{i18n.translate('spikeHubs.message')}</p>
43+
<p>
44+
<a href={pybricksDfuRestoreUrl} target="_blank" rel="noreferrer">
45+
{i18n.translate('spikeHubs.action')}
46+
</a>
47+
<ExternalLinkIcon />
48+
</p>
49+
</div>
50+
</Dialog>
51+
);
52+
};
53+
54+
export default RestoreOfficialDialog;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2022 The Pybricks Authors
3+
4+
export {
5+
show as firmwareRestoreOfficialDialogShow,
6+
hide as firmwareRestoreOfficialDialogHide,
7+
} from './redux';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2022 The Pybricks Authors
3+
4+
import { useI18n as useShopifyI18n } from '@shopify/react-i18n';
5+
import type { TypedI18n } from '../../i18n';
6+
import type translations from './translations/en.json';
7+
8+
export function useI18n(): TypedI18n<typeof translations> {
9+
// istanbul ignore next: babel-loader rewrites this line
10+
const [i18n] = useShopifyI18n();
11+
return i18n;
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2022 The Pybricks Authors
3+
4+
import reducer from './redux';
5+
6+
export default reducer;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2022 The Pybricks Authors
3+
4+
import { createSlice } from '@reduxjs/toolkit';
5+
6+
type State = {
7+
isOpen: boolean;
8+
};
9+
10+
const initialState: State = {
11+
isOpen: false,
12+
};
13+
14+
const slice = createSlice({
15+
name: 'restoreOfficialDialog',
16+
initialState,
17+
reducers: {
18+
show(state) {
19+
state.isOpen = true;
20+
},
21+
hide(state) {
22+
state.isOpen = false;
23+
},
24+
},
25+
});
26+
27+
export const { show, hide } = slice.actions;
28+
export default slice.reducer;

0 commit comments

Comments
 (0)