Skip to content

Commit

Permalink
feat(updates): display update details and add update and restart butt…
Browse files Browse the repository at this point in the history
…on (#1550)
  • Loading branch information
JPSchellenberg committed May 21, 2021
1 parent 7210e62 commit 6982907
Show file tree
Hide file tree
Showing 14 changed files with 407 additions and 48 deletions.
11 changes: 11 additions & 0 deletions client/src/state/Updates/UpdatesAPI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import superagent from 'superagent';

import { IUpdateInfo } from './UpdatesTypes';

export async function getUpdates(): Promise<IUpdateInfo> {
return (await superagent.get(`/api/v1/updates`)).body;
}

export async function update(): Promise<void> {
await superagent.post('api/v1/updates');
}
65 changes: 65 additions & 0 deletions client/src/state/Updates/UpdatesActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as Sentry from '@sentry/browser';

import {
UPDATES_GET_UPDATES_REQUEST,
UPDATES_GET_UPDATES_ERROR,
UPDATES_GET_UPDATES_SUCCESS,
UPDATES_UPDATE_REQUEST,
UPDATES_UPDATE_ERROR,
UPDATES_UPDATE_SUCCESS
} from './UpdatesTypes';

import * as API from './UpdatesAPI';

export function getUpdates(): any {
return async (dispatch: any) => {
try {
dispatch({
payload: {},
type: UPDATES_GET_UPDATES_REQUEST
});

try {
const updateInfo = await API.getUpdates();

dispatch({
payload: updateInfo,
type: UPDATES_GET_UPDATES_SUCCESS
});
return updateInfo;
} catch (error) {
Sentry.captureException(error);

dispatch({
payload: { error },
type: UPDATES_GET_UPDATES_ERROR
});
}
} catch (error) {}
};
}

export function update(): any {
return async (dispatch: any) => {
try {
dispatch({
type: UPDATES_UPDATE_REQUEST
});

try {
await API.update();

dispatch({
type: UPDATES_UPDATE_SUCCESS
});
} catch (error) {
Sentry.captureException(error);

dispatch({
payload: { error },
type: UPDATES_UPDATE_ERROR
});
}
} catch (error) {}
};
}
45 changes: 45 additions & 0 deletions client/src/state/Updates/UpdatesReducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as Sentry from '@sentry/browser';

import {
IUpdatesState,
IUpdatesActionTypes,
UPDATES_GET_UPDATES_SUCCESS
} from './UpdatesTypes';

export const initialState: IUpdatesState = {
updateAvailable: false,
checkingForUpdates: false,
updateInfo: {
version: '',
releaseName: '',
releaseNotes: '',
releaseDate: ''
},
downloadProgress: {
progress: 0,
bytesPersecond: 0,
percent: 0,
total: 0,
transferred: 0
}
};

export default function updatesReducer(
state: IUpdatesState = initialState,
action: IUpdatesActionTypes
): IUpdatesState {
try {
switch (action.type) {
case UPDATES_GET_UPDATES_SUCCESS:
return {
...state,
updateInfo: action.payload
};
default:
return state;
}
} catch (error) {
Sentry.captureException(error);
return state;
}
}
68 changes: 68 additions & 0 deletions client/src/state/Updates/UpdatesTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export interface IState {
updates: IUpdatesState;
}

export interface IUpdateInfo {
// derived from https://www.electron.build/auto-update#UpdateInfo
version: string;
releaseName: string;
releaseNotes: string;
releaseDate: string;
}

export interface IUpdatesState {
updateAvailable: boolean;
checkingForUpdates: boolean;
updateInfo: IUpdateInfo;
downloadProgress: {
// dervied from https://www.electron.build/auto-update#event-download-progress
progress: number;
bytesPersecond: number;
percent: number;
total: number;
transferred: number;
};
}

export const UPDATES_GET_UPDATES_REQUEST = 'UPDATES_GET_UPDATES_REQUEST';
export const UPDATES_GET_UPDATES_SUCCESS = 'UPDATES_GET_UPDATES_SUCCESS';
export const UPDATES_GET_UPDATES_ERROR = 'UPDATES_GET_UPDATES_ERROR';

export const UPDATES_UPDATE_REQUEST = 'UPDATES_UPDATE_REQUEST';
export const UPDATES_UPDATE_SUCCESS = 'UPADTES_UPDATE_SUCCESS';
export const UPDATES_UPDATE_ERROR = 'UPADTES_UPDATE_ERROR';

export interface IUpdateRequestAction {
type: typeof UPDATES_UPDATE_REQUEST;
}

export interface IUpdateSuccessAction {
type: typeof UPDATES_UPDATE_SUCCESS;
}
export interface IUpdateErrorAction {
type: typeof UPDATES_UPDATE_ERROR;
}

export interface IGetUpdatesRequestAction {
payload: {};
type: typeof UPDATES_GET_UPDATES_REQUEST;
}

export interface IGetUpdatesSuccessAction {
payload: IUpdateInfo;
type: typeof UPDATES_GET_UPDATES_SUCCESS;
}
export interface IGetUpdatesErrorAction {
payload: {
error: string;
};
type: typeof UPDATES_GET_UPDATES_ERROR;
}

export type IUpdatesActionTypes =
| IGetUpdatesRequestAction
| IGetUpdatesSuccessAction
| IGetUpdatesErrorAction
| IUpdateErrorAction
| IUpdateRequestAction
| IUpdateSuccessAction;
13 changes: 10 additions & 3 deletions client/src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import * as SystemTypes from './System/SystemTypes';
import SystemReducer from './System/SystemReducer';
import * as SystemActions from './System/SystemActions';

import * as UpdatesTypes from './Updates/UpdatesTypes';
import UpdatesReducer from './Updates/UpdatesReducer';
import * as UpdatesActions from './Updates/UpdatesActions';

import RunReducer from './Run/RunReducer';
import * as RunTypes from './Run/RunTypes';
import * as RunActions from './Run/RunActions';
Expand Down Expand Up @@ -53,7 +57,8 @@ const rootReducer = () =>
analytics: AnalyticsReducer,
run: RunReducer,
settings: SettingsReducer,
system: SystemReducer
system: SystemReducer,
updates: UpdatesReducer
});

const store = createStore(
Expand All @@ -68,15 +73,17 @@ export interface IState
AnalyticsTypes.IState,
SettingsTypes.IState,
RunTypes.IState,
SystemTypes.IState {}
SystemTypes.IState,
UpdatesTypes.IState {}

export const actions = {
notifications: NotificationsActions,
h5peditor: H5PEditorActions,
analytics: AnalyticsActions,
settings: SettingsActions,
run: RunActions,
system: SystemActions
system: SystemActions,
updates: UpdatesActions
};

export const selectors = {
Expand Down
6 changes: 4 additions & 2 deletions client/src/views/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import RunSetupDialogContainer from './container/RunSetupDialogContainer';
import RunUploadDialogContainer from './container/RunUploadDialogContainer';

import ErrorDialog from './components/ErrorDialog';

import { actions } from '../state';

const log = new Logger('container:app');
Expand All @@ -35,11 +34,14 @@ export default function AppContainer() {

useEffect(() => {
dispatch(actions.settings.getSettings()).then(
async (settings: { language: string }) => {
async (settings: { language: string; autoUpdates: boolean }) => {
if (settings?.language) {
await i18n.loadLanguages(settings.language);
i18n.changeLanguage(settings.language);
}
if (settings?.autoUpdates) {
dispatch(actions.updates.getUpdates());
}
}
);

Expand Down
22 changes: 18 additions & 4 deletions client/src/views/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Slide from '@material-ui/core/Slide';
import { TransitionProps } from '@material-ui/core/transitions';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';

import Badge from '@material-ui/core/Badge';
import Drawer from '@material-ui/core/Drawer';
import List from '@material-ui/core/List';
import Divider from '@material-ui/core/Divider';
Expand Down Expand Up @@ -107,6 +107,10 @@ export default function FullScreenDialog() {
(state: IState) => state.system.platformSupportsUpdates
);

const updateAvailable = useSelector(
(state: IState) => state.updates.updateInfo.releaseName !== ''
);

const [section, setSection] = React.useState('general');

const handleClickOpen = () => {
Expand All @@ -121,9 +125,19 @@ export default function FullScreenDialog() {

return (
<div>
<IconButton color="inherit" onClick={handleClickOpen}>
<SettingsIcon />
</IconButton>
<Badge
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left'
}}
color="secondary"
badgeContent={t('updates.badge')}
invisible={!updateAvailable}
>
<IconButton color="inherit" onClick={handleClickOpen}>
<SettingsIcon />
</IconButton>
</Badge>
<Dialog
fullScreen={true}
open={open}
Expand Down
Loading

0 comments on commit 6982907

Please sign in to comment.