From 1a3e40153fe3704d36ae316e23754286ef275976 Mon Sep 17 00:00:00 2001 From: Roy Li Date: Tue, 2 Nov 2021 23:36:35 +0100 Subject: [PATCH] fix: version in local storage isn't up-to-date --- src/i18n/en/translation.json | 3 ++- src/i18n/zh/translation.json | 3 ++- src/models/profile.tsx | 26 ++++++++++++++++++++++++ src/pages/Index/index.tsx | 38 ++++++++++++++++++++++++++++++++++-- src/utils/fetcher.ts | 1 + src/utils/store.ts | 21 ++++++++++++++++++++ 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/utils/store.ts diff --git a/src/i18n/en/translation.json b/src/i18n/en/translation.json index b0d9982..a73c7d8 100644 --- a/src/i18n/en/translation.json +++ b/src/i18n/en/translation.json @@ -11,7 +11,8 @@ "success_interaction": "Success", "failed_interaction": "Failed", "see": "See", - "save": "Save" + "save": "Save", + "surge_too_old": "Your Surge is too old, please upgrade in order to use this application!" }, "form": { "err_invalid": "Invalid value", diff --git a/src/i18n/zh/translation.json b/src/i18n/zh/translation.json index c640380..658cdf6 100644 --- a/src/i18n/zh/translation.json +++ b/src/i18n/zh/translation.json @@ -11,7 +11,8 @@ "success_interaction": "操作成功", "failed_interaction": "操作失败", "see": "查看", - "save": "保存" + "save": "保存", + "surge_too_old": "您的 Surge 版本过低,请考虑升级 Surge 以使用本程序!" }, "form": { "err_invalid": "无效的输入内容", diff --git a/src/models/profile.tsx b/src/models/profile.tsx index 9f01e2f..282b0a9 100644 --- a/src/models/profile.tsx +++ b/src/models/profile.tsx @@ -2,6 +2,7 @@ import React, { createContext, Dispatch, Reducer, useReducer } from 'react' import { Profile } from '../types' import { setServer } from '../utils/fetcher' +import { updateStoredProfile } from '../utils/store' interface IProfileContext { profile?: Profile @@ -15,6 +16,12 @@ type ReducerAction = | { type: 'clear' } + | { + type: 'updatePlatformVersion' + payload: { + platformVersion: Profile['platformVersion'] + } + } const profileReducer: Reducer = ( state, @@ -32,6 +39,25 @@ const profileReducer: Reducer = ( return { profile: undefined, } + case 'updatePlatformVersion': { + if (!state.profile) { + throw new Error( + 'updatePlatformVersion cannot be dispatched if the profile is absent.', + ) + } + + const profile = state.profile + const updated = { + ...profile, + platformVersion: action.payload.platformVersion, + } + + updateStoredProfile(updated.id, updated) + + return { + profile: updated, + } + } default: throw new Error() } diff --git a/src/pages/Index/index.tsx b/src/pages/Index/index.tsx index adb9f45..42069a8 100644 --- a/src/pages/Index/index.tsx +++ b/src/pages/Index/index.tsx @@ -1,9 +1,10 @@ /** @jsx jsx */ import { jsx } from '@emotion/core' -import React, { useCallback } from 'react' +import React, { useCallback, useEffect, useRef } from 'react' import { Button, Heading, Toggle } from '@sumup/circuit-ui' import css from '@emotion/css/macro' import { useTranslation } from 'react-i18next' +import { toast } from 'react-toastify' import tw from 'twin.macro' import { delay } from 'bluebird' import { useHistory } from 'react-router-dom' @@ -19,11 +20,12 @@ import { usePlatformBuild, usePlatformVersion, useProfile, + useProfileDispatch, } from '../../models/profile' import { Capability } from '../../types' import { isRunInSurge } from '../../utils' import { ExistingProfiles, LastUsedProfile } from '../../utils/constant' -import fetcher from '../../utils/fetcher' +import fetcher, { httpClient } from '../../utils/fetcher' import HostInfo from './components/HostInfo' import TrafficCell from './components/TrafficCell' import Events from './components/Events' @@ -34,6 +36,7 @@ import menu from './menu' const Page: React.FC = () => { const history = useHistory() const profile = useProfile() + const profileDispatch = useProfileDispatch() const { data: systemProxy } = useSWR( profile?.platform === 'macos' ? '/features/system_proxy' : null, fetcher, @@ -46,6 +49,7 @@ const Page: React.FC = () => { const platform = usePlatform() const platformVersion = usePlatformVersion() const platformBuild = usePlatformBuild() + const isFirstShown = useRef(true) const toggleSystemProxy = useCallback(() => { fetcher({ @@ -95,6 +99,36 @@ const Page: React.FC = () => { } } + useEffect(() => { + if (!profile?.platform || !isFirstShown.current) { + return + } + + httpClient + .request({ + url: '/environment', + method: 'GET', + }) + .then((res) => { + const currentPlatformVersion = res.headers['x-surge-version'] + + if (currentPlatformVersion !== platformVersion) { + profileDispatch({ + type: 'updatePlatformVersion', + payload: { + platformVersion: currentPlatformVersion, + }, + }) + } + + isFirstShown.current = false + }) + .catch((err) => { + console.error(err) + toast.error(t('common.surge_too_old')) + }) + }, [platformVersion, profile?.platform, profileDispatch, t]) + return (
(requestConfig: AxiosRequestConfig): Promise => { } export default fetcher +export { client as httpClient } diff --git a/src/utils/store.ts b/src/utils/store.ts new file mode 100644 index 0000000..35f826a --- /dev/null +++ b/src/utils/store.ts @@ -0,0 +1,21 @@ +import { findIndex } from 'lodash-es' +import store from 'store2' + +import { Profile } from '../types' +import { ExistingProfiles } from './constant' + +export const updateStoredProfile = ( + profileId: Profile['id'], + newProfile: Profile, +): void => { + const storedExistingProfiles: Profile[] = store.get(ExistingProfiles) + + if (storedExistingProfiles) { + const result = findIndex(storedExistingProfiles, { id: profileId }) + + if (result !== -1) { + storedExistingProfiles.splice(result, 1, newProfile) + store.set(ExistingProfiles, storedExistingProfiles) + } + } +}