From 13c012bee487a9a4b37f71d86397c277889f9303 Mon Sep 17 00:00:00 2001 From: Peter Sanderson Date: Tue, 16 Jul 2024 11:43:06 +0200 Subject: [PATCH] feat(suite): add support for multiline changelog, use markdown --- packages/components/package.json | 1 + .../src/components/Markdown/Markdown.tsx | 79 +++ packages/components/src/index.ts | 5 +- .../files/firmware/t2t1/releases.json | 669 +++++++++++++++--- packages/connect/src/types/firmware.ts | 4 +- .../components/firmware/FirmwareChangelog.tsx | 17 - .../src/components/firmware/FirmwareOffer.tsx | 6 +- .../suite/src/components/firmware/index.tsx | 1 - .../src/components/guide/GuideMarkdown.tsx | 82 +-- packages/suite/src/hooks/suite/useFirmware.ts | 2 + .../__tests__/parseFirmwareChangelog.test.ts | 52 +- .../suite-utils/src/parseFirmwareChangelog.ts | 22 +- yarn.lock | 1 + 13 files changed, 697 insertions(+), 244 deletions(-) create mode 100644 packages/components/src/components/Markdown/Markdown.tsx delete mode 100644 packages/suite/src/components/firmware/FirmwareChangelog.tsx diff --git a/packages/components/package.json b/packages/components/package.json index 0d65f63dc915..bbc6c203e783 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -36,6 +36,7 @@ "react-date-range": "^1.4.0", "react-dom": "18.2.0", "react-intl": "^6.6.2", + "react-markdown": "^9.0.1", "react-select": "^5.8.0", "react-svg": "^16.1.33", "react-use": "^17.5.0", diff --git a/packages/components/src/components/Markdown/Markdown.tsx b/packages/components/src/components/Markdown/Markdown.tsx new file mode 100644 index 000000000000..d6067baaa796 --- /dev/null +++ b/packages/components/src/components/Markdown/Markdown.tsx @@ -0,0 +1,79 @@ +import styled from 'styled-components'; + +import ReactMarkdown, { Options } from 'react-markdown'; +import { variables } from '../../config'; + +const StyledMarkdown = styled.div` + color: ${({ theme }) => theme.TYPE_LIGHT_GREY}; + font-size: ${variables.FONT_SIZE.SMALL}; + font-weight: ${variables.FONT_WEIGHT.MEDIUM}; + line-height: 1.5; + padding: 0 0 32px; + + h1, + h2, + h3, + h4, + h5, + h6 { + color: ${({ theme }) => theme.TYPE_DARK_GREY}; + font-weight: ${variables.FONT_WEIGHT.DEMI_BOLD}; + } + + h1 { + margin: 8px 0 16px; + font-size: ${variables.FONT_SIZE.BIG}; + } + + h2 { + margin-bottom: 8px 0 12px; + font-size: ${variables.FONT_SIZE.NORMAL}; + } + + h3, + h4, + h5, + h6 { + margin: 4px 0 12px; + font-size: ${variables.FONT_SIZE.SMALL}; + } + + p, + ul, + ol { + margin: 4px 0 12px; + } + + ul, + ol { + padding: 0 0 0 16px; + } + + li { + margin: 0 0 8px; + } + + a { + color: ${({ theme }) => theme.TYPE_GREEN}; + + &:hover { + text-decoration: underline; + } + } + + img { + max-width: 100%; + } + + strong { + font-weight: ${variables.FONT_WEIGHT.DEMI_BOLD}; + } +`; + +export const Markdown = (options: Readonly) => { + return ( + + + + ); +}; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 57c1e13df628..6b51ce45f045 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -31,7 +31,6 @@ export * from './components/Divider/Divider'; export * from './components/Dropdown/Dropdown'; export * from './components/ElevationContext/ElevationContext'; export * from './components/Flex/Flex'; -export * from './components/HotkeyBadge/HotkeyBadge'; export * from './components/form/Input/Input'; export * from './components/form/InputStyles'; export * from './components/form/Radio/Radio'; @@ -41,6 +40,7 @@ export * from './components/form/SelectBar/SelectBar'; export * from './components/form/Switch/Switch'; export * from './components/form/Textarea/Textarea'; export * from './components/GradientOverlay/GradientOverlay'; +export * from './components/HotkeyBadge/HotkeyBadge'; export * from './components/Image/Image'; export * from './components/Image/images'; export * from './components/loaders/LoadingContent/LoadingContent'; @@ -48,6 +48,7 @@ export * from './components/loaders/ProgressBar/ProgressBar'; export * from './components/loaders/ProgressPie/ProgressPie'; export * from './components/loaders/Spinner/Spinner'; export * from './components/loaders/Stepper/Stepper'; +export * from './components/Markdown/Markdown'; export * from './components/modals/DialogModal/DialogModal'; export * from './components/modals/Modal/Backdrop'; export * from './components/modals/Modal/Modal'; @@ -60,13 +61,13 @@ export * from './components/skeletons/SkeletonRectangle'; export * from './components/skeletons/SkeletonSpread'; export * from './components/skeletons/SkeletonStack'; export * from './components/skeletons/types'; -export * from './components/typography/Text/Text'; export * from './components/Timerange/Timerange'; export * from './components/Tooltip/Tooltip'; export * from './components/Tooltip/TooltipDelay'; export * from './components/typography/Heading/Heading'; export * from './components/typography/Link/Link'; export * from './components/typography/Paragraph/Paragraph'; +export * from './components/typography/Text/Text'; export * from './components/typography/TruncateWithTooltip/TruncateWithTooltip'; export * from './components/Warning/Warning'; diff --git a/packages/connect-common/files/firmware/t2t1/releases.json b/packages/connect-common/files/firmware/t2t1/releases.json index 839fc6fcdb46..7a0765ba5e18 100644 --- a/packages/connect-common/files/firmware/t2t1/releases.json +++ b/packages/connect-common/files/firmware/t2t1/releases.json @@ -1,24 +1,77 @@ [ { "required": false, - "version": [2, 7, 2], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], - "bootloader_version": [2, 1, 4], - "translations": ["cs-CZ", "de-DE", "es-ES", "fr-FR"], + "version": [ + 2, + 7, + 2 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], + "bootloader_version": [ + 2, + 1, + 4 + ], + "translations": [ + "cs-CZ", + "de-DE", + "es-ES", + "fr-FR" + ], "url": "firmware/t2t1/trezor-t2t1-2.7.2.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.7.2-bitcoinonly.bin", "fingerprint": "d64fcf47a8ead6edf0329583e312136d1548d30990c29cfaa2ce7c67197babcc", "fingerprint_bitcoinonly": "cba515383705ec6420c54dd1ffdb33ea7ce4bb04bc6d992c2923880daa53d3e1", - "changelog": "* Introducing repeated backups. \n* Multi-share backups can now have any number of shares. \n* Added support for Cardano Conway certificates [Universal fw only]." + "changelog": "* Introducing repeated backups. \n* Multi-share backups can now have any number of shares. \n* Added support for Cardano Conway certificates [Universal fw only].", + "changelogBtcOnly": [ + "## 🎨 Improvements", + " - The \"Remember Wallet\" feature has been enhanced and renamed to \"View-Only Wallet\" for better discoverability and clarity.", + " - The wallet switcher has been redesigned for a smoother experience.", + " - The passphrase is now integrated into the wallet switcher, eliminating prompts at every device connection.", + " - Token management has been revamped with manual hide/unhide options, enhanced search functionality, and more.", + " - Staked ETH balance is now included in the Dashboard Portfolio.", + " - Fractional gas prices now supported for EVM transactions, allowing for more precise gas fee calculations.", + "## 🔧 Bug fixes", + " - Various small improvements and bug fixes." + ] }, { "required": false, - "version": [2, 7, 0], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], - "bootloader_version": [2, 1, 4], - "translations": ["cs-CZ", "de-DE", "es-ES", "fr-FR"], + "version": [ + 2, + 7, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], + "bootloader_version": [ + 2, + 1, + 4 + ], + "translations": [ + "cs-CZ", + "de-DE", + "es-ES", + "fr-FR" + ], "url": "firmware/t2t1/trezor-t2t1-2.7.0.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.7.0-bitcoinonly.bin", "fingerprint": "53a645218792e413ad06c27320b7d1adc944b690ce831301bbf11c30352d3278", @@ -27,10 +80,26 @@ }, { "required": false, - "version": [2, 6, 4], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], - "bootloader_version": [2, 1, 4], + "version": [ + 2, + 6, + 4 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], + "bootloader_version": [ + 2, + 1, + 4 + ], "url": "firmware/t2t1/trezor-t2t1-2.6.4.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.6.4-bitcoinonly.bin", "fingerprint": "441faa92156e8ae0b8247f9434c3ec8cf6ffd872f16fc593b22c4460dfd93913", @@ -39,10 +108,26 @@ }, { "required": false, - "version": [2, 6, 3], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], - "bootloader_version": [2, 1, 4], + "version": [ + 2, + 6, + 3 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], + "bootloader_version": [ + 2, + 1, + 4 + ], "url": "firmware/t2t1/trezor-t2t1-2.6.3.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.6.3-bitcoinonly.bin", "fingerprint": "9ff0874f2ce3579a7502747578cef65c824097d906e7150b0142f6b9aa395a43", @@ -51,10 +136,26 @@ }, { "required": false, - "version": [2, 6, 0], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], - "bootloader_version": [2, 1, 0], + "version": [ + 2, + 6, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], + "bootloader_version": [ + 2, + 1, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.6.0.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.6.0-bitcoinonly.bin", "fingerprint": "050526db604b9acceef2a5a8561bc99ecbe337909283ebb927b556d8e9b13872", @@ -64,9 +165,21 @@ }, { "required": false, - "version": [2, 5, 3], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 5, + 3 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.5.3.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.5.3-bitcoinonly.bin", "fingerprint": "4f57dca1abc1a60d82c4fef7c96e86d784fc7a1e5e3da724dd2ae4d14c6350bf", @@ -76,9 +189,21 @@ }, { "required": false, - "version": [2, 5, 2], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 5, + 2 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.5.2.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.5.2-bitcoinonly.bin", "fingerprint": "659b1b698546fa63f24200e148b6f9a7044df31d11a0a5ec7c044f2dd83f4a27", @@ -88,9 +213,21 @@ }, { "required": false, - "version": [2, 5, 1], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 5, + 1 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.5.1.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.5.1-bitcoinonly.bin", "fingerprint": "782d4934897018cac779eebb0d7c66e21da7789b9cd35e1f99f097bdfd9b7d33", @@ -100,9 +237,21 @@ }, { "required": false, - "version": [2, 4, 3], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 4, + 3 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.4.3.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.4.3-bitcoinonly.bin", "fingerprint": "a07f69d8d2065006a79c6b5636bd046496dbcb3820b41f1d604d8a4605ca4056", @@ -112,9 +261,21 @@ }, { "required": false, - "version": [2, 4, 2], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 4, + 2 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.4.2.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.4.2-bitcoinonly.bin", "fingerprint": "54ccf155510b5292bd17ed748409d0d135112e24e62eb74184639460beecb213", @@ -124,9 +285,21 @@ }, { "required": false, - "version": [2, 4, 1], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 4, + 1 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.4.1.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.4.1-bitcoinonly.bin", "fingerprint": "84bc47bb197b3ae7bfb096f03d4a528ccf6c9ef4dfee0aac4022971e4ec91d68", @@ -136,9 +309,21 @@ }, { "required": false, - "version": [2, 4, 0], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 4, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.4.0.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.4.0-bitcoinonly.bin", "fingerprint": "d90265ee6d7d499c7d938b5322f71f27042da8a6fdaed54c224d31b65e868def", @@ -148,9 +333,21 @@ }, { "required": false, - "version": [2, 3, 6], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 6 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.6.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.6-bitcoinonly.bin", "fingerprint": "0efa3ba6135caea7693d145d60441eeb46283fe0b8b1fd59a04af33a638ad237", @@ -159,9 +356,21 @@ }, { "required": false, - "version": [2, 3, 5], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 5 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.5.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.5-bitcoinonly.bin", "fingerprint": "c0a6cacfed5c7a691314919c22307c29fbe9522071a9a28669769c014762d386", @@ -171,9 +380,21 @@ }, { "required": false, - "version": [2, 3, 4], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 4 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.4.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.4-bitcoinonly.bin", "fingerprint": "58b51a6587993965979a744f8fcd5c4761f11ce4bec6b059a5d56bd0987d6658", @@ -183,9 +404,21 @@ }, { "required": false, - "version": [2, 3, 3], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 3 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.3.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.3-bitcoinonly.bin", "fingerprint": "46326222f8afcb82e1cd07867bc3bf8836f4e9d0f367e23b58d1e9bc32cd032e", @@ -195,9 +428,21 @@ }, { "required": false, - "version": [2, 3, 2], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 2 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.2.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.2-bitcoinonly.bin", "fingerprint": "f5ccdca0cbe163ecb93df726da72b69abb93f70d24d295db00b3ca2738216160", @@ -207,9 +452,21 @@ }, { "required": false, - "version": [2, 3, 1], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 1 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.1.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.1-bitcoinonly.bin", "fingerprint": "37178a5ec24e34f8a0599aebcadaf206af3ebadef2fc596665d617dd3e05a5db", @@ -219,9 +476,21 @@ }, { "required": false, - "version": [2, 3, 0], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 3, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.3.0.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.3.0-bitcoinonly.bin", "fingerprint": "212929f63fe1393e2ff57e06537a38cff281e3cfb3a4e17235079e2f08871e6c", @@ -231,9 +500,21 @@ }, { "required": false, - "version": [2, 1, 8], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 8 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.8.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.1.8-bitcoinonly.bin", "fingerprint": "8a5fa12132651b6e33344fd025d0d90885f5cc1c342427ebcea4f0ae98b50d8c", @@ -242,9 +523,21 @@ }, { "required": false, - "version": [2, 1, 7], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 7 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.7.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.1.7-bitcoinonly.bin", "fingerprint": "acf1b4c6fec3624a8fc53f9130ff53d690c3fa1c134bd4ca3e58ee7b5a0441d8", @@ -253,9 +546,21 @@ }, { "required": false, - "version": [2, 1, 6], - "min_firmware_version": [2, 0, 8], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 6 + ], + "min_firmware_version": [ + 2, + 0, + 8 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.6.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.1.6-bitcoinonly.bin", "fingerprint": "e2032ad84108a85d4014d477b955b9181a1a56e6f222ef21bb7d47b503a02f0b", @@ -264,9 +569,21 @@ }, { "required": false, - "version": [2, 1, 5], - "min_firmware_version": [2, 1, 0], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 5 + ], + "min_firmware_version": [ + 2, + 1, + 0 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.5.bin", "url_bitcoinonly": "firmware/t2t1/trezor-t2t1-2.1.5-bitcoinonly.bin", "fingerprint": "40e4bfaf3c5ec77872c1aaaac085aafcc443f60279ca2bb38d29c669233fdf62", @@ -275,68 +592,166 @@ }, { "required": false, - "version": [2, 1, 4], - "min_firmware_version": [2, 1, 0], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 4 + ], + "min_firmware_version": [ + 2, + 1, + 0 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.4.bin", "fingerprint": "820611a92605b1ccc612b9bf8550617aec6962bd2484fcb6ae4792bc498654e4", "changelog": "* Shamir Backup with Recovery persistence\n* Touchscreen freeze fix\n* Fix display of non-divisible OMNI amounts" }, { "required": false, - "version": [2, 1, 1], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 1 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.1.bin", "fingerprint": "1b3166a878658fcd2ff82c7ac9a2587da544fd105f678cc7b4d41cba5a8d4c01", "changelog": "* Hotfix for touchscreen freeze\n* Don't rotate the screen via swipe gesture\n* Set screen rotation via user setting\n* More strict path validations\n* Display non-zero locktime values\n* EOS support\n* Monero UI fixes\n* Speed and memory optimizations" }, { "required": true, - "version": [2, 1, 0], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 1, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.1.0.bin", - "tags": ["security"], + "tags": [ + "security" + ], "fingerprint": "bb5b0308807b45d41d1e2ab66a468152997ad69a01099789d8a35e464cde999f", "notes": "https://blog.trezor.io/firmware-updates-for-trezor-one-firmware-1-8-0-and-trezor-model-t-firmware-2-1-0-b9df91e048df", "changelog": "* Security improvements\n* Upgraded to new storage format\n* Ripple, Stellar, Cardano and NEM fixes\n* New coins: ATS, AXE, FLO, GIN, KMD, NIX,\n PIVX, REOSC, XPM, XSN, ZCL\n* New ETH tokens" }, { "required": false, - "version": [2, 0, 10], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 0, + 10 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.0.10.bin", "fingerprint": "fcaa6ee206c2c121eb2d45d065d66f0879f14be45c244d4acf908be1de22275e", "changelog": "* Fix Monero payment ID computation\n* Fix issue with touch screen and flickering\n* Add support for OMNI layer: OMNI/MAID/USDT\n* Add support for new coins: BTX, CPC, GAME, RVN\n* Add support for new Ethereum tokens" }, { "required": false, - "version": [2, 0, 9], - "bootloader_version": [2, 0, 0], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 0, + 9 + ], + "bootloader_version": [ + 2, + 0, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.0.9.bin", "fingerprint": "87be93d6966e7a9eff78dc7b434d1a138ec8d1ee0300882d16f90b606f3a806b", "changelog": "* Small Monero and Segwit bugfixes" }, { "required": false, - "version": [2, 0, 8], - "bootloader_version": [2, 0, 0], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 0, + 8 + ], + "bootloader_version": [ + 2, + 0, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.0.8.bin", "fingerprint": "642b6215bda981f8eacafee34dbee5cdeee7d47d49f605bbe2828a8d9b79813d", "changelog": "* Monero support\n* Cardano support\n* Stellar support\n* Ripple support\n* Tezos support\n* Decred support\n* Groestlcoin support\n* Zencash support\n* Zcash sapling hardfork support\n* Implemented seedless setup" }, { "required": false, - "version": [2, 0, 7], - "bootloader_version": [2, 0, 0], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 0, + 7 + ], + "bootloader_version": [ + 2, + 0, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.0.7.bin", "fingerprint": "f3a42e640e526fba6574fafa520fc7d97ef9f557d24da24d9a2ea4176a4c4164", "changelog": "* Bitcoin Cash cashaddr support\n* Zcash Overwinter hardfork support\n* NEM support\n* Lisk support\n* Show warning on home screen if PIN is not set\n* Support for new coins:\n - Bitcoin Private, Fujicoin, Vertcoin, Viacoin, Zcoin\n* Support for new Ethereum networks:\n - EOS Classic, Ethereum Social, Ellaism, Callisto, EtherGem, Wanchain\n* Support for 500+ new Ethereum tokens", @@ -344,22 +759,54 @@ }, { "required": false, - "version": [2, 0, 6], - "bootloader_version": [2, 0, 0], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 0, + 6 + ], + "bootloader_version": [ + 2, + 0, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.0.6.bin", "fingerprint": "4eccabf2fd7e121ed0da657c064a65c5694402497e60ea2ac2dcf1e118db9cc6", "changelog": "* Fix layout for Ethereum transactions\n* Fix public key generation for SSH and GPG\n* Add special characters to passphrase keyboard" }, { "required": true, - "version": [2, 0, 5], - "bootloader_version": [2, 0, 0], - "min_firmware_version": [2, 0, 5], - "min_bootloader_version": [2, 0, 0], + "version": [ + 2, + 0, + 5 + ], + "bootloader_version": [ + 2, + 0, + 0 + ], + "min_firmware_version": [ + 2, + 0, + 5 + ], + "min_bootloader_version": [ + 2, + 0, + 0 + ], "url": "firmware/t2t1/trezor-t2t1-2.0.5.bin", "fingerprint": "851172eab96c07bf9efb43771cb0fd14dc0320a68de047132c7bd787a1ad64e9", "changelog": "* First public release" } -] +] \ No newline at end of file diff --git a/packages/connect/src/types/firmware.ts b/packages/connect/src/types/firmware.ts index 56037e8604d5..b1d9d1d62618 100644 --- a/packages/connect/src/types/firmware.ts +++ b/packages/connect/src/types/firmware.ts @@ -15,8 +15,8 @@ export type FirmwareRelease = { required: boolean; url: string; fingerprint: string; - changelog: string; - changelogBtcOnly?: string; // Added later, may not be there for older releases + changelog: string | string[]; + changelogBtcOnly?: string | string[]; // Added later, may not be there for older releases version: VersionArray; min_firmware_version: VersionArray; min_bootloader_version: VersionArray; diff --git a/packages/suite/src/components/firmware/FirmwareChangelog.tsx b/packages/suite/src/components/firmware/FirmwareChangelog.tsx deleted file mode 100644 index 130409472493..000000000000 --- a/packages/suite/src/components/firmware/FirmwareChangelog.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import styled from 'styled-components'; - -const ChangesUl = styled.ul` - margin-left: 16px; - - > li { - margin: 4px 0; - } -`; - -interface FirmwareChangelogProps { - changelog: string[]; -} - -export const FirmwareChangelog = ({ changelog }: FirmwareChangelogProps) => ( - {changelog.map(change => change &&
  • {change}
  • )}
    -); diff --git a/packages/suite/src/components/firmware/FirmwareOffer.tsx b/packages/suite/src/components/firmware/FirmwareOffer.tsx index c013d3996433..abd096ffe0fe 100644 --- a/packages/suite/src/components/firmware/FirmwareOffer.tsx +++ b/packages/suite/src/components/firmware/FirmwareOffer.tsx @@ -5,12 +5,11 @@ import { getFwUpdateVersion, parseFirmwareChangelog, } from '@suite-common/suite-utils'; -import { Icon, Tooltip, variables } from '@trezor/components'; +import { Icon, Markdown, Tooltip, variables } from '@trezor/components'; import { getFirmwareVersion } from '@trezor/device-utils'; import { FirmwareType } from '@trezor/connect'; import { Translation, TrezorLink } from 'src/components/suite'; -import { FirmwareChangelog } from 'src/components/firmware'; import { useFirmware, useTranslation, useSelector } from 'src/hooks/suite'; import { getSuiteFirmwareTypeString } from 'src/utils/firmware'; import { spacingsPx } from '@trezor/theme'; @@ -113,6 +112,7 @@ export const FirmwareOffer = ({ customFirmware, targetFirmwareType }: FirmwareOf {parsedChangelog ? ( @@ -131,7 +131,7 @@ export const FirmwareOffer = ({ customFirmware, targetFirmwareType }: FirmwareOf } - content={} + content={{parsedChangelog.changelog}} > {nextVersionElement} diff --git a/packages/suite/src/components/firmware/index.tsx b/packages/suite/src/components/firmware/index.tsx index 2b0498149d7e..600af5292730 100644 --- a/packages/suite/src/components/firmware/index.tsx +++ b/packages/suite/src/components/firmware/index.tsx @@ -1,6 +1,5 @@ export { CheckSeedStep } from './CheckSeedStep'; export { ReconnectDevicePrompt } from './ReconnectDevicePrompt'; -export { FirmwareChangelog } from './FirmwareChangelog'; export { FirmwareOffer } from './FirmwareOffer'; export { FirmwareInstallation } from './FirmwareInstallation'; export { FirmwareInitial } from './FirmwareInitial'; diff --git a/packages/suite/src/components/guide/GuideMarkdown.tsx b/packages/suite/src/components/guide/GuideMarkdown.tsx index 59f696170f11..b44a417ff134 100644 --- a/packages/suite/src/components/guide/GuideMarkdown.tsx +++ b/packages/suite/src/components/guide/GuideMarkdown.tsx @@ -1,78 +1,8 @@ import { useEffect, useRef } from 'react'; -import ReactMarkdown from 'react-markdown'; -import styled from 'styled-components'; - -import { variables } from '@trezor/components'; -import { TrezorLink } from 'src/components/suite'; +import { Markdown } from '@trezor/components'; import { useGuideOpenNode } from 'src/hooks/guide'; import { GuideHint } from './GuideHint'; - -const StyledMarkdown = styled.div` - color: ${({ theme }) => theme.TYPE_LIGHT_GREY}; - font-size: ${variables.FONT_SIZE.SMALL}; - font-weight: ${variables.FONT_WEIGHT.MEDIUM}; - line-height: 1.5; - padding: 0 0 32px; - - h1, - h2, - h3, - h4, - h5, - h6 { - color: ${({ theme }) => theme.TYPE_DARK_GREY}; - font-weight: ${variables.FONT_WEIGHT.DEMI_BOLD}; - } - - h1 { - margin: 8px 0 16px; - font-size: ${variables.FONT_SIZE.BIG}; - } - - h2 { - margin-bottom: 8px 0 12px; - font-size: ${variables.FONT_SIZE.NORMAL}; - } - - h3, - h4, - h5, - h6 { - margin: 4px 0 12px; - font-size: ${variables.FONT_SIZE.SMALL}; - } - - p, - ul, - ol { - margin: 4px 0 12px; - } - - ul, - ol { - padding: 0 0 0 16px; - } - - li { - margin: 0 0 8px; - } - - a { - color: ${({ theme }) => theme.TYPE_GREEN}; - - &:hover { - text-decoration: underline; - } - } - - img { - max-width: 100%; - } - - strong { - font-weight: ${variables.FONT_WEIGHT.DEMI_BOLD}; - } -`; +import { TrezorLink } from '../suite'; interface GuideMarkdownProps { markdown: string | undefined; @@ -89,9 +19,9 @@ export const GuideMarkdown = ({ markdown }: GuideMarkdownProps) => { }, [markdown, ref]); return ( - +
    {markdown && ( - { if (!href) { @@ -114,8 +44,8 @@ export const GuideMarkdown = ({ markdown }: GuideMarkdownProps) => { }} > {markdown} - + )} - +
    ); }; diff --git a/packages/suite/src/hooks/suite/useFirmware.ts b/packages/suite/src/hooks/suite/useFirmware.ts index 462af45fadff..903445b0df4d 100644 --- a/packages/suite/src/hooks/suite/useFirmware.ts +++ b/packages/suite/src/hooks/suite/useFirmware.ts @@ -28,6 +28,8 @@ export const useFirmware = () => { // Until then, access device as normal. const originalDevice = firmware.cachedDevice || device; + console.log(originalDevice); + // To instruct user to reboot to bootloader manually, UI.FIRMWARE_DISCONNECT event is emitted first, // and UI.FIRMWARE_RECONNECT is emitted after the device disconnects. const showManualReconnectPrompt = diff --git a/suite-common/suite-utils/src/__tests__/parseFirmwareChangelog.test.ts b/suite-common/suite-utils/src/__tests__/parseFirmwareChangelog.test.ts index cccd114f2b8e..2ddedaee98ff 100644 --- a/suite-common/suite-utils/src/__tests__/parseFirmwareChangelog.test.ts +++ b/suite-common/suite-utils/src/__tests__/parseFirmwareChangelog.test.ts @@ -6,6 +6,22 @@ import { ParseFirmwareChangelogResult, } from '../parseFirmwareChangelog'; +const CHANGELOG_STRING = + '* Replacement transaction signing for replace-by-fee.\n* Support for Output Descriptors export.\n* Show Ypub/Zpub correctly for multisig GetAddress.\n* Show amounts in mBTC, uBTC and sat denominations.'; + +const CHANGELOG_ARRAY = [ + '* Replacement transaction signing for replace-by-fee.', + '* Support for Output Descriptors export.', + '* Show Ypub/Zpub correctly for multisig GetAddress.', + '* Show amounts in mBTC, uBTC and sat denominations.', +]; + +const EXPECTED_STRING = + '* Replacement transaction signing for replace-by-fee.\n' + + '* Support for Output Descriptors export.\n' + + '* Show Ypub/Zpub correctly for multisig GetAddress.\n' + + '* Show amounts in mBTC, uBTC and sat denominations.'; + const releaseData: Omit = { required: false, version: [1, 9, 4], @@ -19,42 +35,42 @@ const releaseData: Omit = { notes: 'https://blog.trezor.io/trezor-suite-and-firmware-updates-rbf-and-spending-now-live-c2f69c42d7f7', }; +const resultData = { + notes: 'https://blog.trezor.io/trezor-suite-and-firmware-updates-rbf-and-spending-now-live-c2f69c42d7f7', + url: 'firmware/1/trezor-1.9.4.bin', + versionString: '1.9.4', +}; + const parseFirmwareChangelogFixture: Array<{ description: string; input: ParseFirmwareChangelogParams; result: ParseFirmwareChangelogResult | null; }> = [ { - description: 'Parse release changelog', + description: 'parses release universal changelog passed as an string', input: { - release: { - ...releaseData, - changelog: - '* Replacement transaction signing for replace-by-fee.\n* Support for Output Descriptors export.\n* Show Ypub/Zpub correctly for multisig GetAddress.\n* Show amounts in mBTC, uBTC and sat denominations.', - }, + release: { ...releaseData, changelog: CHANGELOG_STRING }, isBtcOnly: false, }, - result: { - changelog: [ - 'Replacement transaction signing for replace-by-fee.', - 'Support for Output Descriptors export.', - 'Show Ypub/Zpub correctly for multisig GetAddress.', - 'Show amounts in mBTC, uBTC and sat denominations.', - ], - notes: 'https://blog.trezor.io/trezor-suite-and-firmware-updates-rbf-and-spending-now-live-c2f69c42d7f7', - url: 'firmware/1/trezor-1.9.4.bin', - versionString: '1.9.4', - }, + result: { ...resultData, changelog: EXPECTED_STRING }, }, { - description: 'No firmware release', + description: 'return null when no release value is provided', input: { release: undefined, isBtcOnly: false, }, result: null, }, + { + description: 'parses BTC-only changelog from array of strings', + input: { + release: { ...releaseData, changelog: '', changelogBtcOnly: CHANGELOG_ARRAY }, + isBtcOnly: true, + }, + result: { ...resultData, changelog: EXPECTED_STRING }, + }, ]; describe(parseFirmwareChangelog.name, () => { diff --git a/suite-common/suite-utils/src/parseFirmwareChangelog.ts b/suite-common/suite-utils/src/parseFirmwareChangelog.ts index 73b82430079d..8fabbea90d25 100644 --- a/suite-common/suite-utils/src/parseFirmwareChangelog.ts +++ b/suite-common/suite-utils/src/parseFirmwareChangelog.ts @@ -8,35 +8,29 @@ export type ParseFirmwareChangelogParams = { export type ParseFirmwareChangelogResult = { url: string; notes: string | undefined; - changelog: string[]; + changelog: string; versionString: string; }; +type ChangelogField = keyof Pick; + export const parseFirmwareChangelog = ({ release, isBtcOnly, }: ParseFirmwareChangelogParams): ParseFirmwareChangelogResult | null => { - const changeLogField: keyof FirmwareRelease = isBtcOnly ? 'changelogBtcOnly' : 'changelog'; + const changeLogField: ChangelogField = isBtcOnly ? 'changelogBtcOnly' : 'changelog'; - if ( - release === undefined || - release[changeLogField] === undefined || - release[changeLogField]?.length === 0 - ) { + if (release === undefined || release[changeLogField] === undefined) { return null; } - // Default changelog format is a long string where individual changes are separated by "*" symbol. - const changelog = (release[changeLogField] ?? '') - .trim() - .split('*') - .map(l => l.trim()) - .filter(l => l.length); + const changelogRaw = release[changeLogField] ?? ''; + const changelogString = Array.isArray(changelogRaw) ? changelogRaw.join('\n') : changelogRaw; return { url: release.url, notes: release.notes, - changelog, + changelog: changelogString.trim(), versionString: release.version.join('.'), }; }; diff --git a/yarn.lock b/yarn.lock index e07d00107802..78f6e8c068c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10510,6 +10510,7 @@ __metadata: react-date-range: "npm:^1.4.0" react-dom: "npm:18.2.0" react-intl: "npm:^6.6.2" + react-markdown: "npm:^9.0.1" react-select: "npm:^5.8.0" react-svg: "npm:^16.1.33" react-use: "npm:^17.5.0"