diff --git a/components/common/UpdateNotice.js b/components/common/UpdateNotice.js index a0d5f512..13b0cb59 100644 --- a/components/common/UpdateNotice.js +++ b/components/common/UpdateNotice.js @@ -1,36 +1,41 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -import useVersion from '../../hooks/useVersion'; -import Link from '../common/Link'; +import semver from 'semver'; +import useVersion from 'hooks/useVersion'; import styles from './UpdateNotice.module.css'; +import ButtonLayout from '../layout/ButtonLayout'; +import Button from './Button'; export default function UpdateNotice() { const versions = useVersion(); - console.log(versions); - if (!versions) return null; + + if (!versions) { + return null; + } const { current, latest } = versions; + if (latest && semver.gte(current, latest)) { + return null; + } + return ( -
-
+
+
- -
- -
- + + + +
); } diff --git a/components/common/UpdateNotice.module.css b/components/common/UpdateNotice.module.css index ec3a113f..52a97c3b 100644 --- a/components/common/UpdateNotice.module.css +++ b/components/common/UpdateNotice.module.css @@ -1,15 +1,13 @@ -.wrapper { - width: 100%; +.notice { display: flex; - flex-wrap: wrap; justify-content: center; - font-size: var(--font-size-xsmall); -} -.heading { + align-items: center; + padding-top: 10px; + font-size: var(--font-size-small); font-weight: 600; - margin: auto 10px; } -.message, -.heading { - display: inline-block; + +.message { + text-align: center; + margin-right: 20px; } diff --git a/components/layout/Header.js b/components/layout/Header.js index 93b96715..c48fdd11 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -16,7 +16,7 @@ export default function Header() { return (
- {user && } + {user?.is_admin && }
diff --git a/hooks/useVersion.js b/hooks/useVersion.js index 76aefadc..52c53b5a 100644 --- a/hooks/useVersion.js +++ b/hooks/useVersion.js @@ -1,28 +1,20 @@ -import { useMemo } from 'react'; -import useFetch from 'hooks/useFetch'; +import { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { getItem } from 'lib/web'; +import { checkVersion } from 'redux/actions/app'; + +const CHECK_INTERVAL = 24 * 60 * 60 * 1000; export default function useVersion() { - const { data } = useMemo(() => - useFetch('https://api.github.com/repos/mikecao/umami/releases/latest'), - ); + const dispatch = useDispatch(); + const versions = useSelector(state => state.app.versions); - if (!data || !data['tag_name']) return null; + useEffect(() => { + const lastCheck = getItem('umami.version-check'); + if (!lastCheck || Date.now() - lastCheck > CHECK_INTERVAL) { + dispatch(checkVersion()); + } + }, []); - const latest = data['tag_name'].startsWith('v') ? data['tag_name'].slice(1) : data['tag_name']; - const current = process.env.VERSION; - - if (latest === current) return null; - - const latestArray = latest.split('.'); - const currentArray = current.split('.'); - - for (let i = 0; i < 3; i++) { - if (Number(latestArray[i]) > Number(currentArray[i])) - return { - current: current, - latest: latest, - }; - } - - return null; + return versions; } diff --git a/lang/da-DK.json b/lang/da-DK.json index c4940630..cd96cb3f 100644 --- a/lang/da-DK.json +++ b/lang/da-DK.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Kopier til udklipsholder", "button.date-range": "Datointerval", "button.delete": "Slet", + "button.dismiss": "Dismiss", "button.edit": "Rediger", "button.login": "Log ind", "button.more": "Mere", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Få sporingskode", "message.go-to-settings": "Gå til betjeningspanel", "message.incorrect-username-password": "Ugyldigt brugernavn/adgangskode.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Ingen data tilgængelig.", "message.no-websites-configured": "Du har ikke konfigureret nogen websteder.", "message.page-not-found": "Side ikke fundet.", diff --git a/lang/de-DE.json b/lang/de-DE.json index f7ef14fc..7c45d131 100644 --- a/lang/de-DE.json +++ b/lang/de-DE.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "In die Zwischenablage kopieren", "button.date-range": "Datumsbereich", "button.delete": "Löschen", + "button.dismiss": "Dismiss", "button.edit": "Bearbeiten", "button.login": "Anmelden", "button.more": "Mehr", @@ -54,7 +55,7 @@ "message.get-tracking-code": "Erstelle Tracking Kennung", "message.go-to-settings": "Zu den Einstellungen", "message.incorrect-username-password": "Falsches Passwort oder Benutzername.", - "message.new-version-available": "Version {latest} ist verfügbar! Aktuelle Version: {current}", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Keine Daten vorhanden.", "message.no-websites-configured": "Es ist keine Webseite vorhanden.", "message.page-not-found": "Seite nicht gefunden.", @@ -63,7 +64,6 @@ "message.share-url": "Dies ist der öffentliche URL zum Teilen für {target}.", "message.track-stats": "Um die Statistiken für {target} zu übermitteln, platzieren Sie bitte den folgenden Quelltext im {head} ihrer Homepage.", "message.type-delete": "Geben Sie {delete} in das Feld unten ein um zu bestätigen.", - "message.visit-github-update": "Klicken Sie hier um umami auf GitHub zu besuchen für Anweisungen", "metrics.actions": "Aktionen", "metrics.average-visit-time": "Durchschn. Besuchszeit", "metrics.bounce-rate": "Absprungrate", diff --git a/lang/el-GR.json b/lang/el-GR.json index 4b1405e5..14cd69ca 100644 --- a/lang/el-GR.json +++ b/lang/el-GR.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Αντιγραφή στο πρόχειρο", "button.date-range": "Εύρος ημερομηνιών", "button.delete": "Διαγραφή", + "button.dismiss": "Dismiss", "button.edit": "Επεξεργασία", "button.login": "Είσοδος", "button.more": "Περισσότερα", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Λήψη κώδικα παρακολούθησης", "message.go-to-settings": "Μεταβείτε στις ρυθμίσεις", "message.incorrect-username-password": "Εσφαλμένο όνομα χρήστη / κωδικός πρόσβασης.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Δεν υπάρχουν διαθέσιμα δεδομένα.", "message.no-websites-configured": "Δεν έχετε ρυθμίσει κανένα ιστότοπο.", "message.page-not-found": "Η σελίδα δεν βρέθηκε.", diff --git a/lang/en-US.json b/lang/en-US.json index 044d4645..15450b4c 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Copy to clipboard", "button.date-range": "Date range", "button.delete": "Delete", + "button.dismiss": "Dismiss", "button.edit": "Edit", "button.login": "Login", "button.more": "More", @@ -63,7 +64,6 @@ "message.share-url": "This is the publicly shared URL for {target}.", "message.track-stats": "To track stats for {target}, place the following code in the {head} section of your website.", "message.type-delete": "Type {delete} in the box below to confirm.", - "message.visit-github-update": "Click here to visit umami on GitHub for instructions", "metrics.actions": "Actions", "metrics.average-visit-time": "Average visit time", "metrics.bounce-rate": "Bounce rate", diff --git a/lang/es-MX.json b/lang/es-MX.json index ed8cf1a2..16d911ea 100644 --- a/lang/es-MX.json +++ b/lang/es-MX.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Copiar al portapapeles", "button.date-range": "Date range", "button.delete": "Eliminar", + "button.dismiss": "Dismiss", "button.edit": "Editar", "button.login": "Iniciar sesión", "button.more": "Más", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Obtener código de rastreo", "message.go-to-settings": "Ir a la configuración", "message.incorrect-username-password": "Nombre de usuario o contraseña incorrectos.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Sin información disponible.", "message.no-websites-configured": "No tienes ningún sitio configurado.", "message.page-not-found": "Page not found", diff --git a/lang/fo-FO.json b/lang/fo-FO.json index 800f91c7..db9e972b 100644 --- a/lang/fo-FO.json +++ b/lang/fo-FO.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Kopier til clipboard", "button.date-range": "Vel dato", "button.delete": "Sletta", + "button.dismiss": "Dismiss", "button.edit": "Ger broyting", "button.login": "Rita inn", "button.more": "Meira", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Fá sporings kotu", "message.go-to-settings": "Far til stillingar", "message.incorrect-username-password": "Skeivt brúkaranavn/loyniorð.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Einki data tøk.", "message.no-websites-configured": "Tú hevur ongar heimasíður stillaða til.", "message.page-not-found": "Síðan bleiv ikki funnin.", diff --git a/lang/fr-FR.json b/lang/fr-FR.json index 8cfedb33..762cae34 100644 --- a/lang/fr-FR.json +++ b/lang/fr-FR.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Copier dans le presse papier", "button.date-range": "Date range", "button.delete": "Supprimer", + "button.dismiss": "Dismiss", "button.edit": "Modifier", "button.login": "Connexion", "button.more": "Plus", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Obtenez le code de suivi", "message.go-to-settings": "Aller aux paramètres", "message.incorrect-username-password": "nom d'utilisateurs/mot de passe incorrect.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Pas de données disponibles.", "message.no-websites-configured": "Vous n'avez configuré aucun site Web.", "message.page-not-found": "Page non trouvée.", diff --git a/lang/ja-JP.json b/lang/ja-JP.json index b15e0c92..0c9cbd89 100644 --- a/lang/ja-JP.json +++ b/lang/ja-JP.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "クリップボードにコピー", "button.date-range": "期間", "button.delete": "削除", + "button.dismiss": "Dismiss", "button.edit": "編集", "button.login": "ログイン", "button.more": "さらに表示", @@ -54,6 +55,7 @@ "message.get-tracking-code": "トラッキングコードを取得", "message.go-to-settings": "設定する", "message.incorrect-username-password": "ユーザー名/パスワードが正しくありません。", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "データがありません。", "message.no-websites-configured": "Webサイトが設定されていません。", "message.page-not-found": "ページが見つかりません。", diff --git a/lang/mn-MN.json b/lang/mn-MN.json index 377c81b1..b3c033cd 100644 --- a/lang/mn-MN.json +++ b/lang/mn-MN.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Хуулах", "button.date-range": "Хугацааны мужид", "button.delete": "Устгах", + "button.dismiss": "Dismiss", "button.edit": "Засах", "button.login": "Нэвтрэх", "button.more": "Цааш", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Мөрдөх код авах", "message.go-to-settings": "Тохиргоо руу очих", "message.incorrect-username-password": "Буруу хэрэглэгчийн нэр/нууц үг.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Өгөгдөл алга.", "message.no-websites-configured": "Та ямар нэгэн веб тохируулаагүй байна.", "message.page-not-found": "Хуудас олдсонгүй.", diff --git a/lang/nl-NL.json b/lang/nl-NL.json index d8fc730f..148fd32e 100644 --- a/lang/nl-NL.json +++ b/lang/nl-NL.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Kopiëer naar klembord", "button.date-range": "Datumbereik", "button.delete": "Verwijderen", + "button.dismiss": "Dismiss", "button.edit": "Bewerken", "button.login": "Inloggen", "button.more": "Toon meer", @@ -54,7 +55,7 @@ "message.get-tracking-code": "Tracking code", "message.go-to-settings": "Naar instellingen", "message.incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.", - "message.new-version-available": "Versie {latest} beschikbaar! Huidige versie: {current}", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Geen gegevens beschikbaar.", "message.no-websites-configured": "Je hebt geen websites ingesteld.", "message.page-not-found": "Pagina niet gevonden.", @@ -63,7 +64,6 @@ "message.share-url": "Met deze URL kan {target} openbaar gedeeld worden.", "message.track-stats": "Om statistieken voor {target} bij te houden, plaats je de volgende code in het {head} gedeelte van je website.", "message.type-delete": "Type {delete} in onderstaande veld om dit te bevestigen.", - "message.visit-github-update": "Klik hier om naar umami op GitHub te gaan voor instructies", "metrics.actions": "Acties", "metrics.average-visit-time": "Gemiddelde bezoektijd", "metrics.bounce-rate": "Bouncepercentage", diff --git a/lang/ru-RU.json b/lang/ru-RU.json index b9e19336..62a70a7c 100644 --- a/lang/ru-RU.json +++ b/lang/ru-RU.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Скопировать в буфер обмена", "button.date-range": "Диапазон дат", "button.delete": "Удалить", + "button.dismiss": "Dismiss", "button.edit": "Редактировать", "button.login": "Войти", "button.more": "Больше", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Получить код отслеживания", "message.go-to-settings": "Перейти к настройкам", "message.incorrect-username-password": "Неверное имя пользователя/пароль.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Нет данных.", "message.no-websites-configured": "У вас нет настроенных сайтов.", "message.page-not-found": "Страница не найдена.", diff --git a/lang/sv-SE.json b/lang/sv-SE.json index 1a14b60d..9e5e5958 100644 --- a/lang/sv-SE.json +++ b/lang/sv-SE.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Kopiera till urklipp", "button.date-range": "Datumomfång", "button.delete": "Radera", + "button.dismiss": "Dismiss", "button.edit": "Redigera", "button.login": "Logga in", "button.more": "Mer", @@ -54,6 +55,7 @@ "message.get-tracking-code": "Visa spårningskod", "message.go-to-settings": "Gå till inställningar", "message.incorrect-username-password": "Felaktikt användarnamn/lösenord.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Ingen data tillgänglig.", "message.no-websites-configured": "Du har inga webbsajter.", "message.page-not-found": "Sidan kan inte hittas.", diff --git a/lang/tr-TR.json b/lang/tr-TR.json index d8748359..2e84051d 100644 --- a/lang/tr-TR.json +++ b/lang/tr-TR.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "Panoya kopyala", "button.date-range": "Tarih aralığı", "button.delete": "Sil", + "button.dismiss": "Dismiss", "button.edit": "Düzenle", "button.login": "Giriş Yap", "button.more": "Detaylı göster", @@ -54,6 +55,7 @@ "message.get-tracking-code": "İzleme kodunu al", "message.go-to-settings": "Ayarlara git", "message.incorrect-username-password": "Hatalı kullanıcı adı ya da parola.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "Henüz hiç veri yok.", "message.no-websites-configured": "Henüz hiç web sitesi tanımlamadınız", "message.page-not-found": "Sayfa bulunamadı.", @@ -92,4 +94,4 @@ "title.edit-website": "Web sitesini düzenle", "title.share-url": "Paylaşım adresi", "title.tracking-code": "İzleme kodu" -} \ No newline at end of file +} diff --git a/lang/zh-CN.json b/lang/zh-CN.json index a51a42be..d5bf54cd 100644 --- a/lang/zh-CN.json +++ b/lang/zh-CN.json @@ -7,6 +7,7 @@ "button.copy-to-clipboard": "复制", "button.date-range": "多日", "button.delete": "删除", + "button.dismiss": "Dismiss", "button.edit": "编辑", "button.login": "登录", "button.more": "更多", @@ -54,6 +55,7 @@ "message.get-tracking-code": "获得跟踪代码", "message.go-to-settings": "去设置", "message.incorrect-username-password": "用户名密码不正确.", + "message.new-version-available": "A new version of umami {version} is available!", "message.no-data-available": "无可用数据.", "message.no-websites-configured": "你还没有设置任何网站.", "message.page-not-found": "网页未找到.", diff --git a/package.json b/package.json index 9c378ca1..6d1cc41e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "umami", - "version": "0.60.0", + "version": "0.61.0", "description": "A simple, fast, website analytics alternative to Google Analytics. ", "author": "Mike Cao ", "license": "MIT", @@ -80,6 +80,7 @@ "redux": "^4.0.5", "redux-thunk": "^2.3.0", "request-ip": "^2.1.3", + "semver": "^7.3.2", "thenby": "^1.3.4", "timezone-support": "^2.0.2", "tinycolor2": "^1.4.2", diff --git a/redux/actions/app.js b/redux/actions/app.js index 6bcba2f0..1cc5e7b6 100644 --- a/redux/actions/app.js +++ b/redux/actions/app.js @@ -1,5 +1,5 @@ import { createSlice } from '@reduxjs/toolkit'; -import { getItem } from 'lib/web'; +import { get, getItem } from 'lib/web'; import { LOCALE_CONFIG, THEME_CONFIG } from 'lib/constants'; const app = createSlice({ @@ -7,6 +7,10 @@ const app = createSlice({ initialState: { locale: getItem(LOCALE_CONFIG) || 'en-US', theme: getItem(THEME_CONFIG) || 'light', + versions: { + current: process.env.VERSION, + latest: null, + }, }, reducers: { setLocale(state, action) { @@ -17,9 +21,49 @@ const app = createSlice({ state.theme = action.payload; return state; }, + setVersions(state, action) { + state.versions = action.payload; + return state; + }, }, }); -export const { setLocale, setTheme } = app.actions; +export const { setLocale, setTheme, setVersions } = app.actions; export default app.reducer; + +export function checkVersion() { + return async (dispatch, getState) => { + const { + app: { + versions: { current }, + }, + } = 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, + }), + ); + } + } + }; +}