Skip to content

Commit

Permalink
more alova ports
Browse files Browse the repository at this point in the history
  • Loading branch information
proddy committed Jun 17, 2023
1 parent 2ae45ec commit ed55a96
Show file tree
Hide file tree
Showing 31 changed files with 827 additions and 890 deletions.
2 changes: 1 addition & 1 deletion interface/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.11",
"@vitejs/plugin-react-swc": "^3.3.2",
"eslint": "^8.42.0",
"eslint": "^8.43.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.8.0",
Expand Down
2 changes: 1 addition & 1 deletion interface/src/AuthenticatedRouting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const AuthenticatedRouting: FC = () => {
);

useEffect(() => {
// TODO how to replace AXIOS.interceptors.response.use ???
// TODO replace AXIOS.interceptors.response.use ???
const axiosHandlerId = AXIOS.interceptors.response.use((response) => response, handleApiResponseError);
return () => AXIOS.interceptors.response.eject(axiosHandlerId);
}, [handleApiResponseError]);
Expand Down
1 change: 1 addition & 0 deletions interface/src/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const SignIn: FC = () => {

const signIn = async () => {
try {
// TODO move to Alova
const { data: loginResponse } = await AuthenticationApi.signIn(signInRequest);
authenticationContext.signIn(loginResponse.access_token);
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion interface/src/api/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import type { Me, SignInRequest, SignInResponse } from 'types';
export const SIGN_IN_PATHNAME = 'loginPathname';
export const SIGN_IN_SEARCH = 'loginSearch';

// TODO move to Alova
// TODO move verifyAuthorization to Alova
export function verifyAuthorization(): AxiosPromise<void> {
return AXIOS.get('/verifyAuthorization');
}
// TODO move signIn to Alova
export function signIn(request: SignInRequest): AxiosPromise<SignInResponse> {
return AXIOS.post('/signIn', request);
}
Expand Down
8 changes: 5 additions & 3 deletions interface/src/api/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const EVENT_SOURCE_ROOT = 'http://' + host + '/es/';

export const alovaInstance = createAlova({
statesHook: ReactHook,
timeout: 3000,
// timeout: 3000,
localCache: {
GET: {
mode: 'placeholder',
Expand All @@ -35,7 +35,9 @@ export const alovaInstance = createAlova({

responded: {
onSuccess: async (response) => {
if (response.status == 205) {
if (response.status === 202) {
throw new Error('Wait');
} else if (response.status === 205) {
throw new Error('Reboot required');
} else if (response.status === 400) {
throw new Error('Request Failed');
Expand Down Expand Up @@ -117,7 +119,7 @@ export const AXIOS_BIN = axios.create({
transformResponse: [(data) => unpack(data)]
});

// TODO replace upload with alova, see https://alova.js.org/next-step/download-upload-progress
// TODO replace fileupload with alova, see https://alova.js.org/next-step/download-upload-progress
export interface FileUploadConfig {
cancelToken?: CancelToken;
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
Expand Down
8 changes: 2 additions & 6 deletions interface/src/api/features.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { AXIOS } from './endpoints';
import type { AxiosPromise } from 'axios';
import { alovaInstance } from './endpoints';

import type { Features } from 'types';

// TODO move to Alova
export function readFeatures(): AxiosPromise<Features> {
return AXIOS.get('/features');
}
export const readFeatures = () => alovaInstance.Get<Features>('/rest/features');
51 changes: 13 additions & 38 deletions interface/src/api/system.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,27 @@
import { AXIOS, AXIOS_BIN, alovaInstance, startUploadFile } from './endpoints';
import { alovaInstance, startUploadFile } from './endpoints';
import type { FileUploadConfig } from './endpoints';
import type { AxiosPromise } from 'axios';

import type { OTASettings, SystemStatus, LogSettings, LogEntries } from 'types';

// TODO move to Alova
// TODO fix this next!
import type { OTASettings, SystemStatus, LogSettings } from 'types';

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

// export function readSystemStatus(timeout?: number): AxiosPromise<SystemStatus> {
// return AXIOS.get('/systemStatus', { timeout });
// }

export function restart(): AxiosPromise<void> {
return AXIOS.post('/restart');
}

export function partition(): AxiosPromise<void> {
return AXIOS.post('/partition');
}

export function factoryReset(): AxiosPromise<void> {
return AXIOS.post('/factoryReset');
}
// commands
export const restart = () => alovaInstance.Post('/rest/restart');
export const partition = () => alovaInstance.Post('/rest/partition');
export const factoryReset = () => alovaInstance.Post('/rest/factoryReset');

export function readOTASettings(): AxiosPromise<OTASettings> {
return AXIOS.get('/otaSettings');
}
// OTA
export const readOTASettings = () => alovaInstance.Get<OTASettings>(`/rest/otaSettings`);
export const updateOTASettings = (data: any) => alovaInstance.Post('/rest/otaSettings', data);

export function updateOTASettings(otaSettings: OTASettings): AxiosPromise<OTASettings> {
return AXIOS.post('/otaSettings', otaSettings);
}
// SystemLog
export const readLogSettings = () => alovaInstance.Get<LogSettings>(`/rest/logSettings`);
export const updateLogSettings = (data: any) => alovaInstance.Post('/rest/logSettings', data);
export const fetchLog = () => alovaInstance.Post('/rest/fetchLog');

export const uploadFile = (file: File, config?: FileUploadConfig): AxiosPromise<void> =>
startUploadFile('/uploadFile', file, config);

export function readLogSettings(): AxiosPromise<LogSettings> {
return AXIOS.get('/logSettings');
}

export function updateLogSettings(logSettings: LogSettings): AxiosPromise<LogSettings> {
return AXIOS.post('/logSettings', logSettings);
}

export function readLogEntries(): AxiosPromise<LogEntries> {
return AXIOS_BIN.get('/fetchLog');
}
1 change: 1 addition & 0 deletions interface/src/components/upload/useFileUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useI18nContext } from 'i18n/i18n-react';
import { extractErrorMessage } from 'utils';

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

Expand Down
24 changes: 4 additions & 20 deletions interface/src/contexts/features/FeaturesLoader.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
import { useCallback, useEffect, useState } from 'react';
import { useRequest } from 'alova';

import { FeaturesContext } from '.';
import type { FC } from 'react';

import type { Features } from 'types';
import type { RequiredChildrenProps } from 'utils';
import * as FeaturesApi from 'api/features';
import { ApplicationError, LoadingSpinner } from 'components';
import { extractErrorMessage } from 'utils';

const FeaturesLoader: FC<RequiredChildrenProps> = (props) => {
const [errorMessage, setErrorMessage] = useState<string>();
const [features, setFeatures] = useState<Features>();

const loadFeatures = useCallback(async () => {
try {
const response = await FeaturesApi.readFeatures();
setFeatures(response.data);
} catch (error) {
setErrorMessage(extractErrorMessage(error, 'Failed to fetch application details.'));
}
}, []);

useEffect(() => {
void loadFeatures();
}, [loadFeatures]);
const { data: features, error } = useRequest(FeaturesApi.readFeatures);

if (features) {
return (
Expand All @@ -38,8 +22,8 @@ const FeaturesLoader: FC<RequiredChildrenProps> = (props) => {
);
}

if (errorMessage) {
return <ApplicationError message={errorMessage} />;
if (error) {
return <ApplicationError message={error?.message} />;
}

return <LoadingSpinner height="100vh" />;
Expand Down
6 changes: 4 additions & 2 deletions interface/src/framework/network/NetworkSettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
InputAdornment,
TextField
} from '@mui/material';
// eslint-disable-next-line import/named
import { updateState, useRequest } from 'alova';
import { useContext, useEffect, useState } from 'react';
import { toast } from 'react-toastify';
Expand All @@ -29,6 +30,7 @@ import type { FC } from 'react';

import type { NetworkSettings } from 'types';
import * as NetworkApi from 'api/network';
import * as SystemApi from 'api/system';
import {
BlockFormControlLabel,
ButtonRow,
Expand All @@ -40,7 +42,7 @@ import {
BlockNavigation
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import * as EMSESP from 'project/api';

import { numberValue, updateValueDirty, useRest2 } from 'utils';

import { validate } from 'validators';
Expand Down Expand Up @@ -71,7 +73,7 @@ const WiFiSettingsForm: FC = () => {
update: NetworkApi.updateNetworkSettings
});

const { send: restartCommand } = useRequest(EMSESP.restart(), {
const { send: restartCommand } = useRequest(SystemApi.restart(), {
immediate: false
});

Expand Down
81 changes: 31 additions & 50 deletions interface/src/framework/network/WiFiNetworkScanner.tsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,63 @@
import PermScanWifiIcon from '@mui/icons-material/PermScanWifi';
import { Button } from '@mui/material';
import { useEffect, useState, useCallback, useRef } from 'react';
import { useRequest } from 'alova';
import { useState, useCallback, useRef } from 'react';
import { toast } from 'react-toastify';

import WiFiNetworkSelector from './WiFiNetworkSelector';
import type { FC } from 'react';
import type { WiFiNetwork, WiFiNetworkList } from 'types';
import * as NetworkApi from 'api/network';
import { ButtonRow, FormLoader, SectionContent } from 'components';

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

const NUM_POLLS = 10;
const POLLING_FREQUENCY = 500;

const compareNetworks = (network1: WiFiNetwork, network2: WiFiNetwork) => {
if (network1.rssi < network2.rssi) return 1;
if (network1.rssi > network2.rssi) return -1;
return 0;
};
const POLLING_FREQUENCY = 1000;

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

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

const { data: networkList, send: getNetworkList } = useRequest(NetworkApi.listNetworks, {
immediate: false
});

const {
send: scanNetworks,
onSuccess: onSuccessScanNetworks,
onError: onErrorScanNetworks
} = useRequest(NetworkApi.scanNetworks);

const finishedWithError = useCallback((message: string) => {
toast.error(message);
setNetworkList(undefined);
setErrorMessage(message);
pollCount.current = 0;
}, []);

const pollNetworkList = useCallback(async () => {
try {
const response = await NetworkApi.listNetworks();
if (response.status === 202) {
const completedPollCount = pollCount.current + 1;
if (completedPollCount < NUM_POLLS) {
pollCount.current = completedPollCount;
setTimeout(pollNetworkList, POLLING_FREQUENCY);
} else {
finishedWithError(LL.PROBLEM_LOADING());
}
} else {
const newNetworkList = response.data;
newNetworkList.networks.sort(compareNetworks);
setNetworkList(newNetworkList);
}
} catch (error) {
if (error.response) {
finishedWithError(LL.PROBLEM_LOADING() + ' ' + error.response?.data.message);
onErrorScanNetworks((event) => {
console.log('onErrorScanNetworks'); // TODO fix
if (event.error?.message === 'Wait') {
// 202
console.log('not ready...: ', event.error?.message); // TODO fix
const completedPollCount = pollCount.current + 1;
if (completedPollCount < NUM_POLLS) {
pollCount.current = completedPollCount;
setTimeout(scanNetworks, POLLING_FREQUENCY);
} else {
finishedWithError(LL.PROBLEM_LOADING());
}
} else {
finishedWithError(LL.PROBLEM_LOADING());
}
}, [finishedWithError, LL]);
});

const startNetworkScan = useCallback(async () => {
onSuccessScanNetworks(() => {
console.log('onCompleteScanNetworks'); // TODO fix
pollCount.current = 0;
setNetworkList(undefined);
setErrorMessage(undefined);
try {
await NetworkApi.scanNetworks();
setTimeout(pollNetworkList, POLLING_FREQUENCY);
} catch (error) {
if (error.response) {
finishedWithError(LL.PROBLEM_LOADING() + ' ' + error.response?.data.message);
} else {
finishedWithError(LL.PROBLEM_LOADING());
}
}
}, [finishedWithError, pollNetworkList, LL]);

useEffect(() => {
void startNetworkScan();
}, [startNetworkScan]);
void getNetworkList(); // fetch the list
});

const renderNetworkScanner = () => {
if (!networkList) {
Expand All @@ -93,7 +74,7 @@ const WiFiNetworkScanner: FC = () => {
startIcon={<PermScanWifiIcon />}
variant="outlined"
color="secondary"
onClick={startNetworkScan}
onClick={scanNetworks}
disabled={!errorMessage && !networkList}
>
{LL.SCAN_AGAIN()}&hellip;
Expand Down
1 change: 1 addition & 0 deletions interface/src/framework/ntp/NTPSettingsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
import { Button, Checkbox, MenuItem } from '@mui/material';
// eslint-disable-next-line import/named
import { updateState } from 'alova';
import { useState } from 'react';
import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ';
Expand Down
1 change: 1 addition & 0 deletions interface/src/framework/system/GeneralFileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useI18nContext } from 'i18n/i18n-react';
import * as EMSESP from 'project/api';

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

Expand Down
Loading

0 comments on commit ed55a96

Please sign in to comment.