TF-102 Add network config

This commit is contained in:
AmirHossein Mahmoodi
2023-09-27 10:15:01 +03:30
parent f07c5c1b15
commit 67e1801bb5
6 changed files with 176 additions and 77 deletions

View File

@@ -15,6 +15,8 @@
"Resend_code_in": "ارسال مجدد کد در",
"seconds_later": "ثانیه دیگر",
"upload_file_text": "بارگذاری فایل",
"online_message": "شما به اینترنت وصل هستید",
"offline_message": "اتصال شما به اینترنت قطع شده است",
"header": {
"open_profile": "پروفایل",
"edit_profile": "ویرایش پروفایل",

View File

@@ -0,0 +1,58 @@
import Head from "next/head";
const GlobalHead = () => {
return (
<Head>
<meta
name="application-name"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta
name="apple-mobile-web-app-title"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="description" content="Marhaba does it for you"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="format-detection" content="date=no"/>
<meta name="format-detection" content="address=no"/>
<meta name="format-detection" content="email=no"/>
<meta name="mobile-web-app-capable" content="yes"/>
<link rel="apple-touch-icon" href="/icons/maskable_icon_x512.png"/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/icons/maskable_icon_x128.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/maskable_icon_x192.png"
/>
<meta name="google" content="notranslate"/>
<meta name="robots" content="noindex"/>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
/>
<link
rel="icon"
type="image/svg"
sizes="32x32"
href="/icons/favicon.png"
/>
<link
rel="icon"
type="image/svg"
sizes="16x16"
href="/icons/favicon.png"
/>
</Head>
)
}
export default GlobalHead

View File

@@ -0,0 +1,34 @@
import useNetwork from "@/lib/app/hooks/useNetwork";
import {useEffect, useRef} from "react";
import {toast} from "react-toastify";
import WifiIcon from '@mui/icons-material/Wifi';
import WifiOffIcon from '@mui/icons-material/WifiOff';
import {useTranslations} from "next-intl";
const NetworkComponent = () => {
const toastId = useRef(null);
const network = useNetwork()
const t = useTranslations()
useEffect(() => {
if (network.online) {
toast.update(toastId.current, {
type: toast.TYPE.SUCCESS,
render: t('online_message'),
autoClose: 2000,
closeButton: true,
closeOnClick: true,
icon: <WifiIcon/>
});
return
}
toast.dismiss()
toastId.current = toast.warn(t('offline_message'), {
autoClose: false, closeButton: false, closeOnClick: false, icon: <WifiOffIcon/>
})
}, [network.online]);
return ''
}
export default NetworkComponent

View File

@@ -2,12 +2,13 @@ import theme from "@/core/utils/theme";
import useLanguage from "@/lib/app/hooks/useLanguage";
import useLoading from "@/lib/app/hooks/useLoading";
import useUser from "@/lib/app/hooks/useUser";
import Head from "next/head";
import NextNProgress from "nextjs-progressbar";
import {useEffect} from "react";
import {ToastContainer} from "react-toastify";
import useDirection from "@/lib/app/hooks/useDirection";
import "react-toastify/dist/ReactToastify.css";
import NetworkComponent from "@/core/components/NetworkComponent";
import GlobalHead from "@/core/components/GlobalHead";
function AppLayout({children, isBot}) {
const {languageIsReady} = useLanguage();
@@ -40,66 +41,16 @@ function AppLayout({children, isBot}) {
if (!languageIsReady) return;
}
return (
<>
<Head>
<meta
name="application-name"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
<meta
name="apple-mobile-web-app-title"
content={process.env.NEXT_PUBLIC_API_NAME}
/>
<meta name="description" content="Marhaba does it for you"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="format-detection" content="date=no"/>
<meta name="format-detection" content="address=no"/>
<meta name="format-detection" content="email=no"/>
<meta name="mobile-web-app-capable" content="yes"/>
<link rel="apple-touch-icon" href="/icons/maskable_icon_x512.png"/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/icons/maskable_icon_x128.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/maskable_icon_x192.png"
/>
<meta name="google" content="notranslate"/>
<meta name="robots" content="noindex"/>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
/>
<link
rel="icon"
type="image/svg"
sizes="32x32"
href="/images/logo.png"
/>
<link
rel="icon"
type="image/svg"
sizes="16x16"
href="/images/logo.png"
/>
</Head>
<NextNProgress
color={theme.palette.secondary.dark}
options={{showSpinner: false}}
/>
<ToastContainer position={directionApp === "ltr" ? "top-left" : "top-right"} rtl={directionApp === 'rtl'}/>
{children}
</>
);
return (<>
<GlobalHead/>
<NextNProgress
color={theme.palette.secondary.dark}
options={{showSpinner: false}}
/>
<ToastContainer position={directionApp === "ltr" ? "top-left" : "top-right"} rtl={directionApp === 'rtl'}/>
<NetworkComponent/>
{children}
</>);
}
export default AppLayout;
export default AppLayout;

View File

@@ -0,0 +1,58 @@
import {useEffect, useState} from "react";
function getNetworkConnection() {
return (
navigator.connection ||
navigator.mozConnection ||
navigator.webkitConnection ||
null
);
}
function getNetworkConnectionInfo() {
const connection = getNetworkConnection();
if (!connection) {
return {};
}
return {
rtt: connection.rtt,
type: connection.type,
saveData: connection.saveData,
downLink: connection.downLink,
downLinkMax: connection.downLinkMax,
effectiveType: connection.effectiveType,
};
}
function useNetwork() {
const [state, setState] = useState(() => {
return {
online: navigator.onLine,
};
});
useEffect(() => {
const handleOnline = () => {
setState((prevState) => ({
...prevState,
online: true,
}));
};
const handleOffline = () => {
setState((prevState) => ({
...prevState,
online: false,
}));
};
window.addEventListener("online", handleOnline);
window.addEventListener("offline", handleOffline);
return () => {
window.removeEventListener("online", handleOnline);
window.removeEventListener("offline", handleOffline);
};
}, []);
return state;
}
export default useNetwork;

View File

@@ -4,27 +4,23 @@ import PendingNotification from "@/core/components/notifications/PendingNotifica
import {useTranslations} from "next-intl";
import useUser from "@/lib/app/hooks/useUser";
import {errorRequest, errorResponse, errorSetting} from "@/core/utils/errorHandler";
import useNetwork from "@/lib/app/hooks/useNetwork";
const defaultOptions = {
auth: false,
data: {},
requestOptions: {
auth: false, data: {}, requestOptions: {
headers: {}
},
notification: true,
pending: true,
success: {
}, notification: true, pending: true, success: {
notification: {
show: true,
},
},
failed: {
}, failed: {
notification: {
show: true,
},
},
}
const useRequest = (initOptions) => {
const network = useNetwork()
const t = useTranslations()
const {token, clearToken} = useUser()
let _options = {...defaultOptions, ...initOptions}
@@ -32,20 +28,20 @@ const useRequest = (initOptions) => {
function requestServer(url = '', method = 'get', options) {
_options = {..._options, ...options}
if (_options.auth) _options = {
..._options,
requestOptions: {
..._options, requestOptions: {
..._options.requestOptions,
headers: {..._options.requestOptions.headers, authorization: `Bearer ${token}`}
}
}
return new Promise((resolve, reject) => {
if (!network.online) {
reject()
return
}
if (_options.notification && _options.failed.notification.show && _options.pending) PendingNotification(t)
axios({
url: url,
method: method,
data: _options.data,
..._options.requestOptions
url: url, method: method, data: _options.data, ..._options.requestOptions
})
.then(response => {
successRequest(response, t, _options)