mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
alova upload experiments
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "EMS-ESP",
|
"name": "EMS-ESP",
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"description": "build EMS-ESP TypeScript WebUI",
|
"description": "build EMS-ESP WebUI",
|
||||||
"homepage": "https://emsesp.github.io/docs",
|
"homepage": "https://emsesp.github.io/docs",
|
||||||
"author": "proddy",
|
"author": "proddy",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -19,24 +19,25 @@
|
|||||||
"lint": "eslint . --cache --fix"
|
"lint": "eslint . --cache --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alova/adapter-xhr": "^1.0.0",
|
"@alova/adapter-xhr": "^1.0.1",
|
||||||
"@alova/scene-react": "^1.1.0",
|
"@alova/scene-react": "^1.1.3",
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@mui/icons-material": "^5.11.16",
|
"@mui/icons-material": "^5.11.16",
|
||||||
"@mui/material": "^5.13.6",
|
"@mui/material": "^5.13.6",
|
||||||
"@table-library/react-table-library": "4.1.4",
|
"@table-library/react-table-library": "4.1.4",
|
||||||
"@types/lodash-es": "^4.17.7",
|
"@types/lodash-es": "^4.17.7",
|
||||||
"@types/node": "^20.3.1",
|
"@types/node": "^20.3.2",
|
||||||
"@types/react": "^18.2.14",
|
"@types/react": "^18.2.14",
|
||||||
"@types/react-dom": "^18.2.6",
|
"@types/react-dom": "^18.2.6",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"alova": "^2.6.2",
|
"alova": "^2.8.0",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"axios": "^1.4.0",
|
"dev": "^0.1.3",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
"react": "latest",
|
"react": "latest",
|
||||||
"react-dom": "latest",
|
"react-dom": "latest",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
@@ -45,11 +46,12 @@
|
|||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
"sockette": "^2.0.6",
|
"sockette": "^2.0.6",
|
||||||
"typesafe-i18n": "^5.24.3",
|
"typesafe-i18n": "^5.24.3",
|
||||||
"typescript": "^5.1.3"
|
"typescript": "^5.1.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
"@types/mime-types": "^2",
|
||||||
"@typescript-eslint/parser": "^5.60.0",
|
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||||
|
"@typescript-eslint/parser": "^5.60.1",
|
||||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||||
"eslint": "^8.43.0",
|
"eslint": "^8.43.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
@@ -66,7 +68,7 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"terser": "^5.18.1",
|
"terser": "^5.18.2",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vite-plugin-svgr": "^3.2.0",
|
"vite-plugin-svgr": "^3.2.0",
|
||||||
"vite-tsconfig-paths": "^4.2.0"
|
"vite-tsconfig-paths": "^4.2.0"
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
// import { useCallback, useEffect } from 'react';
|
|
||||||
import { Navigate, Routes, Route } from 'react-router-dom';
|
import { Navigate, Routes, Route } from 'react-router-dom';
|
||||||
import Dashboard from './project/Dashboard';
|
import Dashboard from './project/Dashboard';
|
||||||
import Help from './project/Help';
|
import Help from './project/Help';
|
||||||
import Settings from './project/Settings';
|
import Settings from './project/Settings';
|
||||||
// import type { AxiosError } from 'axios';
|
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
// import * as AuthenticationApi from 'api/authentication';
|
|
||||||
// import { AXIOS } from 'api/endpoints';
|
|
||||||
import { Layout, RequireAdmin } from 'components';
|
import { Layout, RequireAdmin } from 'components';
|
||||||
|
|
||||||
import AccessPoint from 'framework/ap/AccessPoint';
|
import AccessPoint from 'framework/ap/AccessPoint';
|
||||||
import Mqtt from 'framework/mqtt/Mqtt';
|
import Mqtt from 'framework/mqtt/Mqtt';
|
||||||
import NetworkConnection from 'framework/network/NetworkConnection';
|
import NetworkConnection from 'framework/network/NetworkConnection';
|
||||||
@@ -18,10 +13,9 @@ import Security from 'framework/security/Security';
|
|||||||
import System from 'framework/system/System';
|
import System from 'framework/system/System';
|
||||||
|
|
||||||
const AuthenticatedRouting: FC = () => (
|
const AuthenticatedRouting: FC = () => (
|
||||||
|
// TODO not sure if this is needed, to redirect on 401. If so add incerceptor to Alova
|
||||||
// const location = useLocation();
|
// const location = useLocation();
|
||||||
// const navigate = useNavigate();
|
// const navigate = useNavigate();
|
||||||
|
|
||||||
// TODO not sure if this is needed, to redirect on 401. If so add incerceptor to Alova
|
|
||||||
// const handleApiResponseError = useCallback(
|
// const handleApiResponseError = useCallback(
|
||||||
// (error: AxiosError) => {
|
// (error: AxiosError) => {
|
||||||
// if (error.response && error.response.status === 401) {
|
// if (error.response && error.response.status === 401) {
|
||||||
@@ -32,7 +26,6 @@ const AuthenticatedRouting: FC = () => (
|
|||||||
// },
|
// },
|
||||||
// [location, navigate]
|
// [location, navigate]
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// const axiosHandlerId = AXIOS.interceptors.response.use((response) => response, handleApiResponseError);
|
// const axiosHandlerId = AXIOS.interceptors.response.use((response) => response, handleApiResponseError);
|
||||||
// return () => AXIOS.interceptors.response.eject(axiosHandlerId);
|
// return () => AXIOS.interceptors.response.eject(axiosHandlerId);
|
||||||
@@ -68,4 +61,5 @@ const AuthenticatedRouting: FC = () => (
|
|||||||
</Routes>
|
</Routes>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default AuthenticatedRouting;
|
export default AuthenticatedRouting;
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import { xhrRequestAdapter } from '@alova/adapter-xhr';
|
import { xhrRequestAdapter } from '@alova/adapter-xhr';
|
||||||
import { createAlova } from 'alova';
|
import { createAlova } from 'alova';
|
||||||
import ReactHook from 'alova/react';
|
import ReactHook from 'alova/react';
|
||||||
import axios from 'axios';
|
|
||||||
import { unpack } from '../api/unpack';
|
import { unpack } from '../api/unpack';
|
||||||
|
|
||||||
import type { AxiosPromise, CancelToken, AxiosProgressEvent } from 'axios';
|
|
||||||
|
|
||||||
export const ACCESS_TOKEN = 'access_token';
|
export const ACCESS_TOKEN = 'access_token';
|
||||||
|
|
||||||
const host = window.location.host;
|
const host = window.location.host;
|
||||||
@@ -14,11 +11,10 @@ export const EVENT_SOURCE_ROOT = 'http://' + host + '/es/';
|
|||||||
|
|
||||||
export const alovaInstance = createAlova({
|
export const alovaInstance = createAlova({
|
||||||
statesHook: ReactHook,
|
statesHook: ReactHook,
|
||||||
timeout: 3000,
|
// timeout: 3000, // timeout not used because of uploading firmware
|
||||||
localCache: {
|
localCache: {
|
||||||
GET: {
|
GET: {
|
||||||
mode: 'placeholder',
|
mode: 'placeholder', // see https://alova.js.org/learning/response-cache/#cache-replaceholder-mode
|
||||||
// see https://alova.js.org/learning/response-cache/#cache-replaceholder-mode
|
|
||||||
expire: 2000
|
expire: 2000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -61,42 +57,3 @@ export const alovaInstanceGH = createAlova({
|
|||||||
statesHook: ReactHook,
|
statesHook: ReactHook,
|
||||||
requestAdapter: xhrRequestAdapter()
|
requestAdapter: xhrRequestAdapter()
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AXIOS = axios.create({
|
|
||||||
baseURL: '/rest/',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
transformRequest: [
|
|
||||||
(data, headers) => {
|
|
||||||
if (headers) {
|
|
||||||
if (localStorage.getItem(ACCESS_TOKEN)) {
|
|
||||||
headers.Authorization = 'Bearer ' + localStorage.getItem(ACCESS_TOKEN);
|
|
||||||
}
|
|
||||||
if (headers['Content-Type'] !== 'application/json') {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return JSON.stringify(data);
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO fileupload move to alova
|
|
||||||
// see https://alova.js.org/next-step/download-upload-progress
|
|
||||||
export interface FileUploadConfig {
|
|
||||||
cancelToken?: CancelToken;
|
|
||||||
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const startUploadFile = (url: string, file: File, config?: FileUploadConfig): AxiosPromise<void> => {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
return AXIOS.post(url, formData, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'multipart/form-data'
|
|
||||||
},
|
|
||||||
...(config || {})
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import { alovaInstance, alovaInstanceGH, startUploadFile } from './endpoints';
|
import { alovaInstance, alovaInstanceGH } from './endpoints';
|
||||||
import type { FileUploadConfig } from './endpoints';
|
|
||||||
import type { AxiosPromise } from 'axios';
|
|
||||||
|
|
||||||
import type { OTASettings, SystemStatus, LogSettings, Version } from 'types';
|
import type { OTASettings, SystemStatus, LogSettings, Version } from 'types';
|
||||||
|
|
||||||
// SystemStatus - also used to ping in Restart monitor
|
// SystemStatus - also used to ping in Restart monitor
|
||||||
@@ -32,6 +29,7 @@ export const getStableVersion = () =>
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getDevVersion = () =>
|
export const getDevVersion = () =>
|
||||||
alovaInstanceGH.Get<Version>('releases/tags/latest', {
|
alovaInstanceGH.Get<Version>('releases/tags/latest', {
|
||||||
transformData(reponse: any) {
|
transformData(reponse: any) {
|
||||||
@@ -43,6 +41,10 @@ export const getDevVersion = () =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO fileupload move to alova
|
export const uploadFile = (file: File) => {
|
||||||
export const uploadFile = (file: File, config?: FileUploadConfig): AxiosPromise<void> =>
|
const formData = new FormData();
|
||||||
startUploadFile('/uploadFile', file, config);
|
formData.append('file', file);
|
||||||
|
return alovaInstance.Post('/rest/uploadFile', formData, {
|
||||||
|
enableUpload: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Box, Button, LinearProgress, Typography, useTheme } from '@mui/material
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { useDropzone } from 'react-dropzone';
|
import { useDropzone } from 'react-dropzone';
|
||||||
import type { Theme } from '@mui/material';
|
import type { Theme } from '@mui/material';
|
||||||
import type { AxiosProgressEvent } from 'axios';
|
import type { Progress } from 'alova';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import type { DropzoneState } from 'react-dropzone';
|
import type { DropzoneState } from 'react-dropzone';
|
||||||
|
|
||||||
@@ -26,11 +26,13 @@ const getBorderColor = (theme: Theme, props: DropzoneState) => {
|
|||||||
export interface SingleUploadProps {
|
export interface SingleUploadProps {
|
||||||
onDrop: (acceptedFiles: File[]) => void;
|
onDrop: (acceptedFiles: File[]) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
uploading: boolean;
|
isUploading: boolean;
|
||||||
progress?: AxiosProgressEvent;
|
progress?: Progress;
|
||||||
|
// TODO remove
|
||||||
|
// progress?: AxiosProgressEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, uploading, progress }) => {
|
const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, isUploading, progress }) => {
|
||||||
const dropzoneState = useDropzone({
|
const dropzoneState = useDropzone({
|
||||||
onDrop,
|
onDrop,
|
||||||
accept: {
|
accept: {
|
||||||
@@ -38,7 +40,7 @@ const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, uploading, prog
|
|||||||
'application/json': ['.json'],
|
'application/json': ['.json'],
|
||||||
'text/plain': ['.md5']
|
'text/plain': ['.md5']
|
||||||
},
|
},
|
||||||
disabled: uploading,
|
disabled: isUploading,
|
||||||
multiple: false
|
multiple: false
|
||||||
});
|
});
|
||||||
const { getRootProps, getInputProps } = dropzoneState;
|
const { getRootProps, getInputProps } = dropzoneState;
|
||||||
@@ -46,8 +48,11 @@ const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, uploading, prog
|
|||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
|
// TODO remove debug
|
||||||
|
console.log('progress', progress?.loaded);
|
||||||
|
|
||||||
const progressText = () => {
|
const progressText = () => {
|
||||||
if (uploading) {
|
if (isUploading) {
|
||||||
if (progress?.total) {
|
if (progress?.total) {
|
||||||
return LL.UPLOADING() + ': ' + Math.round((progress.loaded * 100) / progress.total) + '%';
|
return LL.UPLOADING() + ': ' + Math.round((progress.loaded * 100) / progress.total) + '%';
|
||||||
}
|
}
|
||||||
@@ -68,7 +73,7 @@ const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, uploading, prog
|
|||||||
color: theme.palette.grey[400],
|
color: theme.palette.grey[400],
|
||||||
transition: 'border .24s ease-in-out',
|
transition: 'border .24s ease-in-out',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
cursor: uploading ? 'default' : 'pointer',
|
cursor: isUploading ? 'default' : 'pointer',
|
||||||
borderColor: getBorderColor(theme, dropzoneState)
|
borderColor: getBorderColor(theme, dropzoneState)
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
@@ -77,7 +82,7 @@ const SingleUpload: FC<SingleUploadProps> = ({ onDrop, onCancel, uploading, prog
|
|||||||
<Box flexDirection="column" display="flex" alignItems="center">
|
<Box flexDirection="column" display="flex" alignItems="center">
|
||||||
<CloudUploadIcon fontSize="large" />
|
<CloudUploadIcon fontSize="large" />
|
||||||
<Typography variant="h6">{progressText()}</Typography>
|
<Typography variant="h6">{progressText()}</Typography>
|
||||||
{uploading && (
|
{isUploading && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Box width="100%" p={2}>
|
<Box width="100%" p={2}>
|
||||||
<LinearProgress
|
<LinearProgress
|
||||||
|
|||||||
@@ -1,72 +1,94 @@
|
|||||||
import axios from 'axios';
|
import { useRequest } from 'alova';
|
||||||
|
// import axios from 'axios';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import type { FileUploadConfig } from 'api/endpoints';
|
// import type { FileUploadConfig } from 'api/endpoints';
|
||||||
import type { AxiosPromise, CancelTokenSource, AxiosProgressEvent } from 'axios';
|
// import type { AxiosPromise, CancelTokenSource, AxiosProgressEvent } from 'axios';
|
||||||
|
|
||||||
|
import * as SystemApi from 'api/system';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
interface MediaUploadOptions {
|
interface MediaUploadOptions {
|
||||||
// TODO fileupload move to alova
|
// TODO fileupload move to alova
|
||||||
upload: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
// upload: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
||||||
|
upload: (file: File) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useFileUpload = ({ upload }: MediaUploadOptions) => {
|
const useFileUpload = ({ upload }: MediaUploadOptions) => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
const [uploading, setUploading] = useState<boolean>(false);
|
// const [uploading, setUploading] = useState<boolean>(false);
|
||||||
const [md5, setMd5] = useState<string>('');
|
const [md5, setMd5] = useState<string>('');
|
||||||
const [uploadProgress, setUploadProgress] = useState<AxiosProgressEvent>();
|
// const [uploadProgress, setUploadProgress] = useState<AxiosProgressEvent>();
|
||||||
const [uploadCancelToken, setUploadCancelToken] = useState<CancelTokenSource>();
|
// const [uploadCancelToken, setUploadCancelToken] = useState<CancelTokenSource>();
|
||||||
|
|
||||||
|
const { uploading, send: sendUpload } = useRequest(SystemApi.uploadFile, {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
const resetUploadingStates = () => {
|
const resetUploadingStates = () => {
|
||||||
setUploading(false);
|
// setUploading(false);
|
||||||
setUploadProgress(undefined);
|
// setUploadProgress(undefined);
|
||||||
setUploadCancelToken(undefined);
|
// setUploadCancelToken(undefined);
|
||||||
setMd5('');
|
setMd5('');
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelUpload = useCallback(() => {
|
// const cancelUpload = useCallback(() => {
|
||||||
uploadCancelToken?.cancel();
|
// uploadCancelToken?.cancel();
|
||||||
resetUploadingStates();
|
// resetUploadingStates();
|
||||||
}, [uploadCancelToken]);
|
// }, [uploadCancelToken]);
|
||||||
|
|
||||||
useEffect(
|
// useEffect(
|
||||||
() => () => {
|
// () => () => {
|
||||||
uploadCancelToken?.cancel();
|
// uploadCancelToken?.cancel();
|
||||||
},
|
// },
|
||||||
[uploadCancelToken]
|
// [uploadCancelToken]
|
||||||
);
|
// );
|
||||||
|
|
||||||
// TODO fileupload move to alova
|
// TODO fileupload move to alova
|
||||||
const uploadFile = async (images: File[]) => {
|
// TODO make it single file
|
||||||
try {
|
const uploadFile = async (files: File[]) => {
|
||||||
const cancelToken = axios.CancelToken.source();
|
// TODO remove debug
|
||||||
setUploadCancelToken(cancelToken);
|
console.log('useFileUpload.ts:uploadFile:' + files[0].name, files[0].size);
|
||||||
setUploading(true);
|
|
||||||
const response = await upload(images[0], {
|
await sendUpload(files[0]);
|
||||||
onUploadProgress: setUploadProgress,
|
|
||||||
cancelToken: cancelToken.token
|
// const response = await SystemApi.startUploadFile(files[0]);
|
||||||
});
|
// console.log(response.status);
|
||||||
resetUploadingStates();
|
|
||||||
if (response.status === 200) {
|
// const response = await upload(files[0], {
|
||||||
toast.success(LL.UPLOAD() + ' ' + LL.SUCCESSFUL());
|
// onUploadProgress: setUploadProgress,
|
||||||
} else if (response.status === 201) {
|
// cancelToken: cancelToken.token
|
||||||
setMd5(String(response.data));
|
// });
|
||||||
toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL());
|
|
||||||
}
|
// try {
|
||||||
} catch (error) {
|
// const cancelToken = axios.CancelToken.source();
|
||||||
if (axios.isCancel(error)) {
|
// setUploadCancelToken(cancelToken);
|
||||||
toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED());
|
// setUploading(true);
|
||||||
} else {
|
// const response = await upload(images[0], {
|
||||||
resetUploadingStates();
|
// onUploadProgress: setUploadProgress,
|
||||||
toast.error(LL.UPLOAD() + ' ' + LL.FAILED(0));
|
// cancelToken: cancelToken.token
|
||||||
}
|
// });
|
||||||
}
|
// resetUploadingStates();
|
||||||
|
// if (response.status === 200) {
|
||||||
|
// toast.success(LL.UPLOAD() + ' ' + LL.SUCCESSFUL());
|
||||||
|
// } else if (response.status === 201) {
|
||||||
|
// setMd5(String(response.data));
|
||||||
|
// toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL());
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
// if (axios.isCancel(error)) {
|
||||||
|
// toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED());
|
||||||
|
// } else {
|
||||||
|
// resetUploadingStates();
|
||||||
|
// toast.error(LL.UPLOAD() + ' ' + LL.FAILED(0));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
return [uploadFile, cancelUpload, uploading, uploadProgress, md5] as const;
|
return [uploadFile, uploading, md5] as const;
|
||||||
|
// return [uploadFile, cancelUpload, uploading, uploadProgress, md5] as const;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useFileUpload;
|
export default useFileUpload;
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ import DownloadIcon from '@mui/icons-material/GetApp';
|
|||||||
import { Typography, Button, Box } from '@mui/material';
|
import { Typography, Button, Box } from '@mui/material';
|
||||||
import { useRequest } from 'alova';
|
import { useRequest } from 'alova';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import type { FileUploadConfig } from 'api/endpoints';
|
|
||||||
import type { AxiosPromise } from 'axios';
|
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import * as SystemApi from 'api/system';
|
||||||
import { SingleUpload, useFileUpload } from 'components';
|
import { SingleUpload, useFileUpload } from 'components';
|
||||||
|
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
@@ -13,11 +12,20 @@ import * as EMSESP from 'project/api';
|
|||||||
|
|
||||||
interface UploadFileProps {
|
interface UploadFileProps {
|
||||||
// TODO fileupload move to alova
|
// TODO fileupload move to alova
|
||||||
uploadGeneralFile: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
// uploadGeneralFile: (file: File, config?: FileUploadConfig) => AxiosPromise<void>;
|
||||||
|
uploadGeneralFile: (file: File) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
|
const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
|
||||||
const [uploadFile, cancelUpload, uploading, uploadProgress, md5] = useFileUpload({ upload: uploadGeneralFile });
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
|
// TODO remove these
|
||||||
|
const md5 = '';
|
||||||
|
const cancelUpload = () => {};
|
||||||
|
const uploading = false;
|
||||||
|
|
||||||
|
// const [uploadFile, cancelUpload, uploading, uploadProgress, md5] = useFileUpload({ upload: uploadGeneralFile });
|
||||||
|
// const [uploadFile, cancelUpload, uploading, md5] = useFileUpload({ upload: uploadGeneralFile });
|
||||||
|
|
||||||
const { send: getSettings, onSuccess: onSuccessGetSettings } = useRequest(EMSESP.getSettings(), {
|
const { send: getSettings, onSuccess: onSuccessGetSettings } = useRequest(EMSESP.getSettings(), {
|
||||||
immediate: false
|
immediate: false
|
||||||
@@ -32,8 +40,23 @@ const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
|
|||||||
immediate: false
|
immediate: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const {
|
||||||
|
loading: isUploading,
|
||||||
|
uploading: progress,
|
||||||
|
send: sendUpload
|
||||||
|
} = useRequest(SystemApi.uploadFile, {
|
||||||
|
immediate: false,
|
||||||
|
force: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const uploadFile = async (files: File[]) => {
|
||||||
|
// TODO remove debug
|
||||||
|
console.log('useFileUpload.ts:uploadFile:' + files[0].name, files[0].size);
|
||||||
|
await sendUpload(files[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO see if refactor like https://alova.js.org/extension/alova-adapter-xhr/#download
|
||||||
|
// And use revoke
|
||||||
const saveFile = (json: any, endpoint: string) => {
|
const saveFile = (json: any, endpoint: string) => {
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
const filename = 'emsesp_' + endpoint + '.json';
|
const filename = 'emsesp_' + endpoint + '.json';
|
||||||
@@ -103,9 +126,11 @@ const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
|
|||||||
<Typography variant="body2">{'MD5: ' + md5}</Typography>
|
<Typography variant="body2">{'MD5: ' + md5}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<SingleUpload onDrop={uploadFile} onCancel={cancelUpload} uploading={uploading} progress={uploadProgress} />
|
{/* TODO fix this hardcoded isUploading */}
|
||||||
|
<SingleUpload onDrop={uploadFile} onCancel={cancelUpload} isUploading={isUploading} progress={progress} />
|
||||||
{!uploading && (
|
{console.log(progress)}
|
||||||
|
{/* <SingleUpload onDrop={uploadFile} onCancel={cancelUpload} isUploading={false} progress={uploading} /> */}
|
||||||
|
{!isUploading && (
|
||||||
<>
|
<>
|
||||||
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
||||||
{LL.DOWNLOAD(0)}
|
{LL.DOWNLOAD(0)}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import { useRequest } from 'alova';
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import GeneralFileUpload from './GeneralFileUpload';
|
import GeneralFileUpload from './GeneralFileUpload';
|
||||||
import RestartMonitor from './RestartMonitor';
|
import RestartMonitor from './RestartMonitor';
|
||||||
import type { FileUploadConfig } from 'api/endpoints';
|
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
import * as SystemApi from 'api/system';
|
import * as SystemApi from 'api/system';
|
||||||
@@ -14,13 +14,25 @@ const UploadFileForm: FC = () => {
|
|||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
const uploadFile = useRef(async (file: File, config?: FileUploadConfig) => {
|
const {
|
||||||
|
loading,
|
||||||
|
data,
|
||||||
|
uploading,
|
||||||
|
send: sendUpload
|
||||||
|
} = useRequest(SystemApi.uploadFile, {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const uploadFile = useRef(async (file: File) => {
|
||||||
// TODO fileupload move to alova
|
// TODO fileupload move to alova
|
||||||
const response = await SystemApi.uploadFile(file, config);
|
console.log('UploadFileForm.tsx: uploadFile duplicate!!!'); // TODO do we need this function??? duplicate?
|
||||||
if (response.status === 200) {
|
await sendUpload(file);
|
||||||
setRestarting(true);
|
|
||||||
}
|
// const response = await SystemApi.uploadFile(file);
|
||||||
return response;
|
// if (response.status === 200) {
|
||||||
|
// setRestarting(true);
|
||||||
|
// }
|
||||||
|
// return response;
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ __metadata:
|
|||||||
version: 6
|
version: 6
|
||||||
cacheKey: 8c0
|
cacheKey: 8c0
|
||||||
|
|
||||||
"@alova/adapter-xhr@npm:^1.0.0":
|
"@alova/adapter-xhr@npm:^1.0.1":
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
resolution: "@alova/adapter-xhr@npm:1.0.0"
|
resolution: "@alova/adapter-xhr@npm:1.0.1"
|
||||||
checksum: 87c8be0cbb4a110921811cd1d772b18d59c220d286aaae8f70977f4116422f5692b1fcacd7d6914134a62c0111ee8f9406ac99048186a648034a3e457dcbf055
|
checksum: e423a583a3c7c14acab9a5019a34c545cf685e88de45525be6e373be40c688cfd639ea2b6e2522207629330dac74c52280faef0c511224c4213ada861c384da6
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@alova/scene-react@npm:^1.1.0":
|
"@alova/scene-react@npm:^1.1.3":
|
||||||
version: 1.1.0
|
version: 1.1.3
|
||||||
resolution: "@alova/scene-react@npm:1.1.0"
|
resolution: "@alova/scene-react@npm:1.1.3"
|
||||||
checksum: e1b956a5ea1f0b93f7e60896bb43aa124106e7b527dbdcd77cf200975b2b403240a91c050a43d43c083941f91f106d50ceb91dc0ef0a97feabd91a3945568b43
|
checksum: f318720b2dc0d85b5284cb352236000343f2399300ecee647b78d1ccb8d297e2a523394391eda04d4ab5d4a34e1ee411ad0547848530e35a8d362674685ff769
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1319,10 +1319,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/node@npm:^20.3.1":
|
"@types/mime-types@npm:^2":
|
||||||
version: 20.3.1
|
version: 2.1.1
|
||||||
resolution: "@types/node@npm:20.3.1"
|
resolution: "@types/mime-types@npm:2.1.1"
|
||||||
checksum: 7e8a6f5d6fc1ad3778f038f5f8df570741459984280fd2e9539af32620d93438c955fd1b90d00f9cc438cd132ec04d7669ada9e32502336e78713a3ad9b51d10
|
checksum: 131b33bfd89481f6a791996db9198c6c5ffccbb310e990d1dd9fab7a2287b5a0fd642bdd959a19281397c86f721498e09956e3892e5db17f93f38e726ca05008
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/node@npm:^20.3.2":
|
||||||
|
version: 20.3.2
|
||||||
|
resolution: "@types/node@npm:20.3.2"
|
||||||
|
checksum: d857cbe388d11fefd6c598144db42a32e1c15c09624b9e0669ec65e9d72e080093db3ec6b536037e6575574e33413479d4b3762140c2544ff30eb0c2111b5596
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1424,14 +1431,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@npm:^5.60.0":
|
"@typescript-eslint/eslint-plugin@npm:^5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/eslint-plugin@npm:5.60.0"
|
resolution: "@typescript-eslint/eslint-plugin@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/regexpp": ^4.4.0
|
"@eslint-community/regexpp": ^4.4.0
|
||||||
"@typescript-eslint/scope-manager": 5.60.0
|
"@typescript-eslint/scope-manager": 5.60.1
|
||||||
"@typescript-eslint/type-utils": 5.60.0
|
"@typescript-eslint/type-utils": 5.60.1
|
||||||
"@typescript-eslint/utils": 5.60.0
|
"@typescript-eslint/utils": 5.60.1
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
grapheme-splitter: ^1.0.4
|
grapheme-splitter: ^1.0.4
|
||||||
ignore: ^5.2.0
|
ignore: ^5.2.0
|
||||||
@@ -1444,43 +1451,43 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: e41d1a45f330e766afb594429fad535f4db06efc458e74cc05109c4555550efdad57141aa088d5cb836aeb90b822e08e7690e5b650fd7b2419da1d64113d5360
|
checksum: 1861e7fde48019ecae9acbc654d24f746e6a375f11f6f924e2ff3c9aa52528744a003da14592fafdbc407cf58b8cf7d0e42c624f3de06cb7bee5d8a31879ed79
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/parser@npm:^5.60.0":
|
"@typescript-eslint/parser@npm:^5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/parser@npm:5.60.0"
|
resolution: "@typescript-eslint/parser@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager": 5.60.0
|
"@typescript-eslint/scope-manager": 5.60.1
|
||||||
"@typescript-eslint/types": 5.60.0
|
"@typescript-eslint/types": 5.60.1
|
||||||
"@typescript-eslint/typescript-estree": 5.60.0
|
"@typescript-eslint/typescript-estree": 5.60.1
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: a9b4875a3ed37cfe8205173caf85b21f8025cf21bc295036c6265010ff622054b137fa7f3251476104086804bf55b420431efa887935b67c506800e3adcc8910
|
checksum: b44d041bb46908078df898ab1d8a0da0a58901caced0bb657af9d48c6bb54c090e565cc31d7526a27f25faeb25315fdec648873b2527feed043532a053914dd2
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@npm:5.60.0":
|
"@typescript-eslint/scope-manager@npm:5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/scope-manager@npm:5.60.0"
|
resolution: "@typescript-eslint/scope-manager@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": 5.60.0
|
"@typescript-eslint/types": 5.60.1
|
||||||
"@typescript-eslint/visitor-keys": 5.60.0
|
"@typescript-eslint/visitor-keys": 5.60.1
|
||||||
checksum: 87c742ea716359206244e1c7a8d2805b9e1caf04bce127f84b790046ae994849f25bf38af05de7a283eec58b34ecc701f441f23dfcccb59b9185260667bfe6e7
|
checksum: 50164675adb4850354a8e0297d498b59283eee961e10e0c00f9d664e03b464a9de4dc7a9d84c534c84df6ac3ea6f32238e2df9528374104bd66678b1ec9fbfec
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@npm:5.60.0":
|
"@typescript-eslint/type-utils@npm:5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/type-utils@npm:5.60.0"
|
resolution: "@typescript-eslint/type-utils@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/typescript-estree": 5.60.0
|
"@typescript-eslint/typescript-estree": 5.60.1
|
||||||
"@typescript-eslint/utils": 5.60.0
|
"@typescript-eslint/utils": 5.60.1
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
tsutils: ^3.21.0
|
tsutils: ^3.21.0
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1488,23 +1495,23 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 0baa4baa9c059e3a0d4da19cb62b821ababce781208cf18965e54916ea718a993d969f8f42b4356409ac1ce74228532e9d1cd0f2e9d3e0815c405467775b4015
|
checksum: ef07f5c84636b8a9ff68dbc093ba6bce32d0e0f56831b214c2df3ff189502ae103c73bda7eb5e9f9ca21d3492dc851b7ac4b2cb83bdd6fbf5a9fe21068b404f4
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/types@npm:5.60.0":
|
"@typescript-eslint/types@npm:5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/types@npm:5.60.0"
|
resolution: "@typescript-eslint/types@npm:5.60.1"
|
||||||
checksum: 008aedc2322120b9b760204ae26b5ecf5a1a61da84e77427048d076074cef703914a7a2db0286f891bbd045c1246238823671ec97192e03eabec35e9f75288e2
|
checksum: 4be7654356f9b79fb942ae22196b518f30e20b07588355df22c85dfdcdaafe02f312b473de67af34fbb2283182d0d337aa65312f1117c6f8bf635cc427944c23
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@npm:5.60.0":
|
"@typescript-eslint/typescript-estree@npm:5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/typescript-estree@npm:5.60.0"
|
resolution: "@typescript-eslint/typescript-estree@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": 5.60.0
|
"@typescript-eslint/types": 5.60.1
|
||||||
"@typescript-eslint/visitor-keys": 5.60.0
|
"@typescript-eslint/visitor-keys": 5.60.1
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
globby: ^11.1.0
|
globby: ^11.1.0
|
||||||
is-glob: ^4.0.3
|
is-glob: ^4.0.3
|
||||||
@@ -1513,35 +1520,35 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 83352afbd5b32a2c0d939ba17dc3420c0e72b5d920146b96af863acda675d4f307bb5b8cff25637761dfcba0cbe71c624307f45e2b87810798967b5af0798d43
|
checksum: 09933d3c1b1bacf7e043d33a7e134489650fca7b7b965b633a1c526453f20478b38c4aa9b7c6da269d2a43f26608110d4c129eec917c4561431149dae82c3b9d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/utils@npm:5.60.0":
|
"@typescript-eslint/utils@npm:5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/utils@npm:5.60.0"
|
resolution: "@typescript-eslint/utils@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/eslint-utils": ^4.2.0
|
"@eslint-community/eslint-utils": ^4.2.0
|
||||||
"@types/json-schema": ^7.0.9
|
"@types/json-schema": ^7.0.9
|
||||||
"@types/semver": ^7.3.12
|
"@types/semver": ^7.3.12
|
||||||
"@typescript-eslint/scope-manager": 5.60.0
|
"@typescript-eslint/scope-manager": 5.60.1
|
||||||
"@typescript-eslint/types": 5.60.0
|
"@typescript-eslint/types": 5.60.1
|
||||||
"@typescript-eslint/typescript-estree": 5.60.0
|
"@typescript-eslint/typescript-estree": 5.60.1
|
||||||
eslint-scope: ^5.1.1
|
eslint-scope: ^5.1.1
|
||||||
semver: ^7.3.7
|
semver: ^7.3.7
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
checksum: 00556a31fc288d2d59e85c139077c111ad2218ce817e24d02d9a50fb29c62293be7ab5200ae2a0cecce9c193a43519b690e9fd263bdc8bcef940eec005dc2bef
|
checksum: cb408bd67dd5be3a3585b67ac19f60e9feb309a56782924b314077f7dc77cb10e690fdb4a7ac643784e8fab30bc04d6f23935c1aed6d08233f8dd8604782ac27
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@npm:5.60.0":
|
"@typescript-eslint/visitor-keys@npm:5.60.1":
|
||||||
version: 5.60.0
|
version: 5.60.1
|
||||||
resolution: "@typescript-eslint/visitor-keys@npm:5.60.0"
|
resolution: "@typescript-eslint/visitor-keys@npm:5.60.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": 5.60.0
|
"@typescript-eslint/types": 5.60.1
|
||||||
eslint-visitor-keys: ^3.3.0
|
eslint-visitor-keys: ^3.3.0
|
||||||
checksum: 797888d1e9cfd42b92382443956f0a46d093c49bca2789699f638d79387f26c91c55b8545bfaba7b9b6d846efc6b1134df640c3975d51a8c3b57d8e6a837ab5b
|
checksum: e70bd584ff0eef1c8739e3457e7402485acc06aba468ff8f191f4546aaed93ec91f309bb567a3d8bbd9a4aec030f3b73c8e8df085bb82cbb8ea9a0209c7355f8
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1560,24 +1567,25 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "EMS-ESP@workspace:."
|
resolution: "EMS-ESP@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
"@alova/adapter-xhr": ^1.0.0
|
"@alova/adapter-xhr": ^1.0.1
|
||||||
"@alova/scene-react": ^1.1.0
|
"@alova/scene-react": ^1.1.3
|
||||||
"@emotion/react": ^11.11.1
|
"@emotion/react": ^11.11.1
|
||||||
"@emotion/styled": ^11.11.0
|
"@emotion/styled": ^11.11.0
|
||||||
"@mui/icons-material": ^5.11.16
|
"@mui/icons-material": ^5.11.16
|
||||||
"@mui/material": ^5.13.6
|
"@mui/material": ^5.13.6
|
||||||
"@table-library/react-table-library": 4.1.4
|
"@table-library/react-table-library": 4.1.4
|
||||||
"@types/lodash-es": ^4.17.7
|
"@types/lodash-es": ^4.17.7
|
||||||
"@types/node": ^20.3.1
|
"@types/mime-types": ^2
|
||||||
|
"@types/node": ^20.3.2
|
||||||
"@types/react": ^18.2.14
|
"@types/react": ^18.2.14
|
||||||
"@types/react-dom": ^18.2.6
|
"@types/react-dom": ^18.2.6
|
||||||
"@types/react-router-dom": ^5.3.3
|
"@types/react-router-dom": ^5.3.3
|
||||||
"@typescript-eslint/eslint-plugin": ^5.60.0
|
"@typescript-eslint/eslint-plugin": ^5.60.1
|
||||||
"@typescript-eslint/parser": ^5.60.0
|
"@typescript-eslint/parser": ^5.60.1
|
||||||
"@vitejs/plugin-react-swc": ^3.3.2
|
"@vitejs/plugin-react-swc": ^3.3.2
|
||||||
alova: ^2.6.2
|
alova: ^2.8.0
|
||||||
async-validator: ^4.2.5
|
async-validator: ^4.2.5
|
||||||
axios: ^1.4.0
|
dev: ^0.1.3
|
||||||
eslint: ^8.43.0
|
eslint: ^8.43.0
|
||||||
eslint-config-airbnb: ^19.0.4
|
eslint-config-airbnb: ^19.0.4
|
||||||
eslint-config-airbnb-typescript: ^17.0.0
|
eslint-config-airbnb-typescript: ^17.0.0
|
||||||
@@ -1592,6 +1600,7 @@ __metadata:
|
|||||||
history: ^5.3.0
|
history: ^5.3.0
|
||||||
jwt-decode: ^3.1.2
|
jwt-decode: ^3.1.2
|
||||||
lodash-es: ^4.17.21
|
lodash-es: ^4.17.21
|
||||||
|
mime-types: ^2.1.35
|
||||||
nodemon: ^2.0.22
|
nodemon: ^2.0.22
|
||||||
npm-run-all: ^4.1.5
|
npm-run-all: ^4.1.5
|
||||||
prettier: ^2.8.8
|
prettier: ^2.8.8
|
||||||
@@ -1603,9 +1612,9 @@ __metadata:
|
|||||||
react-toastify: ^9.1.3
|
react-toastify: ^9.1.3
|
||||||
rollup-plugin-visualizer: ^5.9.2
|
rollup-plugin-visualizer: ^5.9.2
|
||||||
sockette: ^2.0.6
|
sockette: ^2.0.6
|
||||||
terser: ^5.18.1
|
terser: ^5.18.2
|
||||||
typesafe-i18n: ^5.24.3
|
typesafe-i18n: ^5.24.3
|
||||||
typescript: ^5.1.3
|
typescript: ^5.1.6
|
||||||
vite: ^4.3.9
|
vite: ^4.3.9
|
||||||
vite-plugin-svgr: ^3.2.0
|
vite-plugin-svgr: ^3.2.0
|
||||||
vite-tsconfig-paths: ^4.2.0
|
vite-tsconfig-paths: ^4.2.0
|
||||||
@@ -1679,10 +1688,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"alova@npm:^2.6.2":
|
"alova@npm:^2.8.0":
|
||||||
version: 2.6.2
|
version: 2.8.0
|
||||||
resolution: "alova@npm:2.6.2"
|
resolution: "alova@npm:2.8.0"
|
||||||
checksum: ad9e6d7e1edb18e9f608440c6ad263d075326754ccc6c2e305a6088021007b7c52f8cedb403ec0788bef21545d324f41da5bb23aa6742a9a9ad6092e08ed88d3
|
checksum: 378da1832558947c0daa55483d91da4824a0d9f7461addf7bfe09689d4526f578460437ac9c7d1695da9680de35d3f52941ed2754d4240152b90e7b0ca876836
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1835,13 +1844,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"asynckit@npm:^0.4.0":
|
|
||||||
version: 0.4.0
|
|
||||||
resolution: "asynckit@npm:0.4.0"
|
|
||||||
checksum: d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"attr-accept@npm:^2.2.2":
|
"attr-accept@npm:^2.2.2":
|
||||||
version: 2.2.2
|
version: 2.2.2
|
||||||
resolution: "attr-accept@npm:2.2.2"
|
resolution: "attr-accept@npm:2.2.2"
|
||||||
@@ -1863,17 +1865,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"axios@npm:^1.4.0":
|
|
||||||
version: 1.4.0
|
|
||||||
resolution: "axios@npm:1.4.0"
|
|
||||||
dependencies:
|
|
||||||
follow-redirects: ^1.15.0
|
|
||||||
form-data: ^4.0.0
|
|
||||||
proxy-from-env: ^1.1.0
|
|
||||||
checksum: a925a07590b0ec1d4daf28cd27890f930daab980371558deb3b883af174b881da09e5ba2cb8393a648fda5859e39934982d0b8b092fe89fc84cb6c80a70a1910
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"axobject-query@npm:^3.1.1":
|
"axobject-query@npm:^3.1.1":
|
||||||
version: 3.1.1
|
version: 3.1.1
|
||||||
resolution: "axobject-query@npm:3.1.1"
|
resolution: "axobject-query@npm:3.1.1"
|
||||||
@@ -1908,6 +1899,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"bindings@npm:^1.3.1":
|
||||||
|
version: 1.5.0
|
||||||
|
resolution: "bindings@npm:1.5.0"
|
||||||
|
dependencies:
|
||||||
|
file-uri-to-path: 1.0.0
|
||||||
|
checksum: 3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"brace-expansion@npm:^1.1.7":
|
"brace-expansion@npm:^1.1.7":
|
||||||
version: 1.1.11
|
version: 1.1.11
|
||||||
resolution: "brace-expansion@npm:1.1.11"
|
resolution: "brace-expansion@npm:1.1.11"
|
||||||
@@ -2134,15 +2134,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"combined-stream@npm:^1.0.8":
|
|
||||||
version: 1.0.8
|
|
||||||
resolution: "combined-stream@npm:1.0.8"
|
|
||||||
dependencies:
|
|
||||||
delayed-stream: ~1.0.0
|
|
||||||
checksum: 0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"commander@npm:^2.20.0":
|
"commander@npm:^2.20.0":
|
||||||
version: 2.20.3
|
version: 2.20.3
|
||||||
resolution: "commander@npm:2.20.3"
|
resolution: "commander@npm:2.20.3"
|
||||||
@@ -2311,13 +2302,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"delayed-stream@npm:~1.0.0":
|
|
||||||
version: 1.0.0
|
|
||||||
resolution: "delayed-stream@npm:1.0.0"
|
|
||||||
checksum: d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"delegates@npm:^1.0.0":
|
"delegates@npm:^1.0.0":
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
resolution: "delegates@npm:1.0.0"
|
resolution: "delegates@npm:1.0.0"
|
||||||
@@ -2332,6 +2316,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"dev@npm:^0.1.3":
|
||||||
|
version: 0.1.3
|
||||||
|
resolution: "dev@npm:0.1.3"
|
||||||
|
dependencies:
|
||||||
|
inotify: ">= 0.1.6"
|
||||||
|
bin:
|
||||||
|
node-dev: ./node-dev.sh
|
||||||
|
checksum: 125fb02ab0e693b6f4863edf0304b5e6a37303e66a71795a8d14a96501764620910a4419280c1110fb7d896191ddd707647ea1145b28b6649abb607162a033bc
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"dir-glob@npm:^3.0.1":
|
"dir-glob@npm:^3.0.1":
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
resolution: "dir-glob@npm:3.0.1"
|
resolution: "dir-glob@npm:3.0.1"
|
||||||
@@ -3067,6 +3062,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"file-uri-to-path@npm:1.0.0":
|
||||||
|
version: 1.0.0
|
||||||
|
resolution: "file-uri-to-path@npm:1.0.0"
|
||||||
|
checksum: 3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"fill-range@npm:^7.0.1":
|
"fill-range@npm:^7.0.1":
|
||||||
version: 7.0.1
|
version: 7.0.1
|
||||||
resolution: "fill-range@npm:7.0.1"
|
resolution: "fill-range@npm:7.0.1"
|
||||||
@@ -3110,16 +3112,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"follow-redirects@npm:^1.15.0":
|
|
||||||
version: 1.15.2
|
|
||||||
resolution: "follow-redirects@npm:1.15.2"
|
|
||||||
peerDependenciesMeta:
|
|
||||||
debug:
|
|
||||||
optional: true
|
|
||||||
checksum: da5932b70e63944d38eecaa16954bac4347036f08303c913d166eda74809d8797d38386e3a0eb1d2fe37d2aaff2764cce8e9dbd99459d860cf2cdfa237923b5f
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"for-each@npm:^0.3.3":
|
"for-each@npm:^0.3.3":
|
||||||
version: 0.3.3
|
version: 0.3.3
|
||||||
resolution: "for-each@npm:0.3.3"
|
resolution: "for-each@npm:0.3.3"
|
||||||
@@ -3129,17 +3121,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"form-data@npm:^4.0.0":
|
|
||||||
version: 4.0.0
|
|
||||||
resolution: "form-data@npm:4.0.0"
|
|
||||||
dependencies:
|
|
||||||
asynckit: ^0.4.0
|
|
||||||
combined-stream: ^1.0.8
|
|
||||||
mime-types: ^2.1.12
|
|
||||||
checksum: cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0":
|
"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0":
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
resolution: "fs-minipass@npm:2.1.0"
|
resolution: "fs-minipass@npm:2.1.0"
|
||||||
@@ -3602,6 +3583,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"inotify@npm:>= 0.1.6":
|
||||||
|
version: 1.4.6
|
||||||
|
resolution: "inotify@npm:1.4.6"
|
||||||
|
dependencies:
|
||||||
|
bindings: ^1.3.1
|
||||||
|
nan: ^2.12.1
|
||||||
|
node-gyp: latest
|
||||||
|
checksum: 8415dbb54cd3ab8232951cdf1d91b1f0ca3c5925617a47d985e650ff3a038efb265acfff0f4f826db1ef1f2f484f516e3e7874d47d059015957818149d9d932e
|
||||||
|
conditions: os=linux
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5":
|
"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5":
|
||||||
version: 1.0.5
|
version: 1.0.5
|
||||||
resolution: "internal-slot@npm:1.0.5"
|
resolution: "internal-slot@npm:1.0.5"
|
||||||
@@ -4148,7 +4141,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"mime-types@npm:^2.1.12":
|
"mime-types@npm:^2.1.35":
|
||||||
version: 2.1.35
|
version: 2.1.35
|
||||||
resolution: "mime-types@npm:2.1.35"
|
resolution: "mime-types@npm:2.1.35"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4282,6 +4275,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"nan@npm:^2.12.1":
|
||||||
|
version: 2.17.0
|
||||||
|
resolution: "nan@npm:2.17.0"
|
||||||
|
dependencies:
|
||||||
|
node-gyp: latest
|
||||||
|
checksum: 4a231a62dba025f4c4fa814c1e6ffeb450c5cd0852b780f19fe4ea22b86ba0f1f394406dfd628c67fb7f0987e982fa230da1fbd3632258f927b8defd7046c1ad
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"nanoid@npm:^3.3.6":
|
"nanoid@npm:^3.3.6":
|
||||||
version: 3.3.6
|
version: 3.3.6
|
||||||
resolution: "nanoid@npm:3.3.6"
|
resolution: "nanoid@npm:3.3.6"
|
||||||
@@ -4763,13 +4765,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"proxy-from-env@npm:^1.1.0":
|
|
||||||
version: 1.1.0
|
|
||||||
resolution: "proxy-from-env@npm:1.1.0"
|
|
||||||
checksum: fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"pstree.remy@npm:^1.1.8":
|
"pstree.remy@npm:^1.1.8":
|
||||||
version: 1.1.8
|
version: 1.1.8
|
||||||
resolution: "pstree.remy@npm:1.1.8"
|
resolution: "pstree.remy@npm:1.1.8"
|
||||||
@@ -5568,9 +5563,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"terser@npm:^5.18.1":
|
"terser@npm:^5.18.2":
|
||||||
version: 5.18.1
|
version: 5.18.2
|
||||||
resolution: "terser@npm:5.18.1"
|
resolution: "terser@npm:5.18.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jridgewell/source-map": ^0.3.3
|
"@jridgewell/source-map": ^0.3.3
|
||||||
acorn: ^8.8.2
|
acorn: ^8.8.2
|
||||||
@@ -5578,7 +5573,7 @@ __metadata:
|
|||||||
source-map-support: ~0.5.20
|
source-map-support: ~0.5.20
|
||||||
bin:
|
bin:
|
||||||
terser: bin/terser
|
terser: bin/terser
|
||||||
checksum: f3ab58c6193f05cf4a4c06999dd95f23151542701782a3e91348828b184b7f54efebcbad3cc462b39b96b788a38936a4f6388edb022e9c696acf73af93692fdb
|
checksum: 7a7203eceef379c6381f5b43aaed509d12381c7453baee28b320fcd968523347f1bf4ba297cd3155ec860e9604279a1c9bc7060b35d9c34fae94c80cfa2738c2
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -5715,23 +5710,23 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@npm:^5.1.3":
|
"typescript@npm:^5.1.6":
|
||||||
version: 5.1.3
|
version: 5.1.6
|
||||||
resolution: "typescript@npm:5.1.3"
|
resolution: "typescript@npm:5.1.6"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
checksum: 1faba8d5ffd4717864ddce767613c5ab77c1c8510c1ce21dc9b112a4c662357b9338dc0a6121615266d3a44ebec699f115ef2dabf18d9d7341ea1675692b9b24
|
checksum: 45ac28e2df8365fd28dac42f5d62edfe69a7203d5ec646732cadc04065331f34f9078f81f150fde42ed9754eed6fa3b06a8f3523c40b821e557b727f1992e025
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@patch:typescript@^5.1.3#~builtin<compat/typescript>":
|
"typescript@patch:typescript@^5.1.6#~builtin<compat/typescript>":
|
||||||
version: 5.1.3
|
version: 5.1.6
|
||||||
resolution: "typescript@patch:typescript@npm%3A5.1.3#~builtin<compat/typescript>::version=5.1.3&hash=1f5320"
|
resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin<compat/typescript>::version=5.1.6&hash=1f5320"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
checksum: 6219383250b585b201c9ea10576164c9d5760c7a167bc761b118692c9fb8e88610f37730c0a1169d96ac19b29ed80418048763d0c1ff00ce48e051abbc213a9b
|
checksum: c134abcd9fc5c393db30498db18d8e89453efae14e11a39c1adb6238138d4c152472e497499b8a67b0c87ca6eafcb26b0eb02f962f240c233c2e0ad3785f8742
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"@msgpack/msgpack": "^2.8.0",
|
"@msgpack/msgpack": "^2.8.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
"nodemon": "^2.0.22"
|
"nodemon": "^2.0.22"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@3.4.1"
|
"packageManager": "yarn@3.4.1"
|
||||||
|
|||||||
@@ -2,17 +2,43 @@ const express = require('express');
|
|||||||
const compression = require('compression');
|
const compression = require('compression');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const msgpack = require('@msgpack/msgpack');
|
const msgpack = require('@msgpack/msgpack');
|
||||||
|
const multer = require('multer'); // https://www.npmjs.com/package/multer#readme
|
||||||
|
|
||||||
// REST API
|
// REST API
|
||||||
const rest_server = express();
|
const rest_server = express();
|
||||||
const port = 3080;
|
const port = 3080;
|
||||||
|
|
||||||
rest_server.use(compression());
|
rest_server.use(compression());
|
||||||
rest_server.use(express.static(path.join(__dirname, '../interface/build')));
|
// rest_server.use(express.static(path.join(__dirname, '../interface/build')));
|
||||||
rest_server.use(express.json());
|
// rest_server.use(express.json());
|
||||||
|
|
||||||
// FOR TESTING
|
// uploads
|
||||||
|
const upload = multer({ dest: '../mock-api/uploads' });
|
||||||
|
function progress_middleware(req, res, next) {
|
||||||
|
let progress = 0;
|
||||||
|
const file_size = req.headers['content-length'];
|
||||||
|
|
||||||
|
// set event listener
|
||||||
|
req.on('data', async (chunk) => {
|
||||||
|
progress += chunk.length;
|
||||||
|
const percentage = (progress / file_size) * 100;
|
||||||
|
console.log(`Progress: ${Math.round(percentage)}%`);
|
||||||
|
// await delay(1000); // slow it down
|
||||||
|
delay_blocking(200); // slow it down
|
||||||
|
});
|
||||||
|
next(); // invoke next middleware which is multer
|
||||||
|
}
|
||||||
|
|
||||||
|
// delays
|
||||||
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
||||||
|
function delay_blocking(milliseconds) {
|
||||||
|
var start = new Date().getTime();
|
||||||
|
for (var i = 0; i < 1e7; i++) {
|
||||||
|
if (new Date().getTime() - start > milliseconds) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// endpoints
|
// endpoints
|
||||||
const API_ENDPOINT_ROOT = '/api/';
|
const API_ENDPOINT_ROOT = '/api/';
|
||||||
@@ -2119,11 +2145,19 @@ rest_server.post(RESTART_ENDPOINT, async (req, res) => {
|
|||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
});
|
});
|
||||||
rest_server.post(FACTORY_RESET_ENDPOINT, (req, res) => {
|
rest_server.post(FACTORY_RESET_ENDPOINT, (req, res) => {
|
||||||
|
console.log('command: reset');
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
});
|
});
|
||||||
rest_server.post(UPLOAD_FILE_ENDPOINT, (req, res) => {
|
|
||||||
res.sendStatus(200);
|
rest_server.post(UPLOAD_FILE_ENDPOINT, progress_middleware, upload.single('file'), (req, res) => {
|
||||||
|
console.log('command: uploadFile completed.');
|
||||||
|
console.log(req.file);
|
||||||
|
if (req.file) {
|
||||||
|
return res.sendStatus(200);
|
||||||
|
}
|
||||||
|
return res.sendStatus(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
rest_server.post(SIGN_IN_ENDPOINT, (req, res) => {
|
rest_server.post(SIGN_IN_ENDPOINT, (req, res) => {
|
||||||
// res.sendStatus(401); // test bad user
|
// res.sendStatus(401); // test bad user
|
||||||
console.log('Signed in as ' + req.body.username);
|
console.log('Signed in as ' + req.body.username);
|
||||||
@@ -2669,7 +2703,7 @@ rest_server.get(SYSTEM_INFO_ENDPOINT, (req, res) => {
|
|||||||
|
|
||||||
const GET_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'getSettings';
|
const GET_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'getSettings';
|
||||||
rest_server.get(GET_SETTINGS_ENDPOINT, (req, res) => {
|
rest_server.get(GET_SETTINGS_ENDPOINT, (req, res) => {
|
||||||
console.log('getSettings:');
|
console.log('getSettings');
|
||||||
res.json(settings);
|
res.json(settings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
1
mock-api/uploads/README.md
Normal file
1
mock-api/uploads/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
leave empty
|
||||||
@@ -117,10 +117,18 @@ __metadata:
|
|||||||
"@msgpack/msgpack": ^2.8.0
|
"@msgpack/msgpack": ^2.8.0
|
||||||
compression: ^1.7.4
|
compression: ^1.7.4
|
||||||
express: ^4.18.2
|
express: ^4.18.2
|
||||||
|
multer: ^1.4.5-lts.1
|
||||||
nodemon: ^2.0.22
|
nodemon: ^2.0.22
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"append-field@npm:^1.0.0":
|
||||||
|
version: 1.0.0
|
||||||
|
resolution: "append-field@npm:1.0.0"
|
||||||
|
checksum: 482ba08acc0ecef00fe7da6bf2f8e48359a9905ee1af525f3120c9260c02e91eedf0579b59d898e8d8455b6c199e340bc0a2fd4b9e02adaa29a8a86c722b37f9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"aproba@npm:^1.0.3 || ^2.0.0":
|
"aproba@npm:^1.0.3 || ^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "aproba@npm:2.0.0"
|
resolution: "aproba@npm:2.0.0"
|
||||||
@@ -207,6 +215,22 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"buffer-from@npm:^1.0.0":
|
||||||
|
version: 1.1.2
|
||||||
|
resolution: "buffer-from@npm:1.1.2"
|
||||||
|
checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"busboy@npm:^1.0.0":
|
||||||
|
version: 1.6.0
|
||||||
|
resolution: "busboy@npm:1.6.0"
|
||||||
|
dependencies:
|
||||||
|
streamsearch: ^1.1.0
|
||||||
|
checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"bytes@npm:3.0.0":
|
"bytes@npm:3.0.0":
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
resolution: "bytes@npm:3.0.0"
|
resolution: "bytes@npm:3.0.0"
|
||||||
@@ -330,6 +354,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"concat-stream@npm:^1.5.2":
|
||||||
|
version: 1.6.2
|
||||||
|
resolution: "concat-stream@npm:1.6.2"
|
||||||
|
dependencies:
|
||||||
|
buffer-from: ^1.0.0
|
||||||
|
inherits: ^2.0.3
|
||||||
|
readable-stream: ^2.2.2
|
||||||
|
typedarray: ^0.0.6
|
||||||
|
checksum: 1ef77032cb4459dcd5187bd710d6fc962b067b64ec6a505810de3d2b8cc0605638551b42f8ec91edf6fcd26141b32ef19ad749239b58fae3aba99187adc32285
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"console-control-strings@npm:^1.1.0":
|
"console-control-strings@npm:^1.1.0":
|
||||||
version: 1.1.0
|
version: 1.1.0
|
||||||
resolution: "console-control-strings@npm:1.1.0"
|
resolution: "console-control-strings@npm:1.1.0"
|
||||||
@@ -367,6 +403,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"core-util-is@npm:~1.0.0":
|
||||||
|
version: 1.0.3
|
||||||
|
resolution: "core-util-is@npm:1.0.3"
|
||||||
|
checksum: 9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"debug@npm:2.6.9":
|
"debug@npm:2.6.9":
|
||||||
version: 2.6.9
|
version: 2.6.9
|
||||||
resolution: "debug@npm:2.6.9"
|
resolution: "debug@npm:2.6.9"
|
||||||
@@ -808,7 +851,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3":
|
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:~2.0.3":
|
||||||
version: 2.0.4
|
version: 2.0.4
|
||||||
resolution: "inherits@npm:2.0.4"
|
resolution: "inherits@npm:2.0.4"
|
||||||
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
|
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
|
||||||
@@ -875,6 +918,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"isarray@npm:~1.0.0":
|
||||||
|
version: 1.0.0
|
||||||
|
resolution: "isarray@npm:1.0.0"
|
||||||
|
checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"isexe@npm:^2.0.0":
|
"isexe@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "isexe@npm:2.0.0"
|
resolution: "isexe@npm:2.0.0"
|
||||||
@@ -986,6 +1036,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"minimist@npm:^1.2.6":
|
||||||
|
version: 1.2.8
|
||||||
|
resolution: "minimist@npm:1.2.8"
|
||||||
|
checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"minipass-collect@npm:^1.0.2":
|
"minipass-collect@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "minipass-collect@npm:1.0.2"
|
resolution: "minipass-collect@npm:1.0.2"
|
||||||
@@ -1063,6 +1120,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"mkdirp@npm:^0.5.4":
|
||||||
|
version: 0.5.6
|
||||||
|
resolution: "mkdirp@npm:0.5.6"
|
||||||
|
dependencies:
|
||||||
|
minimist: ^1.2.6
|
||||||
|
bin:
|
||||||
|
mkdirp: bin/cmd.js
|
||||||
|
checksum: 0c91b721bb12c3f9af4b77ebf73604baf350e64d80df91754dc509491ae93bf238581e59c7188360cec7cb62fc4100959245a42cfe01834efedc5e9d068376c2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
|
"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
|
||||||
version: 1.0.4
|
version: 1.0.4
|
||||||
resolution: "mkdirp@npm:1.0.4"
|
resolution: "mkdirp@npm:1.0.4"
|
||||||
@@ -1093,6 +1161,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"multer@npm:^1.4.5-lts.1":
|
||||||
|
version: 1.4.5-lts.1
|
||||||
|
resolution: "multer@npm:1.4.5-lts.1"
|
||||||
|
dependencies:
|
||||||
|
append-field: ^1.0.0
|
||||||
|
busboy: ^1.0.0
|
||||||
|
concat-stream: ^1.5.2
|
||||||
|
mkdirp: ^0.5.4
|
||||||
|
object-assign: ^4.1.1
|
||||||
|
type-is: ^1.6.4
|
||||||
|
xtend: ^4.0.0
|
||||||
|
checksum: d6dfa78a6ec592b74890412f8962da8a87a3dcfe20f612e039b735b8e0faa72c735516c447f7de694ee0d981eb0a1b892fb9e2402a0348dc6091d18c38d89ecc
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"negotiator@npm:0.6.3, negotiator@npm:^0.6.3":
|
"negotiator@npm:0.6.3, negotiator@npm:^0.6.3":
|
||||||
version: 0.6.3
|
version: 0.6.3
|
||||||
resolution: "negotiator@npm:0.6.3"
|
resolution: "negotiator@npm:0.6.3"
|
||||||
@@ -1181,6 +1264,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"object-assign@npm:^4.1.1":
|
||||||
|
version: 4.1.1
|
||||||
|
resolution: "object-assign@npm:4.1.1"
|
||||||
|
checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"object-inspect@npm:^1.9.0":
|
"object-inspect@npm:^1.9.0":
|
||||||
version: 1.12.3
|
version: 1.12.3
|
||||||
resolution: "object-inspect@npm:1.12.3"
|
resolution: "object-inspect@npm:1.12.3"
|
||||||
@@ -1250,6 +1340,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"process-nextick-args@npm:~2.0.0":
|
||||||
|
version: 2.0.1
|
||||||
|
resolution: "process-nextick-args@npm:2.0.1"
|
||||||
|
checksum: 1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"promise-inflight@npm:^1.0.1":
|
"promise-inflight@npm:^1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "promise-inflight@npm:1.0.1"
|
resolution: "promise-inflight@npm:1.0.1"
|
||||||
@@ -1312,6 +1409,21 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"readable-stream@npm:^2.2.2":
|
||||||
|
version: 2.3.8
|
||||||
|
resolution: "readable-stream@npm:2.3.8"
|
||||||
|
dependencies:
|
||||||
|
core-util-is: ~1.0.0
|
||||||
|
inherits: ~2.0.3
|
||||||
|
isarray: ~1.0.0
|
||||||
|
process-nextick-args: ~2.0.0
|
||||||
|
safe-buffer: ~5.1.1
|
||||||
|
string_decoder: ~1.1.1
|
||||||
|
util-deprecate: ~1.0.1
|
||||||
|
checksum: 65645467038704f0c8aaf026a72fbb588a9e2ef7a75cd57a01702ee9db1c4a1e4b03aaad36861a6a0926546a74d174149c8c207527963e0c2d3eee2f37678a42
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"readable-stream@npm:^3.6.0":
|
"readable-stream@npm:^3.6.0":
|
||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
resolution: "readable-stream@npm:3.6.0"
|
resolution: "readable-stream@npm:3.6.0"
|
||||||
@@ -1350,7 +1462,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"safe-buffer@npm:5.1.2":
|
"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1":
|
||||||
version: 5.1.2
|
version: 5.1.2
|
||||||
resolution: "safe-buffer@npm:5.1.2"
|
resolution: "safe-buffer@npm:5.1.2"
|
||||||
checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c
|
checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c
|
||||||
@@ -1518,6 +1630,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"streamsearch@npm:^1.1.0":
|
||||||
|
version: 1.1.0
|
||||||
|
resolution: "streamsearch@npm:1.1.0"
|
||||||
|
checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.2.3":
|
"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.2.3":
|
||||||
version: 4.2.3
|
version: 4.2.3
|
||||||
resolution: "string-width@npm:4.2.3"
|
resolution: "string-width@npm:4.2.3"
|
||||||
@@ -1538,6 +1657,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"string_decoder@npm:~1.1.1":
|
||||||
|
version: 1.1.1
|
||||||
|
resolution: "string_decoder@npm:1.1.1"
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: ~5.1.0
|
||||||
|
checksum: 9ab7e56f9d60a28f2be697419917c50cac19f3e8e6c28ef26ed5f4852289fe0de5d6997d29becf59028556f2c62983790c1d9ba1e2a3cc401768ca12d5183a5b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"strip-ansi@npm:^6.0.1":
|
"strip-ansi@npm:^6.0.1":
|
||||||
version: 6.0.1
|
version: 6.0.1
|
||||||
resolution: "strip-ansi@npm:6.0.1"
|
resolution: "strip-ansi@npm:6.0.1"
|
||||||
@@ -1597,7 +1725,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"type-is@npm:~1.6.18":
|
"type-is@npm:^1.6.4, type-is@npm:~1.6.18":
|
||||||
version: 1.6.18
|
version: 1.6.18
|
||||||
resolution: "type-is@npm:1.6.18"
|
resolution: "type-is@npm:1.6.18"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1607,6 +1735,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"typedarray@npm:^0.0.6":
|
||||||
|
version: 0.0.6
|
||||||
|
resolution: "typedarray@npm:0.0.6"
|
||||||
|
checksum: 33b39f3d0e8463985eeaeeacc3cb2e28bc3dfaf2a5ed219628c0b629d5d7b810b0eb2165f9f607c34871d5daa92ba1dc69f49051cf7d578b4cbd26c340b9d1b1
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"undefsafe@npm:^2.0.5":
|
"undefsafe@npm:^2.0.5":
|
||||||
version: 2.0.5
|
version: 2.0.5
|
||||||
resolution: "undefsafe@npm:2.0.5"
|
resolution: "undefsafe@npm:2.0.5"
|
||||||
@@ -1639,7 +1774,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"util-deprecate@npm:^1.0.1":
|
"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "util-deprecate@npm:1.0.2"
|
resolution: "util-deprecate@npm:1.0.2"
|
||||||
checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
|
checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
|
||||||
@@ -1687,6 +1822,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"xtend@npm:^4.0.0":
|
||||||
|
version: 4.0.2
|
||||||
|
resolution: "xtend@npm:4.0.2"
|
||||||
|
checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"yallist@npm:^4.0.0":
|
"yallist@npm:^4.0.0":
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
resolution: "yallist@npm:4.0.0"
|
resolution: "yallist@npm:4.0.0"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define EMSESP_APP_VERSION "3.6.0-dev.13"
|
#define EMSESP_APP_VERSION "3.6.0-dev.13a"
|
||||||
|
|||||||
Reference in New Issue
Block a user