+ client: handle update
This commit is contained in:
parent
068072bc5a
commit
cb3f7f2834
|
@ -260,5 +260,7 @@
|
|||
"dns_addresses": "DNS addresses",
|
||||
"down": "Down",
|
||||
"fix": "Fix",
|
||||
"dns_providers": "Here is a <0>list of known DNS providers</0> to choose from."
|
||||
"dns_providers": "Here is a <0>list of known DNS providers</0> to choose from.",
|
||||
"update_now": "Update now",
|
||||
"processing_update": "Please wait, AdGuard Home is being updated"
|
||||
}
|
|
@ -4,7 +4,7 @@ import { t } from 'i18next';
|
|||
import { showLoading, hideLoading } from 'react-redux-loading-bar';
|
||||
|
||||
import { normalizeHistory, normalizeFilteringStatus, normalizeLogs, normalizeTextarea } from '../helpers/helpers';
|
||||
import { SETTINGS_NAMES } from '../helpers/constants';
|
||||
import { SETTINGS_NAMES, CHECK_TIMEOUT } from '../helpers/constants';
|
||||
import Api from '../api/Api';
|
||||
|
||||
const apiClient = new Api();
|
||||
|
@ -154,6 +154,29 @@ export const getVersion = () => async (dispatch) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const getUpdateRequest = createAction('GET_UPDATE_REQUEST');
|
||||
export const getUpdateFailure = createAction('GET_UPDATE_FAILURE');
|
||||
export const getUpdateSuccess = createAction('GET_UPDATE_SUCCESS');
|
||||
|
||||
export const getUpdate = () => async (dispatch) => {
|
||||
dispatch(getUpdateRequest());
|
||||
try {
|
||||
await apiClient.getUpdate();
|
||||
|
||||
const timer = setInterval(async () => {
|
||||
const dnsStatus = await apiClient.getGlobalStatus();
|
||||
if (dnsStatus) {
|
||||
clearInterval(timer);
|
||||
dispatch(getUpdateSuccess());
|
||||
window.location.reload(true);
|
||||
}
|
||||
}, CHECK_TIMEOUT);
|
||||
} catch (error) {
|
||||
dispatch(addErrorToast({ error }));
|
||||
dispatch(getUpdateFailure());
|
||||
}
|
||||
};
|
||||
|
||||
export const getClientsRequest = createAction('GET_CLIENTS_REQUEST');
|
||||
export const getClientsFailure = createAction('GET_CLIENTS_FAILURE');
|
||||
export const getClientsSuccess = createAction('GET_CLIENTS_SUCCESS');
|
||||
|
|
|
@ -40,6 +40,8 @@ export default class Api {
|
|||
GLOBAL_ENABLE_PROTECTION = { path: 'enable_protection', method: 'POST' };
|
||||
GLOBAL_DISABLE_PROTECTION = { path: 'disable_protection', method: 'POST' };
|
||||
GLOBAL_CLIENTS = { path: 'clients', method: 'GET' }
|
||||
GLOBAL_CLIENTS = { path: 'clients', method: 'GET' };
|
||||
GLOBAL_UPDATE = { path: 'update', method: 'POST' };
|
||||
|
||||
restartGlobalFiltering() {
|
||||
const { path, method } = this.GLOBAL_RESTART;
|
||||
|
@ -145,6 +147,11 @@ export default class Api {
|
|||
return this.makeRequest(path, method);
|
||||
}
|
||||
|
||||
getUpdate() {
|
||||
const { path, method } = this.GLOBAL_UPDATE;
|
||||
return this.makeRequest(path, method);
|
||||
}
|
||||
|
||||
// Filtering
|
||||
FILTERING_STATUS = { path: 'filtering/status', method: 'GET' };
|
||||
FILTERING_ENABLE = { path: 'filtering/enable', method: 'POST' };
|
||||
|
|
|
@ -19,6 +19,7 @@ import Toasts from '../Toasts';
|
|||
import Footer from '../ui/Footer';
|
||||
import Status from '../ui/Status';
|
||||
import UpdateTopline from '../ui/UpdateTopline';
|
||||
import UpdateOverlay from '../ui/UpdateOverlay';
|
||||
import EncryptionTopline from '../ui/EncryptionTopline';
|
||||
import i18n from '../../i18n';
|
||||
|
||||
|
@ -37,6 +38,10 @@ class App extends Component {
|
|||
this.props.enableDns();
|
||||
};
|
||||
|
||||
handleUpdate = () => {
|
||||
this.props.getUpdate();
|
||||
}
|
||||
|
||||
setLanguage = () => {
|
||||
const { processing, language } = this.props.dashboard;
|
||||
|
||||
|
@ -62,10 +67,16 @@ class App extends Component {
|
|||
<HashRouter hashType='noslash'>
|
||||
<Fragment>
|
||||
{updateAvailable &&
|
||||
<UpdateTopline
|
||||
url={dashboard.announcementUrl}
|
||||
version={dashboard.version}
|
||||
/>
|
||||
<Fragment>
|
||||
<UpdateTopline
|
||||
url={dashboard.announcementUrl}
|
||||
version={dashboard.newVersion}
|
||||
canAutoUpdate={dashboard.canAutoUpdate}
|
||||
getUpdate={this.handleUpdate}
|
||||
processingUpdate={dashboard.processingUpdate}
|
||||
/>
|
||||
<UpdateOverlay processingUpdate={dashboard.processingUpdate} />
|
||||
</Fragment>
|
||||
}
|
||||
{!encryption.processing &&
|
||||
<EncryptionTopline notAfter={encryption.not_after} />
|
||||
|
@ -100,6 +111,7 @@ class App extends Component {
|
|||
|
||||
App.propTypes = {
|
||||
getDnsStatus: PropTypes.func,
|
||||
getUpdate: PropTypes.func,
|
||||
enableDns: PropTypes.func,
|
||||
dashboard: PropTypes.object,
|
||||
isCoreRunning: PropTypes.bool,
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
.overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 110;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.overlay--visible {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.overlay__loading {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-bottom: 20px;
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2047.6%2047.6%22%20height%3D%22100%25%22%20width%3D%22100%25%22%3E%3Cpath%20opacity%3D%22.235%22%20fill%3D%22%23979797%22%20d%3D%22M44.4%2011.9l-5.2%203c1.5%202.6%202.4%205.6%202.4%208.9%200%209.8-8%2017.8-17.8%2017.8-6.6%200-12.3-3.6-15.4-8.9l-5.2%203C7.3%2042.8%2015%2047.6%2023.8%2047.6c13.1%200%2023.8-10.7%2023.8-23.8%200-4.3-1.2-8.4-3.2-11.9z%22%2F%3E%3Cpath%20fill%3D%22%2366b574%22%20d%3D%22M3.2%2035.7C0%2030.2-.8%2023.8.8%2017.6%202.5%2011.5%206.4%206.4%2011.9%203.2%2017.4%200%2023.8-.8%2030%20.8c6.1%201.6%2011.3%205.6%2014.4%2011.1l-5.2%203c-2.4-4.1-6.2-7.1-10.8-8.3C23.8%205.4%2019%206%2014.9%208.4s-7.1%206.2-8.3%2010.8c-1.2%204.6-.6%209.4%201.8%2013.5l-5.2%203z%22%2F%3E%3C%2Fsvg%3E");
|
||||
will-change: transform;
|
||||
animation: clockwise 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes clockwise {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import './Overlay.css';
|
||||
|
||||
const UpdateOverlay = (props) => {
|
||||
const overlayClass = classnames({
|
||||
overlay: true,
|
||||
'overlay--visible': props.processingUpdate,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={overlayClass}>
|
||||
<div className="overlay__loading"></div>
|
||||
<Trans>processing_update</Trans>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
UpdateOverlay.propTypes = {
|
||||
processingUpdate: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default withNamespaces()(UpdateOverlay);
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Trans, withNamespaces } from 'react-i18next';
|
||||
|
||||
|
@ -6,22 +6,37 @@ import Topline from './Topline';
|
|||
|
||||
const UpdateTopline = props => (
|
||||
<Topline type="info">
|
||||
<Trans
|
||||
values={{ version: props.version }}
|
||||
components={[
|
||||
<a href={props.url} target="_blank" rel="noopener noreferrer" key="0">
|
||||
Click here
|
||||
</a>,
|
||||
]}
|
||||
>
|
||||
update_announcement
|
||||
</Trans>
|
||||
<Fragment>
|
||||
<Trans
|
||||
values={{ version: props.version }}
|
||||
components={[
|
||||
<a href={props.url} target="_blank" rel="noopener noreferrer" key="0">
|
||||
Click here
|
||||
</a>,
|
||||
]}
|
||||
>
|
||||
update_announcement
|
||||
</Trans>
|
||||
{props.canAutoUpdate &&
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm btn-primary ml-3"
|
||||
onClick={props.getUpdate}
|
||||
disabled={props.processingUpdate}
|
||||
>
|
||||
<Trans>update_now</Trans>
|
||||
</button>
|
||||
}
|
||||
</Fragment>
|
||||
</Topline>
|
||||
);
|
||||
|
||||
UpdateTopline.propTypes = {
|
||||
version: PropTypes.string.isRequired,
|
||||
version: PropTypes.string,
|
||||
url: PropTypes.string.isRequired,
|
||||
canAutoUpdate: PropTypes.bool,
|
||||
getUpdate: PropTypes.func,
|
||||
processingUpdate: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default withNamespaces()(UpdateTopline);
|
||||
|
|
|
@ -126,12 +126,16 @@ const dashboard = handleActions({
|
|||
const {
|
||||
version,
|
||||
announcement_url: announcementUrl,
|
||||
new_version: newVersion,
|
||||
can_autoupdate: canAutoUpdate,
|
||||
} = payload;
|
||||
|
||||
const newState = {
|
||||
...state,
|
||||
version,
|
||||
announcementUrl,
|
||||
newVersion,
|
||||
canAutoUpdate,
|
||||
isUpdateAvailable: true,
|
||||
};
|
||||
return newState;
|
||||
|
@ -140,6 +144,13 @@ const dashboard = handleActions({
|
|||
return state;
|
||||
},
|
||||
|
||||
[actions.getUpdateRequest]: state => ({ ...state, processingUpdate: true }),
|
||||
[actions.getUpdateFailure]: state => ({ ...state, processingUpdate: false }),
|
||||
[actions.getUpdateSuccess]: (state) => {
|
||||
const newState = { ...state, processingUpdate: false };
|
||||
return newState;
|
||||
},
|
||||
|
||||
[actions.getFilteringRequest]: state => ({ ...state, processingFiltering: true }),
|
||||
[actions.getFilteringFailure]: state => ({ ...state, processingFiltering: false }),
|
||||
[actions.getFilteringSuccess]: (state, { payload }) => {
|
||||
|
@ -187,6 +198,7 @@ const dashboard = handleActions({
|
|||
processingVersion: true,
|
||||
processingFiltering: true,
|
||||
processingClients: true,
|
||||
processingUpdate: false,
|
||||
upstreamDns: '',
|
||||
bootstrapDns: '',
|
||||
allServers: false,
|
||||
|
|
Loading…
Reference in New Issue