IO-2733 Added countdown timer to PWA Refresh & cache busting meta.
This commit is contained in:
@@ -226,7 +226,9 @@ jobs:
|
||||
command: |
|
||||
curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash
|
||||
hasura migrate apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||
sleep 5
|
||||
hasura metadata apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||
sleep 10
|
||||
hasura metadata reload --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||
- jira/notify:
|
||||
environment: Test (Rome) - Hasura
|
||||
@@ -313,7 +315,9 @@ jobs:
|
||||
command: |
|
||||
curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash
|
||||
hasura migrate apply --endpoint https://db.test.bodyshop.app/ --admin-secret << parameters.secret >>
|
||||
sleep 5
|
||||
hasura metadata apply --endpoint https://db.test.bodyshop.app/ --admin-secret << parameters.secret >>
|
||||
sleep 10
|
||||
hasura metadata reload --endpoint https://db.test.bodyshop.app/ --admin-secret << parameters.secret >>
|
||||
- jira/notify:
|
||||
environment: Test (ImEX) - Hasura
|
||||
@@ -433,7 +437,7 @@ workflows:
|
||||
branches:
|
||||
only: master-AIO
|
||||
- rome-hasura-migrate:
|
||||
secret: ${HASURA_PROD_SECRET}
|
||||
secret: ${HASURA_ROME_PROD_SECRET}
|
||||
filters:
|
||||
branches:
|
||||
only: master-AIO
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,9 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<% if (env.VITE_APP_INSTANCE === 'IMEX') { %>
|
||||
<link rel="icon" href="/favicon.png"/>
|
||||
<% } %> <% if (env.VITE_APP_INSTANCE === 'ROME') { %>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { AlertOutlined } from "@ant-design/icons";
|
||||
import { Alert, Button, Col, Row, Space } from "antd";
|
||||
import { Alert, Button, Col, notification, Row, Space } from "antd";
|
||||
import i18n from "i18next";
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectUpdateAvailable } from "../../redux/application/application.selectors";
|
||||
import { useRegisterSW } from "virtual:pwa-register/react";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import useCountDown from "../../utils/countdownHook";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
updateAvailable: selectUpdateAvailable
|
||||
@@ -19,6 +20,13 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
export function UpdateAlert({ updateAvailable }) {
|
||||
const { t } = useTranslation();
|
||||
const [
|
||||
timeLeft,
|
||||
{
|
||||
start //pause, resume, reset
|
||||
}
|
||||
] = useCountDown(180000, 1000);
|
||||
|
||||
const {
|
||||
offlineReady: [offlineReady],
|
||||
needRefresh: [needRefresh],
|
||||
@@ -40,11 +48,41 @@ export function UpdateAlert({ updateAvailable }) {
|
||||
}
|
||||
});
|
||||
|
||||
const ReloadNewVersion = useCallback(() => {
|
||||
updateServiceWorker(true);
|
||||
setTimeout(() => {
|
||||
window.location.reload(true);
|
||||
}, 2000);
|
||||
}, [updateServiceWorker]);
|
||||
|
||||
useEffect(() => {
|
||||
if (import.meta.env.DEV) {
|
||||
console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`);
|
||||
if (needRefresh) {
|
||||
start();
|
||||
}
|
||||
}, [needRefresh, offlineReady]);
|
||||
}, [start, needRefresh, offlineReady]);
|
||||
|
||||
useEffect(() => {
|
||||
if (needRefresh && timeLeft < 60000) {
|
||||
notification.open({
|
||||
type: "warning",
|
||||
closable: false,
|
||||
duration: 65000,
|
||||
key: "autoupdate",
|
||||
message: t("general.actions.autoupdate", {
|
||||
time: (timeLeft / 1000).toFixed(0),
|
||||
app: InstanceRenderManager({
|
||||
imex: "$t(titles.imexonline)",
|
||||
rome: "$t(titles.romeonline)",
|
||||
promanager: "$t(titles.promanager)"
|
||||
})
|
||||
}),
|
||||
placement: "bottomRight"
|
||||
});
|
||||
}
|
||||
if (needRefresh && timeLeft <= 0) {
|
||||
ReloadNewVersion();
|
||||
}
|
||||
}, [timeLeft, t, needRefresh, ReloadNewVersion]);
|
||||
|
||||
if (!needRefresh) return null;
|
||||
|
||||
@@ -75,9 +113,10 @@ export function UpdateAlert({ updateAvailable }) {
|
||||
<Button onClick={() => window.open("https://imex-online.noticeable.news/", "_blank")}>
|
||||
{i18n.t("general.actions.viewreleasenotes")}
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => updateServiceWorker(true)}>
|
||||
{i18n.t("general.actions.refresh")}
|
||||
<Button type="primary" onClick={() => ReloadNewVersion()}>
|
||||
{i18n.t("general.actions.refresh")} {`(${(timeLeft / 1000).toFixed(0)} s)`}
|
||||
</Button>
|
||||
<Button onClick={() => start(300000)}>{i18n.t("general.actions.delay")}</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
84
client/src/utils/countdownHook.js
Normal file
84
client/src/utils/countdownHook.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import React from "react";
|
||||
|
||||
const useCountDown = (timeToCount = 60 * 1000, interval = 1000) => {
|
||||
const [timeLeft, setTimeLeft] = React.useState(0);
|
||||
const timer = React.useRef({});
|
||||
|
||||
const run = (ts) => {
|
||||
if (!timer.current.started) {
|
||||
timer.current.started = ts;
|
||||
timer.current.lastInterval = ts;
|
||||
}
|
||||
|
||||
const localInterval = Math.min(interval, timer.current.timeLeft || Infinity);
|
||||
if (ts - timer.current.lastInterval >= localInterval) {
|
||||
timer.current.lastInterval += localInterval;
|
||||
setTimeLeft((timeLeft) => {
|
||||
timer.current.timeLeft = timeLeft - localInterval;
|
||||
return timer.current.timeLeft;
|
||||
});
|
||||
}
|
||||
|
||||
if (ts - timer.current.started < timer.current.timeToCount) {
|
||||
timer.current.requestId = window.requestAnimationFrame(run);
|
||||
} else {
|
||||
timer.current = {};
|
||||
setTimeLeft(0);
|
||||
}
|
||||
};
|
||||
|
||||
const start = React.useCallback(
|
||||
(ttc) => {
|
||||
window.cancelAnimationFrame(timer.current.requestId);
|
||||
|
||||
const newTimeToCount = ttc !== undefined ? ttc : timeToCount;
|
||||
timer.current.started = null;
|
||||
timer.current.lastInterval = null;
|
||||
timer.current.timeToCount = newTimeToCount;
|
||||
timer.current.requestId = window.requestAnimationFrame(run);
|
||||
|
||||
setTimeLeft(newTimeToCount);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
);
|
||||
|
||||
const pause = React.useCallback(() => {
|
||||
window.cancelAnimationFrame(timer.current.requestId);
|
||||
timer.current.started = null;
|
||||
timer.current.lastInterval = null;
|
||||
timer.current.timeToCount = timer.current.timeLeft;
|
||||
}, []);
|
||||
|
||||
const resume = React.useCallback(
|
||||
() => {
|
||||
if (!timer.current.started && timer.current.timeLeft > 0) {
|
||||
window.cancelAnimationFrame(timer.current.requestId);
|
||||
timer.current.requestId = window.requestAnimationFrame(run);
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
);
|
||||
|
||||
const reset = React.useCallback(() => {
|
||||
if (timer.current.timeLeft) {
|
||||
window.cancelAnimationFrame(timer.current.requestId);
|
||||
timer.current = {};
|
||||
setTimeLeft(0);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const actions = React.useMemo(
|
||||
() => ({ start, pause, resume, reset }), // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => window.cancelAnimationFrame(timer.current.requestId);
|
||||
}, []);
|
||||
|
||||
return [timeLeft, actions];
|
||||
};
|
||||
|
||||
export default useCountDown;
|
||||
Reference in New Issue
Block a user