Compare commits
7 Commits
1c760cb2a8
...
bugfix/fee
| Author | SHA1 | Date | |
|---|---|---|---|
| ac9b3cc1ea | |||
| 79e759d811 | |||
| b79fde777d | |||
| a8ef18d2b9 | |||
| 6a1d63d98a | |||
| 24ea41205f | |||
| 5b188747a5 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "in-car-system-fe",
|
"name": "in-car-system-fe",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.20",
|
"version": "1.0.23",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ const CameraSettingFields = ({
|
|||||||
onZoomLevelChange,
|
onZoomLevelChange,
|
||||||
}: CameraSettingsProps) => {
|
}: CameraSettingsProps) => {
|
||||||
const [showPwd, setShowPwd] = useState(false);
|
const [showPwd, setShowPwd] = useState(false);
|
||||||
|
|
||||||
const cameraControllerSide = initialData?.id === "CameraA" ? "CameraControllerA" : "CameraControllerB";
|
const cameraControllerSide = initialData?.id === "CameraA" ? "CameraControllerA" : "CameraControllerB";
|
||||||
const { mutation, query } = useCameraZoom({ camera: cameraControllerSide });
|
const { mutation, query } = useCameraZoom({ camera: cameraControllerSide });
|
||||||
const { cameraModeQuery, cameraModeMutation } = useCameraMode({ camera: cameraControllerSide });
|
const { cameraModeQuery, cameraModeMutation } = useCameraMode({ camera: cameraControllerSide });
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import { useSoundContext } from "../../../context/SoundContext";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useCameraBlackboard } from "../../../hooks/useCameraBlackboard";
|
import { useCameraBlackboard } from "../../../hooks/useCameraBlackboard";
|
||||||
import { useFileUpload } from "../../../hooks/useFileUpload";
|
import { useFileUpload } from "../../../hooks/useFileUpload";
|
||||||
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
const SoundUpload = () => {
|
const SoundUpload = () => {
|
||||||
const { state, dispatch } = useSoundContext();
|
const { state, dispatch } = useSoundContext();
|
||||||
const { mutation } = useCameraBlackboard();
|
const { mutation } = useCameraBlackboard();
|
||||||
const { mutation: fileMutation } = useFileUpload({
|
const currentUrlRef = useRef<string | null>(null);
|
||||||
queryKey: state.sightingSound ? [state.sightingSound] : undefined,
|
const { mutation: fileMutation } = useFileUpload();
|
||||||
});
|
|
||||||
|
|
||||||
const initialValues: SoundUploadValue = {
|
const initialValues: SoundUploadValue = {
|
||||||
name: "",
|
name: "",
|
||||||
@@ -43,6 +43,10 @@ const SoundUpload = () => {
|
|||||||
value: updatedValues,
|
value: updatedValues,
|
||||||
});
|
});
|
||||||
await fileMutation.mutateAsync(values.soundFile);
|
await fileMutation.mutateAsync(values.soundFile);
|
||||||
|
if (currentUrlRef.current) {
|
||||||
|
URL.revokeObjectURL(currentUrlRef.current);
|
||||||
|
currentUrlRef.current = null;
|
||||||
|
}
|
||||||
if (result.reason !== "OK") {
|
if (result.reason !== "OK") {
|
||||||
toast.error("Cannot update sound settings");
|
toast.error("Cannot update sound settings");
|
||||||
}
|
}
|
||||||
@@ -54,6 +58,14 @@ const SoundUpload = () => {
|
|||||||
dispatch({ type: "ADD", payload: values });
|
dispatch({ type: "ADD", payload: values });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (currentUrlRef.current) {
|
||||||
|
URL.revokeObjectURL(currentUrlRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik initialValues={initialValues} onSubmit={handleSubmit} enableReinitialize>
|
<Formik initialValues={initialValues} onSubmit={handleSubmit} enableReinitialize>
|
||||||
{({ setFieldValue, errors, setFieldError }) => (
|
{({ setFieldValue, errors, setFieldError }) => (
|
||||||
@@ -69,14 +81,26 @@ const SoundUpload = () => {
|
|||||||
accept="audio/mpeg"
|
accept="audio/mpeg"
|
||||||
className="mt-4 w-full flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5"
|
className="mt-4 w-full flex flex-col items-center justify-center rounded-2xl border border-slate-800 bg-slate-900/40 p-10 text-center file:px-3 file:border file:border-gray-500 file:rounded-lg file:bg-blue-800 file:mr-5"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (e.target?.files && e.target?.files[0]?.type === "audio/mpeg") {
|
if (currentUrlRef.current) {
|
||||||
const url = URL.createObjectURL(e.target.files[0]);
|
URL.revokeObjectURL(currentUrlRef.current);
|
||||||
|
}
|
||||||
|
const files = e.target?.files;
|
||||||
|
if (
|
||||||
|
files &&
|
||||||
|
(files[0]?.type === "audio/mp3" ||
|
||||||
|
files[0]?.type === "audio/mpeg" ||
|
||||||
|
files[0]?.name.endsWith(".wav"))
|
||||||
|
) {
|
||||||
|
const file = e.target?.files;
|
||||||
|
if(file === null) return;
|
||||||
|
currentUrlRef.current = URL.createObjectURL(file[0]);
|
||||||
|
const url = currentUrlRef.current;
|
||||||
setFieldValue("soundUrl", url);
|
setFieldValue("soundUrl", url);
|
||||||
setFieldValue("name", e.target.files[0].name);
|
setFieldValue("name", file[0].name);
|
||||||
setFieldValue("soundFileName", e.target.files[0].name);
|
setFieldValue("soundFileName", file[0].name);
|
||||||
setFieldValue("soundFile", e.target.files[0]);
|
setFieldValue("soundFile", file[0]);
|
||||||
setFieldValue("uploadedAt", Date.now());
|
setFieldValue("uploadedAt", Date.now());
|
||||||
if (e?.target?.files[0]?.size >= 1 * 1024 * 1024) {
|
if (file[0]?.size >= 1 * 1024 * 1024) {
|
||||||
setFieldError("soundFile", "larger than 1mb");
|
setFieldError("soundFile", "larger than 1mb");
|
||||||
toast.error("File larger than 1MB");
|
toast.error("File larger than 1MB");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -5,21 +5,38 @@ import { timezones } from "./timezones";
|
|||||||
import SystemFileUpload from "./SystemFileUpload";
|
import SystemFileUpload from "./SystemFileUpload";
|
||||||
import type { SystemValues, SystemValuesErrors } from "../../../types/types";
|
import type { SystemValues, SystemValuesErrors } from "../../../types/types";
|
||||||
import { useDNSSettings, useSystemConfig } from "../../../hooks/useSystemConfig";
|
import { useDNSSettings, useSystemConfig } from "../../../hooks/useSystemConfig";
|
||||||
import { ValidateIPaddress } from "../../../utils/utils";
|
import { ValidateIPaddress, isUtcOutOfSync } from "../../../utils/utils";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { useSystemStatus } from "../../../hooks/useSystemStatus";
|
||||||
|
|
||||||
const SystemConfigFields = () => {
|
const SystemConfigFields = () => {
|
||||||
const { saveSystemSettings, systemSettingsData, saveSystemSettingsLoading } = useSystemConfig();
|
const { saveSystemSettings, systemSettingsData, saveSystemSettingsLoading } = useSystemConfig();
|
||||||
|
const { systemStatusQuery } = useSystemStatus();
|
||||||
const { hardRebootMutation } = useReboots();
|
const { hardRebootMutation } = useReboots();
|
||||||
const { dnsQuery, dnsMutation } = useDNSSettings();
|
const { dnsQuery, dnsMutation } = useDNSSettings();
|
||||||
|
|
||||||
|
if (systemStatusQuery?.isLoading || !systemStatusQuery?.data) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
const utcTime = systemStatusQuery?.data?.SystemStatus?.utctime;
|
||||||
|
const localDate = systemStatusQuery?.data?.SystemStatus?.localdate;
|
||||||
|
const localTime = systemStatusQuery?.data?.SystemStatus?.localtime;
|
||||||
|
|
||||||
|
const utcOutOfSync = isUtcOutOfSync({
|
||||||
|
utctime: utcTime,
|
||||||
|
localdate: localDate,
|
||||||
|
localtime: localTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
const sntpInterval = systemSettingsData?.sntpInterval;
|
||||||
const dnsPrimary = dnsQuery?.data?.propNameServerPrimary?.value;
|
const dnsPrimary = dnsQuery?.data?.propNameServerPrimary?.value;
|
||||||
const dnsSecondary = dnsQuery?.data?.propNameServerSecondary?.value;
|
const dnsSecondary = dnsQuery?.data?.propNameServerSecondary?.value;
|
||||||
|
|
||||||
const initialvalues: SystemValues = {
|
const initialvalues: SystemValues = {
|
||||||
deviceName: systemSettingsData?.deviceName ?? "",
|
deviceName: systemSettingsData?.deviceName ?? "",
|
||||||
timeZone: systemSettingsData?.timeZone ?? "",
|
timeZone: systemSettingsData?.timeZone ?? "",
|
||||||
sntpServer: systemSettingsData?.sntpServer ?? "",
|
sntpServer: systemSettingsData?.sntpServer ?? "",
|
||||||
sntpInterval: systemSettingsData?.sntpInterval ?? 60,
|
sntpInterval: sntpInterval ?? 60,
|
||||||
serverPrimary: dnsPrimary ?? "",
|
serverPrimary: dnsPrimary ?? "",
|
||||||
serverSecondary: dnsSecondary ?? "",
|
serverSecondary: dnsSecondary ?? "",
|
||||||
softwareUpdate: null,
|
softwareUpdate: null,
|
||||||
@@ -67,6 +84,13 @@ const SystemConfigFields = () => {
|
|||||||
>
|
>
|
||||||
{({ values, errors, touched, isSubmitting }) => (
|
{({ values, errors, touched, isSubmitting }) => (
|
||||||
<Form className="flex flex-col space-y-5 px-2">
|
<Form className="flex flex-col space-y-5 px-2">
|
||||||
|
<div>
|
||||||
|
{utcOutOfSync?.outOfSync ? (
|
||||||
|
<span className="text-red-800 bg-red-300 border border-red-800 rounded-lg p-2">UTC is out of sync</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-green-300 bg-green-800 border border-green-600 rounded-lg p-2">UTC is in sync</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<label htmlFor="deviceName" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
<label htmlFor="deviceName" className="font-medium whitespace-nowrap md:w-1/2 text-left">
|
||||||
Device Name
|
Device Name
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useFormikContext } from "formik";
|
|||||||
import FormGroup from "../components/FormGroup";
|
import FormGroup from "../components/FormGroup";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useSystemConfig } from "../../../hooks/useSystemConfig";
|
import { useSystemConfig } from "../../../hooks/useSystemConfig";
|
||||||
|
import { CAM_BASE } from "../../../utils/config";
|
||||||
|
|
||||||
type SystemFileUploadProps = {
|
type SystemFileUploadProps = {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -19,7 +20,7 @@ const SystemFileUpload = ({ name, selectedFile }: SystemFileUploadProps) => {
|
|||||||
opts: {
|
opts: {
|
||||||
timeoutMs: 30000,
|
timeoutMs: 30000,
|
||||||
fieldName: "upload",
|
fieldName: "upload",
|
||||||
uploadUrl: "http://192.168.75.11/upload/software-update/2",
|
uploadUrl: `${CAM_BASE}/upload/software-update/4`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
uploadSettings(settings);
|
uploadSettings(settings);
|
||||||
|
|||||||
@@ -227,10 +227,6 @@ const SightingModal = ({ isSightingModalOpen, handleClose, sighting, onDelete }:
|
|||||||
<dt className="text-gray-300">Motion</dt>
|
<dt className="text-gray-300">Motion</dt>
|
||||||
<dd className="font-medium text-2xl ">{sighting?.motion ?? "-"}</dd>
|
<dd className="font-medium text-2xl ">{sighting?.motion ?? "-"}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<dt className="text-gray-300">Seen Count</dt>
|
|
||||||
<dd className="font-medium text-2xl">{sighting?.seenCount ?? "-"}</dd>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{sighting?.make && sighting.make.trim() && sighting.make.toLowerCase() !== "disabled" && (
|
{sighting?.make && sighting.make.trim() && sighting.make.toLowerCase() !== "disabled" && (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation } from "@tanstack/react-query";
|
||||||
import { CAM_BASE } from "../utils/config";
|
import { CAM_BASE } from "../utils/config";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { getOrCacheBlob } from "../utils/cacheSound";
|
|
||||||
const camBase = import.meta.env.MODE !== "development" ? CAM_BASE : CAM_BASE;
|
|
||||||
|
|
||||||
type UseFileUploadProps = {
|
const camBase = import.meta.env.MODE !== "development" ? CAM_BASE : CAM_BASE;
|
||||||
queryKey?: string[];
|
console.log(camBase);
|
||||||
};
|
|
||||||
|
|
||||||
const uploadFile = async (file: File) => {
|
const uploadFile = async (file: File) => {
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
@@ -21,19 +18,7 @@ const uploadFile = async (file: File) => {
|
|||||||
return response.text();
|
return response.text();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getUploadFiles = async ({ queryKey }: { queryKey: string[] }) => {
|
export const useFileUpload = () => {
|
||||||
const [, fileName] = queryKey;
|
|
||||||
const url = fileName;
|
|
||||||
return getOrCacheBlob(url);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFileUpload = ({ queryKey }: UseFileUploadProps) => {
|
|
||||||
const query = useQuery({
|
|
||||||
queryKey: ["getUploadFiles", ...(queryKey ?? [])],
|
|
||||||
queryFn: () => getUploadFiles({ queryKey: ["getUploadFiles", ...(queryKey ?? [])] }),
|
|
||||||
enabled: !!queryKey,
|
|
||||||
});
|
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: (file: File) => uploadFile(file),
|
mutationFn: (file: File) => uploadFile(file),
|
||||||
mutationKey: ["uploadFile"],
|
mutationKey: ["uploadFile"],
|
||||||
@@ -41,5 +26,5 @@ export const useFileUpload = ({ queryKey }: UseFileUploadProps) => {
|
|||||||
onSuccess: async (msg) => toast.success(msg),
|
onSuccess: async (msg) => toast.success(msg),
|
||||||
});
|
});
|
||||||
|
|
||||||
return { query: queryKey ? query : undefined, mutation };
|
return { mutation };
|
||||||
};
|
};
|
||||||
|
|||||||
22
src/hooks/useGetUploadedFiles.ts
Normal file
22
src/hooks/useGetUploadedFiles.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { getOrCacheBlob } from "../utils/cacheSound";
|
||||||
|
|
||||||
|
type UseFileUploadProps = {
|
||||||
|
queryKey?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUploadFiles = async ({ queryKey }: { queryKey: string[] }) => {
|
||||||
|
const [, fileName] = queryKey;
|
||||||
|
const url = fileName;
|
||||||
|
return getOrCacheBlob(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetUploadedFiles = ({ queryKey }: UseFileUploadProps) => {
|
||||||
|
const query = useQuery({
|
||||||
|
queryKey: ["getUploadFiles", ...(queryKey ?? [])],
|
||||||
|
queryFn: () => getUploadFiles({ queryKey: ["getUploadFiles", ...(queryKey ?? [])] }),
|
||||||
|
enabled: !!queryKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { query: queryKey ? query : undefined };
|
||||||
|
};
|
||||||
20
src/hooks/useSystemStatus.ts
Normal file
20
src/hooks/useSystemStatus.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { CAM_BASE } from "../utils/config";
|
||||||
|
|
||||||
|
const fetchSystemStatus = async () => {
|
||||||
|
const response = await fetch(`${CAM_BASE}/sysstatus?func=getstatus`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSystemStatus = () => {
|
||||||
|
const systemStatusQuery = useQuery({
|
||||||
|
queryKey: ["get systemStatus"],
|
||||||
|
queryFn: fetchSystemStatus,
|
||||||
|
refetchInterval: 60000,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { systemStatusQuery };
|
||||||
|
};
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { useFileUpload } from "./useFileUpload";
|
|
||||||
import { getSoundFileURL } from "../utils/utils";
|
import { getSoundFileURL } from "../utils/utils";
|
||||||
import type { SoundUploadValue } from "../types/types";
|
import type { SoundUploadValue } from "../types/types";
|
||||||
import { resolveSoundSource } from "../utils/soundResolver";
|
import { resolveSoundSource } from "../utils/soundResolver";
|
||||||
|
import { useGetUploadedFiles } from "./useGetUploadedFiles";
|
||||||
|
|
||||||
export function useCachedSoundSrc(
|
export function useCachedSoundSrc(
|
||||||
selected: string | undefined,
|
selected: string | undefined,
|
||||||
@@ -13,7 +13,7 @@ export function useCachedSoundSrc(
|
|||||||
|
|
||||||
const resolved = resolveSoundSource(selected, soundOptions);
|
const resolved = resolveSoundSource(selected, soundOptions);
|
||||||
|
|
||||||
const { query } = useFileUpload({
|
const { query } = useGetUploadedFiles({
|
||||||
queryKey: resolved?.type === "uploaded" ? [resolved?.url] : undefined,
|
queryKey: resolved?.type === "uploaded" ? [resolved?.url] : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
export async function getOrCacheBlob(url: string) {
|
export async function getOrCacheBlob(url: string) {
|
||||||
|
const cacheAvailable = typeof window !== "undefined" && "caches" in window;
|
||||||
|
|
||||||
|
if (!cacheAvailable) {
|
||||||
|
const res = await fetch(url, { cache: "no-store" });
|
||||||
|
if (!res.ok) throw new Error(`Fetch failed: ${res.status}`);
|
||||||
|
return await res.blob();
|
||||||
|
}
|
||||||
|
|
||||||
const cache = await caches.open("app-sounds-v1");
|
const cache = await caches.open("app-sounds-v1");
|
||||||
const hit = await cache.match(url);
|
const hit = await cache.match(url);
|
||||||
if (hit) return await hit.blob();
|
if (hit) return await hit.blob();
|
||||||
@@ -11,6 +19,11 @@ export async function getOrCacheBlob(url: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function evictFromCache(url: string) {
|
export async function evictFromCache(url: string) {
|
||||||
|
const cacheAvailable = typeof window !== "undefined" && "caches" in window;
|
||||||
|
|
||||||
|
if (!cacheAvailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const cache = await caches.open("app-sounds-v1");
|
const cache = await caches.open("app-sounds-v1");
|
||||||
await cache.delete(url);
|
await cache.delete(url);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const rawCamBase = import.meta.env.VITE_AGX_BOX_URL;
|
const rawCamBase = import.meta.env.VITE_CHRIS_BOX_URL;
|
||||||
const environment = import.meta.env.MODE;
|
const environment = import.meta.env.MODE;
|
||||||
|
|
||||||
export const CAM_BASE =
|
export const CAM_BASE = environment === "development" ? rawCamBase : window.location.origin;
|
||||||
environment === "development" ? rawCamBase : window.location.origin;
|
|
||||||
|
|||||||
@@ -197,3 +197,21 @@ export const ValidateIPaddress = (value: string | undefined) => {
|
|||||||
return "Invalid IP address format";
|
return "Invalid IP address format";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function isUtcOutOfSync(
|
||||||
|
data: {
|
||||||
|
utctime: number;
|
||||||
|
localdate: string;
|
||||||
|
localtime: string;
|
||||||
|
},
|
||||||
|
maxDriftMs = 60_000
|
||||||
|
) {
|
||||||
|
const utc = new Date(data.utctime);
|
||||||
|
|
||||||
|
const [d, m, y] = data.localdate.split("/").map(Number);
|
||||||
|
const [hh, mm, ss] = data.localtime.split(":").map(Number);
|
||||||
|
// Construct local Date in device’s local timezone
|
||||||
|
const local = new Date(y, m - 1, d, hh, mm, ss);
|
||||||
|
const driftMs = Math.abs(utc.getTime() - local.getTime() + utc.getTimezoneOffset() * 60_000);
|
||||||
|
return { driftMs, outOfSync: driftMs > maxDriftMs };
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export default defineConfig({
|
|||||||
host: true,
|
host: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
"/api": {
|
||||||
target: "http://100.118.196.113:8080",
|
target: "http://100.72.72.70:8080",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -40,3 +40,4 @@ export default defineConfig({
|
|||||||
__GIT_TIMESTAMP__: JSON.stringify(gitCommitTimeStamp),
|
__GIT_TIMESTAMP__: JSON.stringify(gitCommitTimeStamp),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
// Previous target: "http://100.118.196.113:8080",
|
||||||
|
|||||||
Reference in New Issue
Block a user