Skip to content

Commit

Permalink
feat: notify about new version (#1846)
Browse files Browse the repository at this point in the history
  • Loading branch information
therealemjy authored Nov 27, 2023
1 parent acda6c6 commit 3d39c71
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/tmp
/out-tsc
.env
/public/version.json

# Sentry Config File
.env.sentry-build-plugin
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
"generate-subgraph-types": "npm-run-all --parallel generate-subgraph-types:mainnet generate-subgraph-types:testnet",
"generate-contracts": "rimraf ./src/packages/contracts/generated/getters && rimraf ./src/packages/contracts/generated/infos && ./src/packages/contracts/scripts/generateContractRecords/index.ts && yarn prettier --write \"src/packages/contracts/generated/getters/**/*.{ts,json}\" && yarn prettier --write \"src/packages/contracts/generated/infos/**/*.{ts,json}\"",
"generate-pancake-swap-tokens": "./src/packages/tokens/scripts/generatePancakeSwapTokenRecords.ts && yarn prettier --write \"src/packages/tokens/infos/pancakeSwapTokens/bscMainnet.ts\"",
"generate-version-file": "genversion --es6 --semi src/constants/version.ts",
"generate-version-files": "genversion --es6 --semi src/constants/version.ts && src/scripts/generatePublicVersionFile.ts",
"husky:install": "husky install",
"postinstall": "npm-run-all --parallel husky:install generate-version-file generate-contracts generate-subgraph-types && yarn generate-pancake-swap-tokens",
"postinstall": "npm-run-all --parallel husky:install generate-version-files generate-contracts generate-subgraph-types && yarn generate-pancake-swap-tokens",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"regression": "reg-suit run"
Expand All @@ -50,6 +50,7 @@
"bignumber.js": "^9.1.1",
"buffer": "^6.0.3",
"clsx": "^2.0.0",
"compare-versions": "^6.1.0",
"copy-to-clipboard": "^3.3.3",
"date-fns": "^2.30.0",
"ethers": "^5.7.2",
Expand Down
3 changes: 3 additions & 0 deletions src/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { QueryClientProvider } from 'react-query';
import { HashRouter } from 'react-router-dom';

import { queryClient } from 'clients/api';
import { AppVersionChecker } from 'containers/AppVersionChecker';
import { Layout } from 'containers/Layout';
import { AuthProvider } from 'context/AuthContext';
import { SentryErrorInfo } from 'packages/errors/SentryErrorInfo';
Expand All @@ -30,6 +31,8 @@ const App = () => (
<Router />
</Layout>

<AppVersionChecker />

<LunaUstWarningModal />

<Suspense>
Expand Down
4 changes: 4 additions & 0 deletions src/clients/api/__mocks__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ export const useGetHypotheticalPrimeApys = vi.fn(() =>
useQuery(FunctionKey.GET_HYPOTHETICAL_PRIME_APYS, getHypotheticalPrimeApys),
);

export const getLatestAppVersion = vi.fn();
export const useGetLatestAppVersion = () =>
useQuery(FunctionKey.GET_LATEST_APP_VERSION, getLatestAppVersion);

// Mutations
export const approveToken = vi.fn();
export const useApproveToken = (_variables: never, options?: MutationObserverOptions) =>
Expand Down
3 changes: 3 additions & 0 deletions src/clients/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,6 @@ export { default as useGetHypotheticalPrimeApys } from './queries/getHypothetica
export { default as getPrimeStatus } from './queries/getPrimeStatus';
export * from './queries/getPrimeStatus';
export { default as useGetPrimeStatus } from './queries/getPrimeStatus/useGetPrimeStatus';

export * from './queries/getLatestAppVersion';
export { default as useGetLatestAppVersion } from './queries/getLatestAppVersion/useGetLatestAppVersion';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Vi from 'vitest';

import { PUBLIC_VERSION_FILE_URL, getLatestAppVersion } from '..';

describe('getLatestAppVersion', () => {
test('returns the latest app version on success', async () => {
const fakeVersion = '9.9.9';

(fetch as Vi.Mock).mockImplementationOnce(() => ({
json: () => ({
version: fakeVersion,
}),
}));

const response = await getLatestAppVersion();

expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith(PUBLIC_VERSION_FILE_URL);
expect(response).toEqual({
version: fakeVersion,
});
});
});
14 changes: 14 additions & 0 deletions src/clients/api/queries/getLatestAppVersion/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type GetLatestAppVersionOutput = {
version?: string;
};

export const PUBLIC_VERSION_FILE_URL = `${window.location.origin}/version.json`;

export const getLatestAppVersion = async (): Promise<GetLatestAppVersionOutput> => {
const data = await fetch(PUBLIC_VERSION_FILE_URL);
const { version } = await data.json();

return {
version,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { QueryObserverOptions, useQuery } from 'react-query';

import {
GetLatestAppVersionOutput,
getLatestAppVersion,
} from 'clients/api/queries/getLatestAppVersion';
import FunctionKey from 'constants/functionKey';

const REFETCH_INTERVAL_MS = 1000 * 60 * 60; // One hour in milliseconds

type Options = QueryObserverOptions<
GetLatestAppVersionOutput,
Error,
GetLatestAppVersionOutput,
GetLatestAppVersionOutput,
FunctionKey.GET_LATEST_APP_VERSION
>;

const useGetLatestAppVersion = (options?: Options) =>
useQuery(FunctionKey.GET_LATEST_APP_VERSION, getLatestAppVersion, {
staleTime: 0,
cacheTime: 0,
refetchInterval: REFETCH_INTERVAL_MS,
...options,
});

export default useGetLatestAppVersion;
1 change: 1 addition & 0 deletions src/constants/functionKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum FunctionKey {
GET_HYPOTHETICAL_PRIME_APYS = 'GET_HYPOTHETICAL_PRIME_APYS',
GET_PRIME_TOKEN = 'GET_PRIME_TOKEN',
GET_PRIME_STATUS = 'GET_PRIME_STATUS',
GET_LATEST_APP_VERSION = 'GET_LATEST_APP_VERSION',

// Mutations
MINT_VAI = 'MINT_VAI',
Expand Down
24 changes: 24 additions & 0 deletions src/containers/AppVersionChecker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { compareVersions } from 'compare-versions';
import { displayNotification } from 'packages/notifications';
import { useTranslation } from 'packages/translations';
import React, { useEffect } from 'react';

import { useGetLatestAppVersion } from 'clients/api';
import { version as APP_VERSION } from 'constants/version';

export const AppVersionChecker: React.FC = () => {
const { t } = useTranslation();
const { data } = useGetLatestAppVersion();
const latestAppVersion = data?.version;

useEffect(() => {
if (latestAppVersion && compareVersions(latestAppVersion, APP_VERSION)) {
displayNotification({
description: t('appVersionChecker.newVersionMessage'),
autoClose: false,
});
}
}, [latestAppVersion, t]);

return null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('useTrackTransaction', () => {
expect(displayNotification).toHaveBeenCalledWith({
id: fakeContractTransaction.hash,
variant: 'loading',
autoClose: false,
title: en.transactionNotification.pending.title,
description: (
<ChainExplorerLink
Expand Down Expand Up @@ -119,6 +120,7 @@ describe('useTrackTransaction', () => {
expect(displayNotification).toHaveBeenCalledWith({
id: fakeContractTransaction.hash,
variant: 'loading',
autoClose: false,
title: en.transactionNotification.pending.title,
description: (
<ChainExplorerLink
Expand Down Expand Up @@ -172,6 +174,7 @@ describe('useTrackTransaction', () => {
expect(displayNotification).toHaveBeenCalledWith({
id: fakeContractTransaction.hash,
variant: 'loading',
autoClose: false,
title: en.transactionNotification.pending.title,
description: (
<ChainExplorerLink
Expand Down Expand Up @@ -219,6 +222,7 @@ describe('useTrackTransaction', () => {
expect(displayNotification).toHaveBeenCalledWith({
id: fakeContractTransaction.hash,
variant: 'loading',
autoClose: false,
title: en.transactionNotification.pending.title,
description: (
<ChainExplorerLink
Expand Down
1 change: 1 addition & 0 deletions src/hooks/useSendTransaction/useTrackTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const useTrackTransaction = () => {
const notificationId = displayNotification({
id: transaction.hash,
variant: 'loading',
autoClose: false,
title: t('transactionNotification.pending.title'),
description: <ChainExplorerLink chainId={chainId} hash={transaction.hash} urlType="tx" />,
});
Expand Down
46 changes: 28 additions & 18 deletions src/packages/notifications/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,11 @@ const timeoutsMapping: {
[notificationId: Notification['id']]: NodeJS.Timer;
} = {};

const setHideTimeout = ({
id,
variant,
}: {
id: Notification['id'];
variant: Notification['variant'];
}) => {
const setHideTimeout = ({ id }: { id: Notification['id'] }) => {
const { removeNotification } = store.getState();

// Automatically hide notification after a certain time if it's not of the variant "loading"
if (variant !== 'loading') {
timeoutsMapping[id] = setTimeout(() => removeNotification({ id }), DISPLAY_TIME_MS);
}
// Automatically hide notification after a certain time
timeoutsMapping[id] = setTimeout(() => removeNotification({ id }), DISPLAY_TIME_MS);
};

export const hideNotification = ({ id }: RemoveNotificationInput) => {
Expand All @@ -36,7 +28,14 @@ export const hideNotification = ({ id }: RemoveNotificationInput) => {
removeNotification({ id });
};

export const displayNotification = (input: AddNotificationInput) => {
type DisplayNotificationInput = AddNotificationInput & {
autoClose?: boolean;
};

export const displayNotification = ({
autoClose = true,
...addNotificationInput
}: DisplayNotificationInput) => {
const { addNotification, notifications } = store.getState();

// Remove last notification if we've reached the maximum allowed
Expand All @@ -45,21 +44,32 @@ export const displayNotification = (input: AddNotificationInput) => {
}

// Add notification to store
const newNotificationId = addNotification(input);
const newNotificationId = addNotification(addNotificationInput);

setHideTimeout({ id: newNotificationId, variant: input.variant });
if (autoClose) {
setHideTimeout({ id: newNotificationId });
}

return newNotificationId;
};

export const updateNotification = (input: UpdateNotificationInput) => {
type UpdateNotificationUtilInput = UpdateNotificationInput & {
autoClose?: boolean;
};

export const updateNotification = ({
autoClose = true,
...updateNotificationInput
}: UpdateNotificationUtilInput) => {
// Clear hide timeout if one was set
clearTimeout(timeoutsMapping[input.id]);
clearTimeout(timeoutsMapping[updateNotificationInput.id]);

const { updateNotification: updateStoreNotification } = store.getState();

// Update notification
updateStoreNotification(input);
updateStoreNotification(updateNotificationInput);

setHideTimeout({ id: input.id, variant: input.variant });
if (autoClose) {
setHideTimeout({ id: updateNotificationInput.id });
}
};
11 changes: 7 additions & 4 deletions src/packages/translations/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@
"step1": "Step 1",
"step2": "Step 2"
},
"appVersionChecker": {
"newVersionMessage": "A new version of Venus is available. Reload the page to use it now."
},
"apyChart": {
"tooltipItemLabels": {
"borrowApy": "Borrow APY",
Expand Down Expand Up @@ -309,15 +312,15 @@
"xvs": "XVS"
}
},
"legacyPool": {
"description": "Venus’ primary pool is composed of large-cap tokens that meet minimum liquidity requirements.",
"name": "Venus Core Pool"
},
"lunaUstWarningModal": {
"closeButtonLabel": "Got it",
"content": "LUNA and UST have been deprecated, please disable them as collateral to get access to the Venus protocol again.",
"title": "Please disable LUNA and UST as collateral"
},
"legacyPool": {
"description": "Venus’ primary pool is composed of large-cap tokens that meet minimum liquidity requirements.",
"name": "Venus Core Pool"
},
"markdownEditor": {
"markdownTabLabel": "Write",
"placeholder": "Nothing to preview",
Expand Down
30 changes: 30 additions & 0 deletions src/scripts/generatePublicVersionFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env tsx
import * as path from 'path';
import { searchForWorkspaceRoot } from 'vite';

import { version } from 'constants/version';
import writeFile from 'utilities/writeFile';

const generatePublicVersionFile = async () => {
const content = JSON.stringify({
version,
});

console.log(searchForWorkspaceRoot(__dirname));

// Generate file
const outputPath = path.join(searchForWorkspaceRoot(__dirname), './public/version.json');

writeFile({
outputPath,
content,
});

return outputPath;
};

console.log('Generating public version file...');

generatePublicVersionFile()
.then(outputPath => console.log(`Finished generating public version file at: ${outputPath}`))
.catch(console.error);
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9710,6 +9710,11 @@ compare-versions@^5.0.0:
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.3.tgz#a9b34fea217472650ef4a2651d905f42c28ebfd7"
integrity sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==

compare-versions@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.0.tgz#3f2131e3ae93577df111dba133e6db876ffe127a"
integrity sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==

compressible@~2.0.16:
version "2.0.18"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
Expand Down

0 comments on commit 3d39c71

Please sign in to comment.