TF-102 Add network config
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
"Resend_code_in": "ارسال مجدد کد در",
|
||||
"seconds_later": "ثانیه دیگر",
|
||||
"upload_file_text": "بارگذاری فایل",
|
||||
"online_message": "شما به اینترنت وصل هستید",
|
||||
"offline_message": "اتصال شما به اینترنت قطع شده است",
|
||||
"header": {
|
||||
"open_profile": "پروفایل",
|
||||
"edit_profile": "ویرایش پروفایل",
|
||||
|
||||
58
src/core/components/GlobalHead.jsx
Normal file
58
src/core/components/GlobalHead.jsx
Normal 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
|
||||
34
src/core/components/NetworkComponent.jsx
Normal file
34
src/core/components/NetworkComponent.jsx
Normal 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
|
||||
@@ -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;
|
||||
58
src/lib/app/hooks/useNetwork.jsx
Normal file
58
src/lib/app/hooks/useNetwork.jsx
Normal 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;
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user