Update version check logic.

This commit is contained in:
Mike Cao 2020-09-29 21:22:08 -07:00
parent 57bb1cb655
commit 37cf2e3017
6 changed files with 58 additions and 42 deletions

View File

@ -1,21 +1,27 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import semver from 'semver';
import useVersion from 'hooks/useVersion';
import styles from './UpdateNotice.module.css';
import ButtonLayout from '../layout/ButtonLayout';
import Button from './Button';
import useForceUpdate from '../../hooks/useForceUpdate';
export default function UpdateNotice() {
const versions = useVersion();
const forceUpdte = useForceUpdate();
const { hasUpdate, latest, updateCheck } = useVersion();
if (!versions) {
return null;
function handleViewClick() {
location.href = 'https://github.com/mikecao/umami/releases';
updateCheck();
forceUpdte();
}
const { current, latest } = versions;
function handleDismissClick() {
updateCheck();
forceUpdte();
}
if (latest && semver.gte(current, latest)) {
if (!hasUpdate) {
return null;
}
@ -29,10 +35,10 @@ export default function UpdateNotice() {
/>
</div>
<ButtonLayout>
<Button size="xsmall" variant="action">
<Button size="xsmall" variant="action" onClick={handleViewClick}>
<FormattedMessage id="button.view-details" defaultMessage="View details" />
</Button>
<Button size="xsmall">
<Button size="xsmall" onClick={handleDismissClick}>
<FormattedMessage id="button.dismiss" defaultMessage="Dismiss" />
</Button>
</ButtonLayout>

View File

@ -26,7 +26,7 @@ export default function Settings() {
{
label: <FormattedMessage id="label.accounts" defaultMessage="Accounts" />,
value: ACCOUNTS,
hidden: !user.is_admin,
hidden: !user?.is_admin,
},
{
label: <FormattedMessage id="label.profile" defaultMessage="Profile" />,

View File

@ -1,20 +1,27 @@
import { useEffect } from 'react';
import { useEffect, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getItem } from 'lib/web';
import semver from 'semver';
import { getItem, setItem } from 'lib/web';
import { checkVersion } from 'redux/actions/app';
const CHECK_INTERVAL = 24 * 60 * 60 * 1000;
import { VERSION_CHECK } from 'lib/constants';
export default function useVersion() {
const dispatch = useDispatch();
const versions = useSelector(state => state.app.versions);
const lastCheck = getItem(VERSION_CHECK);
const { current, latest } = versions;
const hasUpdate = latest && semver.gt(latest, current) && lastCheck?.version !== latest;
const updateCheck = useCallback(() => {
setItem(VERSION_CHECK, { version: latest, time: Date.now() });
}, [versions]);
useEffect(() => {
const lastCheck = getItem('umami.version-check');
if (!lastCheck || Date.now() - lastCheck > CHECK_INTERVAL) {
if (!versions.latest) {
dispatch(checkVersion());
}
}, []);
}, [versions]);
return versions;
return { ...versions, hasUpdate, updateCheck };
}

View File

@ -55,7 +55,7 @@
"message.get-tracking-code": "Get tracking code",
"message.go-to-settings": "Go to settings",
"message.incorrect-username-password": "Incorrect username/password.",
"message.new-version-available": "Version {latest} available! Current version: {current}",
"message.new-version-available": "A new version of umami {version} is available!",
"message.no-data-available": "No data available.",
"message.no-websites-configured": "You don't have any websites configured.",
"message.page-not-found": "Page not found.",

View File

@ -3,6 +3,7 @@ export const LOCALE_CONFIG = 'umami.locale';
export const TIMEZONE_CONFIG = 'umami.timezone';
export const DATE_RANGE_CONFIG = 'umami.date-range';
export const THEME_CONFIG = 'umami.theme';
export const VERSION_CHECK = 'umami.version-check';
export const THEME_COLORS = {
light: {

View File

@ -1,5 +1,5 @@
import { createSlice } from '@reduxjs/toolkit';
import { get, getItem } from 'lib/web';
import { getItem } from 'lib/web';
import { LOCALE_CONFIG, THEME_CONFIG } from 'lib/constants';
const app = createSlice({
@ -40,30 +40,32 @@ export function checkVersion() {
},
} = getState();
const data = await get('https://api.github.com/repos/mikecao/umami/releases/latest');
if (!data || !data['tag_name']) {
return;
}
const latest = data['tag_name'].startsWith('v') ? data['tag_name'].slice(1) : data['tag_name'];
if (latest === current) {
return;
}
const latestArray = latest.split('.');
const currentArray = current.split('.');
for (let i = 0; i < 3; i++) {
if (Number(latestArray[i]) > Number(currentArray[i])) {
return dispatch(
setVersions({
current,
latest: latest,
}),
);
const data = await fetch('https://api.github.com/repos/mikecao/umami/releases/latest', {
method: 'get',
headers: {
Accept: 'application/vnd.github.v3+json',
},
}).then(res => {
if (res.ok) {
return res.json();
}
return null;
});
if (!data) {
return;
}
const { tag_name } = data;
const latest = tag_name.startsWith('v') ? tag_name.slice(1) : tag_name;
return dispatch(
setVersions({
current,
latest,
}),
);
};
}