@nordicsemiconductor/pc-nrfconnect-shared 122.0.0 → 124.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +58 -0
- package/coverage/cobertura-coverage.xml +1343 -978
- package/ipc/launcherConfig.ts +25 -0
- package/ipc/openWindow.ts +17 -1
- package/ipc/schema/packageJson.ts +26 -22
- package/main/index.ts +11 -5
- package/mocks/packageJsonMock.ts +1 -1
- package/nrfutil/device/batch.ts +1 -7
- package/nrfutil/device/common.ts +15 -8
- package/nrfutil/device/list.ts +1 -1
- package/nrfutil/moduleVersion.ts +2 -2
- package/nrfutil/sandbox.ts +52 -32
- package/nrfutil/sandboxTypes.ts +1 -1
- package/package.json +3 -2
- package/scripts/check-app-properties.ts +6 -6
- package/scripts/esbuild.ts +3 -3
- package/scripts/nordic-publish.js +23 -23
- package/scripts/nordic-publish.ts +3 -3
- package/scripts/release-shared.ts +2 -2
- package/src/About/ApplicationCard.tsx +3 -5
- package/src/App/App.test.tsx +7 -0
- package/src/App/App.tsx +14 -27
- package/src/Device/DeviceSelector/DeviceList/MoreDeviceInfo.tsx +1 -1
- package/src/Device/DeviceSelector/DeviceSelector.tsx +27 -9
- package/src/Device/deviceLister.ts +66 -23
- package/src/Device/deviceSetup.ts +4 -4
- package/src/Device/deviceSlice.ts +12 -3
- package/src/ErrorBoundary/ErrorBoundary.tsx +7 -13
- package/src/Feedback/sendFeedback.ts +2 -4
- package/src/Link/FileLink.tsx +4 -1
- package/src/index.ts +3 -0
- package/src/logging/sendInitialLogMessages.ts +2 -4
- package/src/utils/appDetails.ts +22 -0
- package/src/utils/appDirs.ts +4 -4
- package/src/utils/launcherConfig.ts +17 -0
- package/src/utils/packageJson.ts +52 -10
- package/src/utils/persistentStore.ts +21 -14
- package/src/utils/systemReport.ts +1 -3
- package/src/utils/usageData.ts +75 -167
- package/src/utils/usageDataCommon.ts +59 -0
- package/src/utils/usageDataMain.ts +117 -0
- package/src/utils/usageDataRenderer.ts +126 -0
- package/src/utils/useHotKey.ts +2 -2
- package/typings/generated/ipc/launcherConfig.d.ts +14 -0
- package/typings/generated/ipc/launcherConfig.d.ts.map +1 -0
- package/typings/generated/ipc/openWindow.d.ts +10 -4
- package/typings/generated/ipc/openWindow.d.ts.map +1 -1
- package/typings/generated/ipc/schema/packageJson.d.ts +34 -52
- package/typings/generated/ipc/schema/packageJson.d.ts.map +1 -1
- package/typings/generated/main/index.d.ts +8 -2
- package/typings/generated/main/index.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/batch.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/common.d.ts +1 -1
- package/typings/generated/nrfutil/device/common.d.ts.map +1 -1
- package/typings/generated/nrfutil/device/device.d.ts +2 -2
- package/typings/generated/nrfutil/device/list.d.ts +1 -1
- package/typings/generated/nrfutil/device/list.d.ts.map +1 -1
- package/typings/generated/nrfutil/sandbox.d.ts +2 -2
- package/typings/generated/nrfutil/sandbox.d.ts.map +1 -1
- package/typings/generated/nrfutil/sandboxTypes.d.ts +1 -1
- package/typings/generated/nrfutil/sandboxTypes.d.ts.map +1 -1
- package/typings/generated/src/About/ApplicationCard.d.ts.map +1 -1
- package/typings/generated/src/App/App.d.ts +0 -1
- package/typings/generated/src/App/App.d.ts.map +1 -1
- package/typings/generated/src/Device/DeviceSelector/DeviceSelector.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceLister.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSetup.d.ts +2 -2
- package/typings/generated/src/Device/deviceSetup.d.ts.map +1 -1
- package/typings/generated/src/Device/deviceSlice.d.ts +5 -1
- package/typings/generated/src/Device/deviceSlice.d.ts.map +1 -1
- package/typings/generated/src/ErrorBoundary/ErrorBoundary.d.ts.map +1 -1
- package/typings/generated/src/Feedback/sendFeedback.d.ts.map +1 -1
- package/typings/generated/src/Link/FileLink.d.ts +2 -1
- package/typings/generated/src/Link/FileLink.d.ts.map +1 -1
- package/typings/generated/src/index.d.ts +2 -0
- package/typings/generated/src/index.d.ts.map +1 -1
- package/typings/generated/src/logging/sendInitialLogMessages.d.ts.map +1 -1
- package/typings/generated/src/utils/appDetails.d.ts +4 -0
- package/typings/generated/src/utils/appDetails.d.ts.map +1 -0
- package/typings/generated/src/utils/appDirs.d.ts +1 -1
- package/typings/generated/src/utils/appDirs.d.ts.map +1 -1
- package/typings/generated/src/utils/launcherConfig.d.ts +4 -0
- package/typings/generated/src/utils/launcherConfig.d.ts.map +1 -0
- package/typings/generated/src/utils/packageJson.d.ts +30 -7
- package/typings/generated/src/utils/packageJson.d.ts.map +1 -1
- package/typings/generated/src/utils/persistentStore.d.ts +3 -2
- package/typings/generated/src/utils/persistentStore.d.ts.map +1 -1
- package/typings/generated/src/utils/systemReport.d.ts.map +1 -1
- package/typings/generated/src/utils/usageData.d.ts +8 -65
- package/typings/generated/src/utils/usageData.d.ts.map +1 -1
- package/typings/generated/src/utils/usageDataCommon.d.ts +27 -0
- package/typings/generated/src/utils/usageDataCommon.d.ts.map +1 -0
- package/typings/generated/src/utils/usageDataMain.d.ts +10 -0
- package/typings/generated/src/utils/usageDataMain.d.ts.map +1 -0
- package/typings/generated/src/utils/usageDataRenderer.d.ts +10 -0
- package/typings/generated/src/utils/usageDataRenderer.d.ts.map +1 -0
|
@@ -14,7 +14,7 @@ import semver from 'semver';
|
|
|
14
14
|
import calculateShasum from 'shasum';
|
|
15
15
|
|
|
16
16
|
import { AppInfo, SourceJson } from '../ipc/MetaFiles';
|
|
17
|
-
import {
|
|
17
|
+
import { PackageJsonApp } from '../ipc/schema/packageJson';
|
|
18
18
|
import checkAppProperties from './check-app-properties';
|
|
19
19
|
|
|
20
20
|
interface LegacyAppInfo {
|
|
@@ -41,7 +41,7 @@ interface App {
|
|
|
41
41
|
releaseNotesFilename: string;
|
|
42
42
|
iconFilename: string;
|
|
43
43
|
isOfficial: boolean;
|
|
44
|
-
packageJson:
|
|
44
|
+
packageJson: PackageJsonApp;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const client = new FtpClient();
|
|
@@ -113,7 +113,7 @@ const parseOptions = (): Options => {
|
|
|
113
113
|
};
|
|
114
114
|
};
|
|
115
115
|
|
|
116
|
-
const readPackageJson = ():
|
|
116
|
+
const readPackageJson = (): PackageJsonApp =>
|
|
117
117
|
JSON.parse(fs.readFileSync('./package.json', 'utf-8'));
|
|
118
118
|
|
|
119
119
|
const packPackage = () => {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { execSync, spawnSync } from 'node:child_process';
|
|
27
27
|
|
|
28
|
-
import {
|
|
28
|
+
import { PackageJsonApp } from '../ipc/schema/packageJson';
|
|
29
29
|
|
|
30
30
|
const logError = (message: string) => {
|
|
31
31
|
console.error(message);
|
|
@@ -88,7 +88,7 @@ export const packageJsonIsCorrect = (
|
|
|
88
88
|
}
|
|
89
89
|
) => {
|
|
90
90
|
const expectedVersionString = `${expectedVersionNumber}.0.0`;
|
|
91
|
-
const actualVersionString = parseJson<
|
|
91
|
+
const actualVersionString = parseJson<PackageJsonApp>(packageJson).version;
|
|
92
92
|
|
|
93
93
|
return equality(
|
|
94
94
|
expectedVersionString,
|
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useEffect, useState } from 'react';
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
AppDetailsFromLauncher,
|
|
11
|
-
inMain as appDetails,
|
|
12
|
-
} from '../../ipc/appDetails';
|
|
9
|
+
import { AppDetailsFromLauncher } from '../../ipc/appDetails';
|
|
13
10
|
import Card from '../Card/Card';
|
|
14
11
|
import FactoryResetButton from '../FactoryReset/FactoryResetButton';
|
|
12
|
+
import appDetails from '../utils/appDetails';
|
|
15
13
|
import AboutButton from './AboutButton';
|
|
16
14
|
import Section from './Section';
|
|
17
15
|
import ShortcutButton from './ShortcutButton';
|
|
@@ -20,7 +18,7 @@ export default () => {
|
|
|
20
18
|
const [appInfo, setAppInfo] = useState<AppDetailsFromLauncher>();
|
|
21
19
|
|
|
22
20
|
useEffect(() => {
|
|
23
|
-
appDetails
|
|
21
|
+
appDetails().then(setAppInfo);
|
|
24
22
|
}, [setAppInfo]);
|
|
25
23
|
|
|
26
24
|
if (appInfo == null) return null;
|
package/src/App/App.test.tsx
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import { screen } from '@testing-library/react';
|
|
9
9
|
|
|
10
|
+
import packageJsonFromShared from '../../package.json';
|
|
10
11
|
import render from '../../test/testrenderer';
|
|
11
12
|
import App, { Pane } from './App';
|
|
12
13
|
|
|
@@ -17,6 +18,12 @@ jest.mock('../Log/LogViewer', () => ({
|
|
|
17
18
|
|
|
18
19
|
jest.mock('../logging/index.ts', () => ({
|
|
19
20
|
initialise: () => {},
|
|
21
|
+
debug: () => {},
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
jest.mock('../utils/packageJson', () => ({
|
|
25
|
+
isLauncher: () => false,
|
|
26
|
+
packageJson: () => packageJsonFromShared,
|
|
20
27
|
}));
|
|
21
28
|
|
|
22
29
|
const renderApp = (panes: Pane[]) => {
|
package/src/App/App.tsx
CHANGED
|
@@ -30,9 +30,8 @@ import LogViewer from '../Log/LogViewer';
|
|
|
30
30
|
import logger from '../logging';
|
|
31
31
|
import NavBar from '../NavBar/NavBar';
|
|
32
32
|
import classNames from '../utils/classNames';
|
|
33
|
-
import packageJson from '../utils/packageJson';
|
|
34
33
|
import { getPersistedCurrentPane } from '../utils/persistentStore';
|
|
35
|
-
import
|
|
34
|
+
import usageData from '../utils/usageData';
|
|
36
35
|
import useHotKey from '../utils/useHotKey';
|
|
37
36
|
import {
|
|
38
37
|
currentPane as currentPaneSelector,
|
|
@@ -49,19 +48,6 @@ import './app.scss';
|
|
|
49
48
|
import './shared.scss';
|
|
50
49
|
import './tailwind.css';
|
|
51
50
|
|
|
52
|
-
let usageDataAlreadyInitialised = false;
|
|
53
|
-
const initialiseUsageData = () => {
|
|
54
|
-
if (!usageDataAlreadyInitialised) {
|
|
55
|
-
usageDataAlreadyInitialised = true;
|
|
56
|
-
try {
|
|
57
|
-
usageDataInit(packageJson());
|
|
58
|
-
} catch (error) {
|
|
59
|
-
// No need to display the error message for the user
|
|
60
|
-
console.log(error);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
51
|
export interface PaneProps {
|
|
66
52
|
active: boolean;
|
|
67
53
|
}
|
|
@@ -77,7 +63,6 @@ interface ConnectedAppProps {
|
|
|
77
63
|
panes: Pane[];
|
|
78
64
|
sidePanel?: ReactNode;
|
|
79
65
|
showLogByDefault?: boolean;
|
|
80
|
-
reportUsageData?: boolean;
|
|
81
66
|
documentation?: ReactNode[];
|
|
82
67
|
feedback?: boolean | FeedbackPaneProps;
|
|
83
68
|
children?: ReactNode;
|
|
@@ -89,25 +74,25 @@ const ConnectedApp: FC<ConnectedAppProps> = ({
|
|
|
89
74
|
panes,
|
|
90
75
|
sidePanel,
|
|
91
76
|
showLogByDefault = true,
|
|
92
|
-
reportUsageData = false,
|
|
93
77
|
documentation,
|
|
94
78
|
feedback,
|
|
95
79
|
children,
|
|
96
80
|
autoReselectByDefault = false,
|
|
97
81
|
}) => {
|
|
98
|
-
const
|
|
82
|
+
const initApp = useRef(false);
|
|
99
83
|
|
|
100
|
-
if (!
|
|
84
|
+
if (!initApp.current) {
|
|
101
85
|
logger.initialise();
|
|
102
86
|
setNrfutilLogger(logger);
|
|
103
|
-
|
|
104
|
-
|
|
87
|
+
usageData.setLogger(logger);
|
|
88
|
+
initApp.current = true;
|
|
105
89
|
}
|
|
106
90
|
|
|
107
91
|
usePersistedPane();
|
|
108
92
|
const isLogVisible = useSelector(isLogVisibleSelector);
|
|
109
93
|
const currentPane = useSelector(currentPaneSelector);
|
|
110
94
|
const allPanes = useAllPanes(panes, documentation, feedback);
|
|
95
|
+
const paneName = useRef(allPanes.map(({ name }) => name));
|
|
111
96
|
const dispatch = useDispatch();
|
|
112
97
|
|
|
113
98
|
useHotKey({
|
|
@@ -117,6 +102,14 @@ const ConnectedApp: FC<ConnectedAppProps> = ({
|
|
|
117
102
|
action: openWindow.openLauncher,
|
|
118
103
|
});
|
|
119
104
|
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
paneName.current = allPanes.map(({ name }) => name);
|
|
107
|
+
}, [allPanes]);
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
usageData.sendPageView(paneName.current[currentPane]);
|
|
111
|
+
}, [currentPane]);
|
|
112
|
+
|
|
120
113
|
useEffect(() => {
|
|
121
114
|
dispatch(setAutoReselect(autoReselectByDefault));
|
|
122
115
|
}, [dispatch, autoReselectByDefault]);
|
|
@@ -134,12 +127,6 @@ const ConnectedApp: FC<ConnectedAppProps> = ({
|
|
|
134
127
|
const isSidePanelVisible =
|
|
135
128
|
useSelector(isSidePanelVisibleSelector) && currentSidePanel;
|
|
136
129
|
|
|
137
|
-
useEffect(() => {
|
|
138
|
-
if (reportUsageData) {
|
|
139
|
-
initialiseUsageData();
|
|
140
|
-
}
|
|
141
|
-
}, [reportUsageData]);
|
|
142
|
-
|
|
143
130
|
return (
|
|
144
131
|
<div className="core19-app">
|
|
145
132
|
<NavBar deviceSelect={deviceSelect} />
|
|
@@ -44,7 +44,7 @@ const MaybeDeviceName = ({ device }: { device: Device }) => {
|
|
|
44
44
|
const Serialports = ({ ports }: { ports: SerialPort[] }) =>
|
|
45
45
|
ports.length > 0 ? (
|
|
46
46
|
<Row>
|
|
47
|
-
<ul className="tw-
|
|
47
|
+
<ul className="tw-underline">
|
|
48
48
|
{ports.map(port => (
|
|
49
49
|
<li key={port.path}>{port.comName}</li>
|
|
50
50
|
))}
|
|
@@ -10,6 +10,8 @@ import { useDispatch, useSelector } from 'react-redux';
|
|
|
10
10
|
import { NrfutilDeviceLib } from '../../../nrfutil';
|
|
11
11
|
import { DeviceTraits } from '../../../nrfutil/device/common';
|
|
12
12
|
import logger from '../../logging';
|
|
13
|
+
import usageData from '../../utils/usageData';
|
|
14
|
+
import { simplifyDeviceForLogging } from '../../utils/usageDataCommon';
|
|
13
15
|
import useHotKey from '../../utils/useHotKey';
|
|
14
16
|
import {
|
|
15
17
|
clearWaitForDevice,
|
|
@@ -23,6 +25,7 @@ import {
|
|
|
23
25
|
deselectDevice,
|
|
24
26
|
Device,
|
|
25
27
|
deviceIsSelected as deviceIsSelectedSelector,
|
|
28
|
+
isDeviceWithSerialNumber,
|
|
26
29
|
selectDevice,
|
|
27
30
|
selectedDevice,
|
|
28
31
|
setSelectedDeviceInfo,
|
|
@@ -61,12 +64,22 @@ export default ({
|
|
|
61
64
|
const waitingToAutoReconnect = useSelector(getWaitingToAutoReselect);
|
|
62
65
|
const showSelectedDevice = deviceIsSelected || waitingToAutoReconnect;
|
|
63
66
|
|
|
64
|
-
const doDeselectDevice = useCallback(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const doDeselectDevice = useCallback(
|
|
68
|
+
(device?: Device) => {
|
|
69
|
+
if (device) {
|
|
70
|
+
usageData.sendUsageData(
|
|
71
|
+
'device deselected ',
|
|
72
|
+
simplifyDeviceForLogging(device)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
dispatch(clearWaitForDevice());
|
|
77
|
+
dispatch(setAutoSelectDevice(undefined));
|
|
78
|
+
onDeviceDeselected();
|
|
79
|
+
dispatch(deselectDevice());
|
|
80
|
+
},
|
|
81
|
+
[dispatch, onDeviceDeselected]
|
|
82
|
+
);
|
|
70
83
|
|
|
71
84
|
const abortController = useRef<AbortController>();
|
|
72
85
|
|
|
@@ -92,8 +105,13 @@ export default ({
|
|
|
92
105
|
abortController.current = undefined;
|
|
93
106
|
setSelectedDeviceInfo(deviceInfo);
|
|
94
107
|
|
|
108
|
+
usageData.sendUsageData('device selected', {
|
|
109
|
+
device: simplifyDeviceForLogging(device),
|
|
110
|
+
deviceInfo,
|
|
111
|
+
});
|
|
112
|
+
|
|
95
113
|
if (deviceSetupConfig) {
|
|
96
|
-
if (device
|
|
114
|
+
if (isDeviceWithSerialNumber(device)) {
|
|
97
115
|
dispatch(
|
|
98
116
|
setupDevice(
|
|
99
117
|
device,
|
|
@@ -158,7 +176,7 @@ export default ({
|
|
|
158
176
|
<div className="core19-device-selector">
|
|
159
177
|
{showSelectedDevice ? (
|
|
160
178
|
<SelectedDevice
|
|
161
|
-
doDeselectDevice={doDeselectDevice}
|
|
179
|
+
doDeselectDevice={() => doDeselectDevice(currentDevice)}
|
|
162
180
|
toggleDeviceListVisible={toggleDeviceListVisible}
|
|
163
181
|
/>
|
|
164
182
|
) : (
|
|
@@ -176,7 +194,7 @@ export default ({
|
|
|
176
194
|
}
|
|
177
195
|
|
|
178
196
|
if (deviceIsSelected) {
|
|
179
|
-
doDeselectDevice();
|
|
197
|
+
doDeselectDevice(currentDevice);
|
|
180
198
|
}
|
|
181
199
|
|
|
182
200
|
doSelectDevice(device, autoReselected);
|
|
@@ -8,6 +8,8 @@ import { DeviceTraits, NrfutilDevice } from '../../nrfutil/device/common';
|
|
|
8
8
|
import NrfutilDeviceLib from '../../nrfutil/device/device';
|
|
9
9
|
import logger from '../logging';
|
|
10
10
|
import type { AppThunk, RootState } from '../store';
|
|
11
|
+
import usageData from '../utils/usageData';
|
|
12
|
+
import { simplifyDeviceForLogging } from '../utils/usageDataCommon';
|
|
11
13
|
import {
|
|
12
14
|
clearWaitForDevice,
|
|
13
15
|
clearWaitForDeviceTimeout,
|
|
@@ -22,7 +24,6 @@ import { closeDeviceSetupDialog } from './deviceSetupSlice';
|
|
|
22
24
|
import {
|
|
23
25
|
addDevice,
|
|
24
26
|
Device,
|
|
25
|
-
getDevice,
|
|
26
27
|
removeDevice,
|
|
27
28
|
selectDevice,
|
|
28
29
|
setSelectedDeviceInfo,
|
|
@@ -164,10 +165,16 @@ export const startWatchingDevices =
|
|
|
164
165
|
(dispatch, getState) => {
|
|
165
166
|
const onDeviceArrived = async (device: NrfutilDevice) => {
|
|
166
167
|
if (hasValidDeviceTraits(device.traits, deviceListing)) {
|
|
168
|
+
usageData.sendUsageData(
|
|
169
|
+
'device connected',
|
|
170
|
+
simplifyDeviceForLogging(device)
|
|
171
|
+
);
|
|
167
172
|
if (
|
|
168
|
-
device.serialNumber &&
|
|
169
173
|
!getState().device.devices.find(
|
|
170
|
-
d =>
|
|
174
|
+
d =>
|
|
175
|
+
d.id === device.id ||
|
|
176
|
+
(device.serialNumber && // we want to disregard comparing devices with no sn
|
|
177
|
+
d.serialNumber === device.serialNumber)
|
|
171
178
|
)
|
|
172
179
|
) {
|
|
173
180
|
onDeviceConnected(device);
|
|
@@ -294,7 +301,7 @@ export const startWatchingDevices =
|
|
|
294
301
|
const waitForDevice =
|
|
295
302
|
getState().deviceAutoSelect.waitForDevice;
|
|
296
303
|
if (
|
|
297
|
-
device.serialNumber &&
|
|
304
|
+
device.serialNumber && // we want to disregard comparing devices with no sn
|
|
298
305
|
device.serialNumber ===
|
|
299
306
|
getState().deviceAutoSelect.device?.serialNumber
|
|
300
307
|
) {
|
|
@@ -341,7 +348,10 @@ export const startWatchingDevices =
|
|
|
341
348
|
stopWatchingDevices(async () => {
|
|
342
349
|
const operation = await NrfutilDeviceLib.list(
|
|
343
350
|
deviceListing,
|
|
344
|
-
d =>
|
|
351
|
+
d => {
|
|
352
|
+
d.forEach(onDeviceArrived);
|
|
353
|
+
dispatch(autoSelectDeviceCLI(doSelectDevice));
|
|
354
|
+
},
|
|
345
355
|
error => {
|
|
346
356
|
logger.error(error);
|
|
347
357
|
},
|
|
@@ -353,30 +363,63 @@ export const startWatchingDevices =
|
|
|
353
363
|
callback?.();
|
|
354
364
|
});
|
|
355
365
|
};
|
|
356
|
-
|
|
357
|
-
if (!autoSelectDeviceCLISerialUsed) {
|
|
358
|
-
const autoSelectSN = getAutoSelectDeviceCLISerial();
|
|
359
|
-
|
|
360
|
-
if (autoSelectSN !== undefined) {
|
|
361
|
-
const autoSelectDevice = getDevice(
|
|
362
|
-
getState(),
|
|
363
|
-
autoSelectSN
|
|
364
|
-
);
|
|
365
|
-
|
|
366
|
-
if (autoSelectDevice)
|
|
367
|
-
doSelectDevice(autoSelectDevice, true);
|
|
368
|
-
}
|
|
369
|
-
autoSelectDeviceCLISerialUsed = true;
|
|
370
|
-
}
|
|
371
366
|
});
|
|
372
367
|
};
|
|
373
368
|
|
|
374
|
-
const
|
|
369
|
+
const getAutoSelectDeviceCLIProperty = (
|
|
370
|
+
property: string,
|
|
371
|
+
findDevice: (value: string) => Device | undefined
|
|
372
|
+
) => {
|
|
375
373
|
const { argv } = process;
|
|
376
|
-
const
|
|
377
|
-
return
|
|
374
|
+
const index = argv.findIndex(arg => arg === property);
|
|
375
|
+
return index > -1
|
|
376
|
+
? { index, device: findDevice(argv[index + 1]) }
|
|
377
|
+
: undefined;
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const getAutoSelectDevice = (devices: Device[]) => {
|
|
381
|
+
const serialNumber = getAutoSelectDeviceCLIProperty('--deviceSerial', sn =>
|
|
382
|
+
devices.find(device => device.serialNumber === sn)
|
|
383
|
+
);
|
|
384
|
+
const serialPort = getAutoSelectDeviceCLIProperty('--comPort', portPath =>
|
|
385
|
+
devices.find(device =>
|
|
386
|
+
device.serialPorts?.find(port => port.comName === portPath)
|
|
387
|
+
)
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
if (serialNumber && serialPort) {
|
|
391
|
+
if (serialNumber.index > serialPort.index) {
|
|
392
|
+
return serialPort.device;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return serialNumber.device;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (serialNumber) {
|
|
399
|
+
return serialNumber.device;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (serialPort) {
|
|
403
|
+
return serialPort.device;
|
|
404
|
+
}
|
|
378
405
|
};
|
|
379
406
|
|
|
407
|
+
const autoSelectDeviceCLI =
|
|
408
|
+
(
|
|
409
|
+
doSelectDevice: (device: Device, autoReselected: boolean) => void
|
|
410
|
+
): AppThunk<RootState> =>
|
|
411
|
+
(_, getState) => {
|
|
412
|
+
if (!autoSelectDeviceCLISerialUsed) {
|
|
413
|
+
const autoSelectDevice = getAutoSelectDevice(
|
|
414
|
+
getState().device.devices
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
if (autoSelectDevice) doSelectDevice(autoSelectDevice, true);
|
|
418
|
+
|
|
419
|
+
autoSelectDeviceCLISerialUsed = true;
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
|
|
380
423
|
export const stopWatchingDevices = (callback?: () => void) => {
|
|
381
424
|
if (stopNrfutilDevice) stopNrfutilDevice(callback);
|
|
382
425
|
else callback?.();
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
setDeviceSetupProgress,
|
|
14
14
|
setDeviceSetupProgressMessage,
|
|
15
15
|
} from './deviceSetupSlice';
|
|
16
|
-
import { Device } from './deviceSlice';
|
|
16
|
+
import { Device, DeviceWithSerialNumber } from './deviceSlice';
|
|
17
17
|
import { InitPacket } from './initPacket';
|
|
18
18
|
|
|
19
19
|
export interface DfuEntry {
|
|
@@ -239,10 +239,10 @@ export const prepareDevice =
|
|
|
239
239
|
|
|
240
240
|
export const setupDevice =
|
|
241
241
|
(
|
|
242
|
-
device:
|
|
242
|
+
device: DeviceWithSerialNumber,
|
|
243
243
|
deviceSetupConfig: DeviceSetupConfig,
|
|
244
244
|
onDeviceIsReady: (device: Device) => void,
|
|
245
|
-
doDeselectDevice: () => void,
|
|
245
|
+
doDeselectDevice: (device?: Device) => void,
|
|
246
246
|
deviceInfo: DeviceInfo | undefined
|
|
247
247
|
): AppThunk<RootState> =>
|
|
248
248
|
(dispatch, getState) =>
|
|
@@ -270,7 +270,7 @@ export const setupDevice =
|
|
|
270
270
|
`Error while setting up device ${device.serialNumber}`
|
|
271
271
|
);
|
|
272
272
|
logger.error(describeError(error));
|
|
273
|
-
doDeselectDevice();
|
|
273
|
+
doDeselectDevice(getState().device.selectedDevice);
|
|
274
274
|
},
|
|
275
275
|
deviceInfo
|
|
276
276
|
)
|
|
@@ -26,10 +26,19 @@ export interface Device extends NrfutilDevice {
|
|
|
26
26
|
persistedSerialPortOptions?: SerialPortOpenOptions<AutoDetectTypes>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export interface DeviceWithSerialNumber extends Device {
|
|
30
|
+
serialNumber: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const isDeviceWithSerialNumber = (
|
|
34
|
+
device: Device
|
|
35
|
+
): device is DeviceWithSerialNumber =>
|
|
36
|
+
!!(device as DeviceWithSerialNumber).serialNumber;
|
|
37
|
+
|
|
29
38
|
const findDeviceItem = (
|
|
30
39
|
devices: Device[],
|
|
31
40
|
id: number,
|
|
32
|
-
serialNumber?: string
|
|
41
|
+
serialNumber?: string | null
|
|
33
42
|
) => {
|
|
34
43
|
const index = devices.findIndex(
|
|
35
44
|
d => d.id === id || d.serialNumber === serialNumber
|
|
@@ -42,7 +51,7 @@ const updateDevice = (
|
|
|
42
51
|
state: DeviceState,
|
|
43
52
|
updateToMergeIn: Partial<Device>,
|
|
44
53
|
id: number,
|
|
45
|
-
serialNumber?: string
|
|
54
|
+
serialNumber?: string | null
|
|
46
55
|
) => {
|
|
47
56
|
const device = findDeviceItem(state.devices, id, serialNumber).device;
|
|
48
57
|
if (device) {
|
|
@@ -147,7 +156,7 @@ const slice = createSlice({
|
|
|
147
156
|
);
|
|
148
157
|
|
|
149
158
|
if (
|
|
150
|
-
selectedDevice.serialNumber &&
|
|
159
|
+
selectedDevice.serialNumber && // we want to disregard comparing devices with no sn
|
|
151
160
|
vComIndex !== undefined &&
|
|
152
161
|
vComIndex !== -1
|
|
153
162
|
) {
|
|
@@ -13,27 +13,20 @@ import FactoryResetButton from '../FactoryReset/FactoryResetButton';
|
|
|
13
13
|
import { CollapsibleGroup } from '../SidePanel/Group';
|
|
14
14
|
import Spinner from '../Spinner/Spinner';
|
|
15
15
|
import { openUrl } from '../utils/open';
|
|
16
|
-
import packageJson from '../utils/packageJson';
|
|
16
|
+
import { packageJson } from '../utils/packageJson';
|
|
17
17
|
import { getAppSpecificStore as store } from '../utils/persistentStore';
|
|
18
18
|
import { generateSystemReport } from '../utils/systemReport';
|
|
19
|
-
import
|
|
20
|
-
init as initGA,
|
|
21
|
-
isEnabled,
|
|
22
|
-
isInitialized as isGAInitialized,
|
|
23
|
-
sendErrorReport,
|
|
24
|
-
} from '../utils/usageData';
|
|
19
|
+
import usageData from '../utils/usageData';
|
|
25
20
|
import bugIcon from './bug.svg';
|
|
26
21
|
|
|
27
22
|
import './error-boundary.scss';
|
|
28
23
|
|
|
29
24
|
const sendGAEvent = (error: string) => {
|
|
30
|
-
if (!isEnabled()) {
|
|
25
|
+
if (!usageData.isEnabled()) {
|
|
31
26
|
return;
|
|
32
27
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
sendErrorReport(error);
|
|
28
|
+
|
|
29
|
+
usageData.sendErrorReport(error);
|
|
37
30
|
};
|
|
38
31
|
|
|
39
32
|
interface Props {
|
|
@@ -97,7 +90,8 @@ class ErrorBoundary extends React.Component<
|
|
|
97
90
|
return children;
|
|
98
91
|
}
|
|
99
92
|
|
|
100
|
-
const appDisplayName =
|
|
93
|
+
const appDisplayName =
|
|
94
|
+
appName || packageJson().displayName || packageJson().name;
|
|
101
95
|
|
|
102
96
|
return (
|
|
103
97
|
<div className="error-boundary__container">
|
|
@@ -5,18 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { isDevelopment } from '../utils/environment';
|
|
8
|
-
import packageJson from '../utils/packageJson';
|
|
8
|
+
import { packageJson } from '../utils/packageJson';
|
|
9
9
|
|
|
10
10
|
const formURL =
|
|
11
11
|
isDevelopment === true
|
|
12
12
|
? 'https://formkeep.com/f/87deb409a565'
|
|
13
13
|
: 'https://formkeep.com/f/36b394b92851';
|
|
14
14
|
|
|
15
|
-
const getAppName = () => packageJson().name;
|
|
16
|
-
|
|
17
15
|
export default async (feedback: string, category?: string) => {
|
|
18
16
|
const data: Record<string, unknown> = {
|
|
19
|
-
name:
|
|
17
|
+
name: packageJson().name,
|
|
20
18
|
feedback,
|
|
21
19
|
platform: process.platform,
|
|
22
20
|
};
|
package/src/Link/FileLink.tsx
CHANGED
|
@@ -12,15 +12,18 @@ import { openFile } from '../utils/open';
|
|
|
12
12
|
export default ({
|
|
13
13
|
label,
|
|
14
14
|
fileLocation,
|
|
15
|
+
className,
|
|
15
16
|
}: {
|
|
16
17
|
label: string;
|
|
17
18
|
fileLocation: string;
|
|
19
|
+
className: string;
|
|
18
20
|
}) => (
|
|
19
21
|
<button
|
|
20
22
|
type="button"
|
|
21
23
|
onClick={() => openFile(fileLocation)}
|
|
22
24
|
className={classNames(
|
|
23
|
-
'tw-preflight tw-text-nordicBlue hover:tw-underline'
|
|
25
|
+
'tw-preflight tw-overflow-hidden tw-text-ellipsis tw-text-nordicBlue hover:tw-underline',
|
|
26
|
+
className
|
|
24
27
|
)}
|
|
25
28
|
>
|
|
26
29
|
{label}
|
package/src/index.ts
CHANGED
|
@@ -77,6 +77,7 @@ export { openUrl } from './utils/open';
|
|
|
77
77
|
export { default as systemReport } from './utils/systemReport';
|
|
78
78
|
|
|
79
79
|
export { default as usageData } from './utils/usageData';
|
|
80
|
+
export { type Metadata as UsageDataMetadata } from './utils/usageDataCommon';
|
|
80
81
|
export { default as classNames } from './utils/classNames';
|
|
81
82
|
export { truncateMiddle } from './utils/truncateMiddle';
|
|
82
83
|
|
|
@@ -97,6 +98,8 @@ export {
|
|
|
97
98
|
persistApiKey,
|
|
98
99
|
} from './utils/persistentStore';
|
|
99
100
|
|
|
101
|
+
export { default as launcherConfig } from './utils/launcherConfig';
|
|
102
|
+
|
|
100
103
|
export { jprogDeviceSetup } from './Device/jprogOperations';
|
|
101
104
|
|
|
102
105
|
export { sdfuDeviceSetup } from './Device/sdfuOperations';
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { inMain as appDetails } from '../../ipc/appDetails';
|
|
8
7
|
import NrfutilDeviceLib from '../../nrfutil/device/device';
|
|
9
8
|
import {
|
|
10
9
|
getExpectedVersion,
|
|
11
10
|
resolveModuleVersion,
|
|
12
11
|
} from '../../nrfutil/moduleVersion';
|
|
12
|
+
import appDetails from '../utils/appDetails';
|
|
13
13
|
import { getAppDataDir } from '../utils/appDirs';
|
|
14
14
|
import logLibVersions from '../utils/logLibVersions';
|
|
15
15
|
import udevInstalled from '../utils/udevInstalled';
|
|
@@ -23,8 +23,6 @@ export default async () => {
|
|
|
23
23
|
logLibVersions();
|
|
24
24
|
logger.debug(`Application data folder: ${getAppDataDir()}`);
|
|
25
25
|
|
|
26
|
-
const details = await appDetails.getAppDetails();
|
|
27
|
-
|
|
28
26
|
const {
|
|
29
27
|
name,
|
|
30
28
|
currentVersion,
|
|
@@ -35,7 +33,7 @@ export default async () => {
|
|
|
35
33
|
homeDir,
|
|
36
34
|
tmpDir,
|
|
37
35
|
source,
|
|
38
|
-
} =
|
|
36
|
+
} = await appDetails();
|
|
39
37
|
|
|
40
38
|
logger.debug(`App ${name} v${currentVersion} (${source})`);
|
|
41
39
|
logger.debug(`App path: ${installed.path}`);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
3
|
+
*
|
|
4
|
+
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { type AppDetailsFromLauncher, inMain } from '../../ipc/appDetails';
|
|
8
|
+
import { isLauncher } from './packageJson';
|
|
9
|
+
|
|
10
|
+
let cached: AppDetailsFromLauncher;
|
|
11
|
+
|
|
12
|
+
export default async () => {
|
|
13
|
+
if (isLauncher()) {
|
|
14
|
+
throw new Error('Must not be called by the launcher.');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (cached == null) {
|
|
18
|
+
cached = await inMain.getAppDetails();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return cached;
|
|
22
|
+
};
|
package/src/utils/appDirs.ts
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { getGlobal } from '@electron/remote';
|
|
8
7
|
import path from 'path';
|
|
9
8
|
|
|
10
|
-
import
|
|
9
|
+
import launcherConfig from './launcherConfig';
|
|
10
|
+
import { packageJsonApp } from './packageJson';
|
|
11
11
|
|
|
12
|
-
const getUserDataDir = () =>
|
|
12
|
+
const getUserDataDir = () => launcherConfig().userDataDir;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Get the filesystem path of the currently loaded app.
|
|
@@ -17,7 +17,7 @@ const getUserDataDir = () => getGlobal('userDataDir');
|
|
|
17
17
|
* @returns {string|undefined} Absolute path of current app.
|
|
18
18
|
*/
|
|
19
19
|
const getAppDir = () => {
|
|
20
|
-
const html =
|
|
20
|
+
const html = packageJsonApp().nrfConnectForDesktop.html;
|
|
21
21
|
const dir = path.parse(html).dir;
|
|
22
22
|
return path.parse(__filename).dir.replace(dir, '');
|
|
23
23
|
};
|