Skip to content

Commit ed55a96

Browse files
committed
more alova ports
1 parent 2ae45ec commit ed55a96

31 files changed

+827
-890
lines changed

interface/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"@typescript-eslint/eslint-plugin": "^5.59.11",
5151
"@typescript-eslint/parser": "^5.59.11",
5252
"@vitejs/plugin-react-swc": "^3.3.2",
53-
"eslint": "^8.42.0",
53+
"eslint": "^8.43.0",
5454
"eslint-config-airbnb": "^19.0.4",
5555
"eslint-config-airbnb-typescript": "^17.0.0",
5656
"eslint-config-prettier": "^8.8.0",

interface/src/AuthenticatedRouting.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const AuthenticatedRouting: FC = () => {
3333
);
3434

3535
useEffect(() => {
36-
// TODO how to replace AXIOS.interceptors.response.use ???
36+
// TODO replace AXIOS.interceptors.response.use ???
3737
const axiosHandlerId = AXIOS.interceptors.response.use((response) => response, handleApiResponseError);
3838
return () => AXIOS.interceptors.response.eject(axiosHandlerId);
3939
}, [handleApiResponseError]);

interface/src/SignIn.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const SignIn: FC = () => {
4242

4343
const signIn = async () => {
4444
try {
45+
// TODO move to Alova
4546
const { data: loginResponse } = await AuthenticationApi.signIn(signInRequest);
4647
authenticationContext.signIn(loginResponse.access_token);
4748
} catch (error) {

interface/src/api/authentication.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import type { Me, SignInRequest, SignInResponse } from 'types';
99
export const SIGN_IN_PATHNAME = 'loginPathname';
1010
export const SIGN_IN_SEARCH = 'loginSearch';
1111

12-
// TODO move to Alova
12+
// TODO move verifyAuthorization to Alova
1313
export function verifyAuthorization(): AxiosPromise<void> {
1414
return AXIOS.get('/verifyAuthorization');
1515
}
16+
// TODO move signIn to Alova
1617
export function signIn(request: SignInRequest): AxiosPromise<SignInResponse> {
1718
return AXIOS.post('/signIn', request);
1819
}

interface/src/api/endpoints.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const EVENT_SOURCE_ROOT = 'http://' + host + '/es/';
1717

1818
export const alovaInstance = createAlova({
1919
statesHook: ReactHook,
20-
timeout: 3000,
20+
// timeout: 3000,
2121
localCache: {
2222
GET: {
2323
mode: 'placeholder',
@@ -35,7 +35,9 @@ export const alovaInstance = createAlova({
3535

3636
responded: {
3737
onSuccess: async (response) => {
38-
if (response.status == 205) {
38+
if (response.status === 202) {
39+
throw new Error('Wait');
40+
} else if (response.status === 205) {
3941
throw new Error('Reboot required');
4042
} else if (response.status === 400) {
4143
throw new Error('Request Failed');
@@ -117,7 +119,7 @@ export const AXIOS_BIN = axios.create({
117119
transformResponse: [(data) => unpack(data)]
118120
});
119121

120-
// TODO replace upload with alova, see https://alova.js.org/next-step/download-upload-progress
122+
// TODO replace fileupload with alova, see https://alova.js.org/next-step/download-upload-progress
121123
export interface FileUploadConfig {
122124
cancelToken?: CancelToken;
123125
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;

interface/src/api/features.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import { AXIOS } from './endpoints';
2-
import type { AxiosPromise } from 'axios';
1+
import { alovaInstance } from './endpoints';
32

43
import type { Features } from 'types';
54

6-
// TODO move to Alova
7-
export function readFeatures(): AxiosPromise<Features> {
8-
return AXIOS.get('/features');
9-
}
5+
export const readFeatures = () => alovaInstance.Get<Features>('/rest/features');

interface/src/api/system.ts

+13-38
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,27 @@
1-
import { AXIOS, AXIOS_BIN, alovaInstance, startUploadFile } from './endpoints';
1+
import { alovaInstance, startUploadFile } from './endpoints';
22
import type { FileUploadConfig } from './endpoints';
33
import type { AxiosPromise } from 'axios';
44

5-
import type { OTASettings, SystemStatus, LogSettings, LogEntries } from 'types';
6-
7-
// TODO move to Alova
8-
// TODO fix this next!
5+
import type { OTASettings, SystemStatus, LogSettings } from 'types';
96

107
export const readSystemStatus = (timeout?: number) =>
118
alovaInstance.Get<SystemStatus>('/rest/systemStatus', {
129
params: { timeout }
1310
});
1411

15-
// export function readSystemStatus(timeout?: number): AxiosPromise<SystemStatus> {
16-
// return AXIOS.get('/systemStatus', { timeout });
17-
// }
18-
19-
export function restart(): AxiosPromise<void> {
20-
return AXIOS.post('/restart');
21-
}
22-
23-
export function partition(): AxiosPromise<void> {
24-
return AXIOS.post('/partition');
25-
}
26-
27-
export function factoryReset(): AxiosPromise<void> {
28-
return AXIOS.post('/factoryReset');
29-
}
12+
// commands
13+
export const restart = () => alovaInstance.Post('/rest/restart');
14+
export const partition = () => alovaInstance.Post('/rest/partition');
15+
export const factoryReset = () => alovaInstance.Post('/rest/factoryReset');
3016

31-
export function readOTASettings(): AxiosPromise<OTASettings> {
32-
return AXIOS.get('/otaSettings');
33-
}
17+
// OTA
18+
export const readOTASettings = () => alovaInstance.Get<OTASettings>(`/rest/otaSettings`);
19+
export const updateOTASettings = (data: any) => alovaInstance.Post('/rest/otaSettings', data);
3420

35-
export function updateOTASettings(otaSettings: OTASettings): AxiosPromise<OTASettings> {
36-
return AXIOS.post('/otaSettings', otaSettings);
37-
}
21+
// SystemLog
22+
export const readLogSettings = () => alovaInstance.Get<LogSettings>(`/rest/logSettings`);
23+
export const updateLogSettings = (data: any) => alovaInstance.Post('/rest/logSettings', data);
24+
export const fetchLog = () => alovaInstance.Post('/rest/fetchLog');
3825

3926
export const uploadFile = (file: File, config?: FileUploadConfig): AxiosPromise<void> =>
4027
startUploadFile('/uploadFile', file, config);
41-
42-
export function readLogSettings(): AxiosPromise<LogSettings> {
43-
return AXIOS.get('/logSettings');
44-
}
45-
46-
export function updateLogSettings(logSettings: LogSettings): AxiosPromise<LogSettings> {
47-
return AXIOS.post('/logSettings', logSettings);
48-
}
49-
50-
export function readLogEntries(): AxiosPromise<LogEntries> {
51-
return AXIOS_BIN.get('/fetchLog');
52-
}

interface/src/components/upload/useFileUpload.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useI18nContext } from 'i18n/i18n-react';
99
import { extractErrorMessage } from 'utils';
1010

1111
interface MediaUploadOptions {
12+
// TODO fileupload move to alova
1213
upload: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
1314
}
1415

interface/src/contexts/features/FeaturesLoader.tsx

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
1-
import { useCallback, useEffect, useState } from 'react';
1+
import { useRequest } from 'alova';
22

33
import { FeaturesContext } from '.';
44
import type { FC } from 'react';
55

6-
import type { Features } from 'types';
76
import type { RequiredChildrenProps } from 'utils';
87
import * as FeaturesApi from 'api/features';
98
import { ApplicationError, LoadingSpinner } from 'components';
10-
import { extractErrorMessage } from 'utils';
119

1210
const FeaturesLoader: FC<RequiredChildrenProps> = (props) => {
13-
const [errorMessage, setErrorMessage] = useState<string>();
14-
const [features, setFeatures] = useState<Features>();
15-
16-
const loadFeatures = useCallback(async () => {
17-
try {
18-
const response = await FeaturesApi.readFeatures();
19-
setFeatures(response.data);
20-
} catch (error) {
21-
setErrorMessage(extractErrorMessage(error, 'Failed to fetch application details.'));
22-
}
23-
}, []);
24-
25-
useEffect(() => {
26-
void loadFeatures();
27-
}, [loadFeatures]);
11+
const { data: features, error } = useRequest(FeaturesApi.readFeatures);
2812

2913
if (features) {
3014
return (
@@ -38,8 +22,8 @@ const FeaturesLoader: FC<RequiredChildrenProps> = (props) => {
3822
);
3923
}
4024

41-
if (errorMessage) {
42-
return <ApplicationError message={errorMessage} />;
25+
if (error) {
26+
return <ApplicationError message={error?.message} />;
4327
}
4428

4529
return <LoadingSpinner height="100vh" />;

interface/src/framework/network/NetworkSettingsForm.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
InputAdornment,
1919
TextField
2020
} from '@mui/material';
21+
// eslint-disable-next-line import/named
2122
import { updateState, useRequest } from 'alova';
2223
import { useContext, useEffect, useState } from 'react';
2324
import { toast } from 'react-toastify';
@@ -29,6 +30,7 @@ import type { FC } from 'react';
2930

3031
import type { NetworkSettings } from 'types';
3132
import * as NetworkApi from 'api/network';
33+
import * as SystemApi from 'api/system';
3234
import {
3335
BlockFormControlLabel,
3436
ButtonRow,
@@ -40,7 +42,7 @@ import {
4042
BlockNavigation
4143
} from 'components';
4244
import { useI18nContext } from 'i18n/i18n-react';
43-
import * as EMSESP from 'project/api';
45+
4446
import { numberValue, updateValueDirty, useRest2 } from 'utils';
4547

4648
import { validate } from 'validators';
@@ -71,7 +73,7 @@ const WiFiSettingsForm: FC = () => {
7173
update: NetworkApi.updateNetworkSettings
7274
});
7375

74-
const { send: restartCommand } = useRequest(EMSESP.restart(), {
76+
const { send: restartCommand } = useRequest(SystemApi.restart(), {
7577
immediate: false
7678
});
7779

interface/src/framework/network/WiFiNetworkScanner.tsx

+31-50
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,63 @@
11
import PermScanWifiIcon from '@mui/icons-material/PermScanWifi';
22
import { Button } from '@mui/material';
3-
import { useEffect, useState, useCallback, useRef } from 'react';
3+
import { useRequest } from 'alova';
4+
import { useState, useCallback, useRef } from 'react';
45
import { toast } from 'react-toastify';
56

67
import WiFiNetworkSelector from './WiFiNetworkSelector';
78
import type { FC } from 'react';
8-
import type { WiFiNetwork, WiFiNetworkList } from 'types';
99
import * as NetworkApi from 'api/network';
1010
import { ButtonRow, FormLoader, SectionContent } from 'components';
1111

1212
import { useI18nContext } from 'i18n/i18n-react';
1313

1414
const NUM_POLLS = 10;
15-
const POLLING_FREQUENCY = 500;
16-
17-
const compareNetworks = (network1: WiFiNetwork, network2: WiFiNetwork) => {
18-
if (network1.rssi < network2.rssi) return 1;
19-
if (network1.rssi > network2.rssi) return -1;
20-
return 0;
21-
};
15+
const POLLING_FREQUENCY = 1000;
2216

2317
const WiFiNetworkScanner: FC = () => {
2418
const { LL } = useI18nContext();
2519

2620
const pollCount = useRef(0);
27-
const [networkList, setNetworkList] = useState<WiFiNetworkList>();
2821
const [errorMessage, setErrorMessage] = useState<string>();
2922

23+
const { data: networkList, send: getNetworkList } = useRequest(NetworkApi.listNetworks, {
24+
immediate: false
25+
});
26+
27+
const {
28+
send: scanNetworks,
29+
onSuccess: onSuccessScanNetworks,
30+
onError: onErrorScanNetworks
31+
} = useRequest(NetworkApi.scanNetworks);
32+
3033
const finishedWithError = useCallback((message: string) => {
3134
toast.error(message);
32-
setNetworkList(undefined);
3335
setErrorMessage(message);
36+
pollCount.current = 0;
3437
}, []);
3538

36-
const pollNetworkList = useCallback(async () => {
37-
try {
38-
const response = await NetworkApi.listNetworks();
39-
if (response.status === 202) {
40-
const completedPollCount = pollCount.current + 1;
41-
if (completedPollCount < NUM_POLLS) {
42-
pollCount.current = completedPollCount;
43-
setTimeout(pollNetworkList, POLLING_FREQUENCY);
44-
} else {
45-
finishedWithError(LL.PROBLEM_LOADING());
46-
}
47-
} else {
48-
const newNetworkList = response.data;
49-
newNetworkList.networks.sort(compareNetworks);
50-
setNetworkList(newNetworkList);
51-
}
52-
} catch (error) {
53-
if (error.response) {
54-
finishedWithError(LL.PROBLEM_LOADING() + ' ' + error.response?.data.message);
39+
onErrorScanNetworks((event) => {
40+
console.log('onErrorScanNetworks'); // TODO fix
41+
if (event.error?.message === 'Wait') {
42+
// 202
43+
console.log('not ready...: ', event.error?.message); // TODO fix
44+
const completedPollCount = pollCount.current + 1;
45+
if (completedPollCount < NUM_POLLS) {
46+
pollCount.current = completedPollCount;
47+
setTimeout(scanNetworks, POLLING_FREQUENCY);
5548
} else {
5649
finishedWithError(LL.PROBLEM_LOADING());
5750
}
51+
} else {
52+
finishedWithError(LL.PROBLEM_LOADING());
5853
}
59-
}, [finishedWithError, LL]);
54+
});
6055

61-
const startNetworkScan = useCallback(async () => {
56+
onSuccessScanNetworks(() => {
57+
console.log('onCompleteScanNetworks'); // TODO fix
6258
pollCount.current = 0;
63-
setNetworkList(undefined);
64-
setErrorMessage(undefined);
65-
try {
66-
await NetworkApi.scanNetworks();
67-
setTimeout(pollNetworkList, POLLING_FREQUENCY);
68-
} catch (error) {
69-
if (error.response) {
70-
finishedWithError(LL.PROBLEM_LOADING() + ' ' + error.response?.data.message);
71-
} else {
72-
finishedWithError(LL.PROBLEM_LOADING());
73-
}
74-
}
75-
}, [finishedWithError, pollNetworkList, LL]);
76-
77-
useEffect(() => {
78-
void startNetworkScan();
79-
}, [startNetworkScan]);
59+
void getNetworkList(); // fetch the list
60+
});
8061

8162
const renderNetworkScanner = () => {
8263
if (!networkList) {
@@ -93,7 +74,7 @@ const WiFiNetworkScanner: FC = () => {
9374
startIcon={<PermScanWifiIcon />}
9475
variant="outlined"
9576
color="secondary"
96-
onClick={startNetworkScan}
77+
onClick={scanNetworks}
9778
disabled={!errorMessage && !networkList}
9879
>
9980
{LL.SCAN_AGAIN()}&hellip;

interface/src/framework/ntp/NTPSettingsForm.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import CancelIcon from '@mui/icons-material/Cancel';
22
import WarningIcon from '@mui/icons-material/Warning';
33
import { Button, Checkbox, MenuItem } from '@mui/material';
4+
// eslint-disable-next-line import/named
45
import { updateState } from 'alova';
56
import { useState } from 'react';
67
import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ';

interface/src/framework/system/GeneralFileUpload.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useI18nContext } from 'i18n/i18n-react';
1212
import * as EMSESP from 'project/api';
1313

1414
interface UploadFileProps {
15+
// TODO fileupload upload move to alova
1516
uploadGeneralFile: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
1617
}
1718

0 commit comments

Comments
 (0)