From b24f87dd6156da433591d361a0799b2677c2002e Mon Sep 17 00:00:00 2001 From: Jun Ma Date: Mon, 10 Jul 2023 16:21:20 +0800 Subject: [PATCH] feat:Detect new upgrade on launch --- .../GeneralSetting/generalSetting.module.scss | 20 +++++++ .../src/components/GeneralSetting/index.tsx | 45 ++++++++++----- .../neuron-ui/src/containers/Navbar/index.tsx | 56 ++++++++++++++++--- .../src/widgets/Badge/badge.module.scss | 16 ++++++ .../neuron-ui/src/widgets/Badge/index.tsx | 8 +++ 5 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 packages/neuron-ui/src/widgets/Badge/badge.module.scss create mode 100644 packages/neuron-ui/src/widgets/Badge/index.tsx diff --git a/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss b/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss index 37c98c5d7c..c9fb6d0603 100644 --- a/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss +++ b/packages/neuron-ui/src/components/GeneralSetting/generalSetting.module.scss @@ -12,6 +12,7 @@ $action-button-width: 11.25rem; background: var(--input-disabled-color); border-radius: 8px; margin-right: 16px; + p { font-size: 14px; line-height: 20px; @@ -33,6 +34,25 @@ $action-button-width: 11.25rem; } } } + .showVersion { + position: relative; + + &::after { + content: attr(data-new-version-tip); + background-color: #ff1e1e; + border-top-right-radius: 8px; + border-bottom-left-radius: 8px; + position: absolute; + top: 0; + right: 0; + font-size: 12px; + font-style: normal; + font-weight: 500; + line-height: normal; + padding: 2px 4px; + color: #fff; + } + } } .install { diff --git a/packages/neuron-ui/src/components/GeneralSetting/index.tsx b/packages/neuron-ui/src/components/GeneralSetting/index.tsx index 648e93a9aa..8c53edc133 100644 --- a/packages/neuron-ui/src/components/GeneralSetting/index.tsx +++ b/packages/neuron-ui/src/components/GeneralSetting/index.tsx @@ -14,13 +14,13 @@ import { installUpdate, getVersion, } from 'services/remote' -import { uniformTimeFormatter, bytesFormatter } from 'utils' +import { uniformTimeFormatter, bytesFormatter, clsx } from 'utils' import { LanguageSelect } from 'widgets/Icons/icon' import styles from './generalSetting.module.scss' interface UpdateDownloadStatusProps { show: boolean - onCancel: () => void + onCancel: (status?: string) => void progress: number newVersion: string releaseDate: string @@ -69,7 +69,7 @@ const UpdateDownloadStatus = ({ onConfirm={handleConfirm} disabled={!available} confirmText={t('updates.install-update')} - onCancel={onCancel} + onCancel={() => onCancel('checked')} title={t('updates.update-available')} confirmProps={{ 'data-method': 'download', @@ -135,7 +135,9 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => { const [showLangDialog, setShowLangDialog] = useState(false) const [searchParams] = useSearchParams() const [errorMsg, setErrorMsg] = useState('') - const [dialogType, setDialogType] = useState<'' | 'checking' | 'updating' | 'updated'>('') + const [dialogType, setDialogType] = useState<'' | 'checking' | 'checked' | 'updating' | 'updated'>('') + const [isFetchUpdateByClick, setIsFetchUpdateByClick] = useState(false) + const { version: newVersion } = updater const version = useMemo(() => { return getVersion() @@ -145,7 +147,9 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => { const checkUpdate = searchParams.get('checkUpdate') if (checkUpdate === '1') { checkForUpdates() + setIsFetchUpdateByClick(true) } + return () => setIsFetchUpdateByClick(false) }, [searchParams, checkForUpdates]) useEffect(() => { @@ -162,7 +166,11 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => { setDialogType('checking') return } - if (updater.version || updater.downloadProgress > 0) { + if (newVersion) { + setDialogType('checked') + return + } + if (updater.downloadProgress > 0) { setDialogType('updating') return } @@ -175,7 +183,10 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => { dataset: { method }, } = e.target as HTMLElement - if (method === 'cancelCheck') { + setIsFetchUpdateByClick(true) + if (newVersion) { + setDialogType('checked') + } else if (method === 'cancelCheck') { if (dialogType === 'checking') { cancelCheckUpdates() } @@ -189,12 +200,12 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => { return (
-
+

- {t('settings.general.version')} v{version} + {t('settings.general.version')} v{newVersion || version}

@@ -216,11 +227,14 @@ const GeneralSetting = ({ updater }: GeneralSettingProps) => { title={t(`updates.check-updates`)} message={errorMsg} type="failed" - onCancel={() => setErrorMsg('')} + onCancel={() => { + setIsFetchUpdateByClick(false) + setErrorMsg('') + }} /> { { - cancelDownloadUpdate() + show={dialogType === 'updating' || (dialogType === 'checked' && isFetchUpdateByClick)} + onCancel={status => { + if (status !== 'checked') { + cancelDownloadUpdate() + } + setIsFetchUpdateByClick(false) setDialogType('') }} progress={updater.downloadProgress} diff --git a/packages/neuron-ui/src/containers/Navbar/index.tsx b/packages/neuron-ui/src/containers/Navbar/index.tsx index 7c45530421..f765c0137c 100644 --- a/packages/neuron-ui/src/containers/Navbar/index.tsx +++ b/packages/neuron-ui/src/containers/Navbar/index.tsx @@ -2,7 +2,10 @@ import React, { useCallback, useEffect, useState } from 'react' import { createPortal } from 'react-dom' import { useLocation, NavLink, useNavigate } from 'react-router-dom' import { useTranslation } from 'react-i18next' -import { useState as useGlobalState } from 'states' +import { NeuronWalletActions, useDispatch, useState as useGlobalState } from 'states' +import { checkForUpdates } from 'services/remote' +import { AppUpdater as AppUpdaterSubject } from 'services/subjects' +import Badge from 'widgets/Badge' import Logo from 'widgets/Icons/Logo.png' import { Overview, @@ -67,21 +70,51 @@ const MenuButton = ({ const Navbar = () => { const { pathname } = useLocation() + const dispatch = useDispatch() const neuronWallet = useGlobalState() const { wallet: { name }, settings: { wallets = [] }, + updater: { version }, } = neuronWallet const [t, i18n] = useTranslation() useOnLocaleChange(i18n) - const [selectedKey, setSelectedKey] = useState() - const computedKey = menuItems.find(item => item.key === pathname || item.children?.some(v => v.key === pathname))?.key + const [isClickedSetting, setIsClickedSetting] = useState(false) + const selectedKey = menuItems.find(item => item.key === pathname || item.children?.some(v => v.key === pathname))?.key useEffect(() => { - if (computedKey) { - setSelectedKey(computedKey) + const onAppUpdaterUpdates = (info: Subject.AppUpdater) => { + dispatch({ type: NeuronWalletActions.UpdateAppUpdaterStatus, payload: info }) } - }, [computedKey]) + const appUpdaterSubscription = AppUpdaterSubject.subscribe(onAppUpdaterUpdates) + + return () => { + appUpdaterSubscription.unsubscribe() + } + }, [dispatch]) + + useEffect(() => { + const now = new Date() + const nextTriggerTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59) + + checkForUpdates() + if (nextTriggerTime) { + const timeDiff = nextTriggerTime.getTime() - now.getTime() + + setTimeout(() => { + checkForUpdates() + setInterval(() => { + checkForUpdates() + }, 24 * 60 * 60 * 1000) + }, timeDiff) + } + }, [checkForUpdates]) + + useEffect(() => { + if (pathname.includes(RoutePath.Settings)) { + setIsClickedSetting(true) + } + }, [pathname]) const [menuExpanded, setMenuExpanded] = useState(true) const onClickExpand = useCallback(() => { @@ -121,9 +154,18 @@ const Navbar = () => { {item.icon} - {t(item.name)} + + {!isClickedSetting && version && item.key === RoutePath.Settings ? ( + + {t(item.name)} + + ) : ( + {t(item.name)} + )} + {item.children?.length && } + {item.children?.length && item.key === selectedKey && (
diff --git a/packages/neuron-ui/src/widgets/Badge/badge.module.scss b/packages/neuron-ui/src/widgets/Badge/badge.module.scss new file mode 100644 index 0000000000..23ac5ba571 --- /dev/null +++ b/packages/neuron-ui/src/widgets/Badge/badge.module.scss @@ -0,0 +1,16 @@ +@import '../../styles/theme.scss'; + +.badge { + position: relative; + + &::after { + content: ''; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: #ff1e1e; + position: absolute; + top: 20%; + margin-left: 4px; + } +} diff --git a/packages/neuron-ui/src/widgets/Badge/index.tsx b/packages/neuron-ui/src/widgets/Badge/index.tsx new file mode 100644 index 0000000000..d34b2d5001 --- /dev/null +++ b/packages/neuron-ui/src/widgets/Badge/index.tsx @@ -0,0 +1,8 @@ +import React from 'react' +import styles from './badge.module.scss' + +const Badge = ({ children }: { children: React.ReactChild }) => { + return
{children}
+} + +export default Badge