Skip to content

Commit ce9b686

Browse files
committed
feat: migrate bridge to web-usb & upgrade sdk 1.1.16
1 parent 7882efd commit ce9b686

File tree

12 files changed

+481
-348
lines changed

12 files changed

+481
-348
lines changed

config/webpack.config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,12 @@ module.exports = function (webpackEnv) {
561561
// its runtime that would otherwise be processed through "file" loader.
562562
// Also exclude `html` and `json` extensions so they get processed
563563
// by webpacks internal loaders.
564-
exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
564+
exclude: [
565+
/^$/,
566+
/\.(js|mjs|jsx|ts|tsx|cjs)$/,
567+
/\.html$/,
568+
/\.json$/,
569+
],
565570
type: 'asset/resource',
566571
},
567572
// ** STOP ** Are you adding a new loader?

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"@headlessui/react": "^1.7.2",
1010
"@heroicons/react": "^2.0.11",
1111
"@noble/hashes": "^1.1.3",
12-
"@onekeyfe/hd-core": "1.1.15",
13-
"@onekeyfe/hd-shared": "1.1.15",
14-
"@onekeyfe/hd-web-sdk": "1.1.15",
12+
"@onekeyfe/hd-common-connect-sdk": "1.1.16",
13+
"@onekeyfe/hd-core": "1.1.16",
14+
"@onekeyfe/hd-shared": "1.1.16",
1515
"@onekeyfe/ui-components": "^1.0.0",
1616
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
1717
"@reduxjs/toolkit": "^1.8.5",
@@ -185,8 +185,8 @@
185185
"sha.js": "2.4.12",
186186
"cipher-base": "1.0.6",
187187
"@babel/traverse": "7.28.4",
188-
"base-x":"3.0.11",
188+
"base-x": "3.0.11",
189189
"cross-spawn": "7.0.6",
190-
"webpack-dev-middleware":"5.3.4"
190+
"webpack-dev-middleware": "5.3.4"
191191
}
192192
}

src/components/Firmware/Firmware.tsx

Lines changed: 108 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@ import {
1111
getDeviceBootloaderVersion,
1212
} from '@onekeyfe/hd-core';
1313
import { serviceHardware } from '@/hardware';
14-
import { setDevice } from '@/store/reducers/runtime';
14+
import { setDevice, setPageStatus } from '@/store/reducers/runtime';
1515
import { RestartToHomeTip, ListTips, EmptyTips } from './TouchResource/Tips';
1616
import ResourceButton from './TouchResource/Button';
1717

1818
import ConfirmDialog from '../Modal';
1919
import ReleaseInfo from './ReleaseInfo';
2020
import BootloaderTips from './BootloaderTips';
2121
import ProgressBar from './ProgressBar';
22-
import BridgeReleaseDialog from './BridgeReleaseDialog';
2322
import V3FirmwareConfirmUpdate from './V3FirmwareConfirmUpdate';
2423
import V3ReleaseInfo from './V3ReleaseInfo';
2524

@@ -28,12 +27,20 @@ let isPollingUpdateDevice = false;
2827

2928
const DeviceEventAlert: FC = () => {
3029
const intl = useIntl();
30+
const needsPermission = useSelector(
31+
(state: RootState) => state.runtime.needsBootloaderPermission
32+
);
3133
const showPinAlert = useSelector(
3234
(state: RootState) => state.firmware.showPinAlert
3335
);
3436
const showButtonAlert = useSelector(
3537
(state: RootState) => state.firmware.showButtonAlert
3638
);
39+
40+
if (needsPermission) {
41+
return null;
42+
}
43+
3744
return (
3845
<>
3946
{showPinAlert && (
@@ -95,6 +102,76 @@ const Description: FC<{ text: string; value: any }> = ({ text, value }) => (
95102
</div>
96103
);
97104

105+
const BootloaderStatusAlert: FC = () => {
106+
const intl = useIntl();
107+
const device = useSelector((state: RootState) => state.runtime.device);
108+
const isBootLoader = device?.features?.bootloader_mode;
109+
110+
if (!isBootLoader) {
111+
return null;
112+
}
113+
114+
// Bootloader mode - 提示用户当前处于可更新状态
115+
return (
116+
<div className="my-2">
117+
<Alert
118+
type="info"
119+
title={intl.formatMessage({ id: 'TR_DEVICE_IN_BOOTLOADER_MODE' })}
120+
content={intl.formatMessage({ id: 'TR_DEVICE_READY_FOR_UPDATE' })}
121+
/>
122+
</div>
123+
);
124+
};
125+
126+
const BootloaderPermissionPrompt: FC = () => {
127+
const intl = useIntl();
128+
const needsPermission = useSelector(
129+
(state: RootState) => state.runtime.needsBootloaderPermission
130+
);
131+
const [authorizing, setAuthorizing] = useState(false);
132+
133+
if (!needsPermission) {
134+
return null;
135+
}
136+
137+
const handleAuthorize = async () => {
138+
if (authorizing) {
139+
return;
140+
}
141+
setAuthorizing(true);
142+
try {
143+
const success = await serviceHardware.promptBootloaderDeviceAccess();
144+
if (!success) {
145+
console.warn('Bootloader 设备重新授权未完成,可提示用户再次尝试。');
146+
}
147+
} finally {
148+
setAuthorizing(false);
149+
}
150+
};
151+
152+
return (
153+
<div className="my-2">
154+
<Alert
155+
type="warning"
156+
title={intl.formatMessage({ id: 'TR_BOOTLOADER_PERMISSION_REQUIRED' })}
157+
content={intl.formatMessage({
158+
id: 'TR_BOOTLOADER_PERMISSION_REQUIRED_DESC',
159+
})}
160+
action={
161+
<Button
162+
type="primary"
163+
size="sm"
164+
onClick={handleAuthorize}
165+
loading={authorizing}
166+
>
167+
{intl.formatMessage({ id: 'TR_REAUTHORIZE_DEVICE' })}
168+
</Button>
169+
}
170+
/>
171+
</div>
172+
);
173+
};
174+
98175
const RebootToBoard: FC = () => {
99176
const intl = useIntl();
100177
const device = useSelector((state: RootState) => state.runtime.device);
@@ -128,23 +205,39 @@ const RebootToBoard: FC = () => {
128205
return null;
129206
};
130207

208+
const ReconnectDevice: FC = () => {
209+
const intl = useIntl();
210+
const dispatch = useDispatch();
211+
const device = useSelector((state: RootState) => state.runtime.device);
212+
213+
const handleReconnect = useCallback(() => {
214+
// Clear current device and return to search page
215+
dispatch(setDevice(null));
216+
dispatch(setPageStatus('searching'));
217+
}, [dispatch]);
218+
219+
// Show reconnect button when no device is connected
220+
if (!device) {
221+
return (
222+
<div className="flex items-center justify-center py-4">
223+
<Button type="primary" size="lg" onClick={handleReconnect}>
224+
{intl.formatMessage({ id: 'TR_RECONNECT_DEVICE' })}
225+
</Button>
226+
</div>
227+
);
228+
}
229+
230+
return null;
231+
};
232+
131233
const ConfirmUpdate: FC = () => {
132234
const intl = useIntl();
133235
const device = useSelector((state: RootState) => state.runtime.device);
134-
const releaseMap = useSelector(
135-
(state: RootState) => state.runtime.releaseMap
136-
);
137-
const selectedReleaseInfo = useSelector(
138-
(state: RootState) => state.runtime.selectedReleaseInfo
139-
);
140236
const selectedUploadType = useSelector(
141237
(state: RootState) => state.runtime.selectedUploadType
142238
);
143239
const tabType = useSelector((state: RootState) => state.runtime.currentTab);
144240
const [confirmProtocol, setConfirmProtocol] = useState(false);
145-
const [bridgeReleaseModalVisible, setBridgeReleaseModalVisible] =
146-
useState(false);
147-
const [bridgeReleaseVersion, setBridgeReleaseVersion] = useState('');
148241
const [isUpdating, setIsUpdating] = useState(false);
149242
const onHandleInstall = useCallback(async () => {
150243
if (isUpdating) return;
@@ -153,25 +246,6 @@ const ConfirmUpdate: FC = () => {
153246
}
154247
setIsUpdating(true);
155248
try {
156-
if (
157-
device?.deviceType &&
158-
(selectedUploadType === 'firmware' || selectedUploadType === 'ble')
159-
) {
160-
const firmwareField = selectedReleaseInfo?.firmwareField;
161-
if (firmwareField) {
162-
const version =
163-
releaseMap[device.deviceType]?.[firmwareField]?.[0]?.version;
164-
const checkBridgeRelease = await serviceHardware.checkBridgeRelease(
165-
version?.join('.') ?? ''
166-
);
167-
if (checkBridgeRelease?.shouldUpdate) {
168-
setBridgeReleaseVersion(checkBridgeRelease.releaseVersion);
169-
setBridgeReleaseModalVisible(true);
170-
return;
171-
}
172-
}
173-
}
174-
175249
if (tabType === 'bootloader') {
176250
await serviceHardware.bootloaderUpdate();
177251
} else {
@@ -182,14 +256,7 @@ const ConfirmUpdate: FC = () => {
182256
} finally {
183257
setIsUpdating(false);
184258
}
185-
}, [
186-
device,
187-
selectedUploadType,
188-
selectedReleaseInfo,
189-
releaseMap,
190-
tabType,
191-
isUpdating,
192-
]);
259+
}, [tabType, isUpdating]);
193260

194261
return (
195262
<div className="flex justify-center items-center flex-col">
@@ -226,11 +293,6 @@ const ConfirmUpdate: FC = () => {
226293
{intl.formatMessage({ id: 'TR_FIRMWARE_HEADING' })}
227294
</Button>
228295
</div>
229-
<BridgeReleaseDialog
230-
visible={bridgeReleaseModalVisible}
231-
setVisible={setBridgeReleaseModalVisible}
232-
version={bridgeReleaseVersion}
233-
/>
234296
</div>
235297
);
236298
};
@@ -355,8 +417,10 @@ export default function Firmware() {
355417
: 'TR_FIRMWARE_HEADING',
356418
})}
357419
</h1>
420+
<BootloaderPermissionPrompt />
358421
{!showFirmwareUpdate ? (
359422
<>
423+
<ReconnectDevice />
360424
<div className="flex flex-row-reverse">
361425
<div className="md:w-1/2 sm:w-full">
362426
<Description
@@ -400,6 +464,7 @@ export default function Firmware() {
400464
<RebootToBoard />
401465
</div>
402466
</div>
467+
<BootloaderStatusAlert />
403468
{['touch', 'pro'].includes(getDeviceType(device?.features)) && (
404469
<ConfirmDialog
405470
okCancel

src/components/Firmware/V3UploadLocalFirmware.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,7 @@ const V3UploadLocalFirmware: React.FC = () => {
131131
{intl.formatMessage({ id: 'TR_LOCAL_FIRMWARE_UPLOAD' }) ||
132132
'本地固件上传'}
133133
</h3>
134-
<p className="text-sm text-gray-500">
135-
{intl.formatMessage({ id: 'TR_LOCAL_FIRMWARE_DESCRIPTION' }) ||
136-
'选择本地固件文件进行更新。上传前请确保文件来源可靠。'}
137-
</p>
134+
138135

139136
<div className="mt-5 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-2">
140137
{getAllV3ComponentTypes().map((componentType) => {

0 commit comments

Comments
 (0)