diff --git a/suite-common/wallet-core/src/device/deviceReducer.ts b/suite-common/wallet-core/src/device/deviceReducer.ts index 8a45197661f..34c4d2a1c61 100644 --- a/suite-common/wallet-core/src/device/deviceReducer.ts +++ b/suite-common/wallet-core/src/device/deviceReducer.ts @@ -1036,3 +1036,9 @@ export const selectDeviceUpdateFirmwareVersion = (state: DeviceRootState) => { return device ? getFwUpdateVersion(device) : null; }; + +export const selectFirmwareChangelog = (state: DeviceRootState) => { + const device = selectSelectedDevice(state); + + return device?.firmwareRelease?.changelog?.[0]?.changelog; +}; diff --git a/suite-native/intl/src/en.ts b/suite-native/intl/src/en.ts index dc1020dc4e3..6c6f1714470 100644 --- a/suite-native/intl/src/en.ts +++ b/suite-native/intl/src/en.ts @@ -415,6 +415,11 @@ export const en = { updateButton: 'Update firmware', title: 'Firmware update', subtitle: 'New firmware is now available. Update your device now.', + changelog: { + button: 'What’s new?', + title: 'What’s new?', + changelogUnavailable: 'No changelog available', + }, }, firmwareUpdateProgress: { initializing: { title: 'Preparing your Trezor' }, diff --git a/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareChangelog.tsx b/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareChangelog.tsx new file mode 100644 index 00000000000..03d6779176b --- /dev/null +++ b/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareChangelog.tsx @@ -0,0 +1,80 @@ +import { useMemo } from 'react'; +import { useSelector } from 'react-redux'; + +import { BottomSheet, Button, Text } from '@suite-native/atoms'; +import { selectFirmwareChangelog } from '@suite-common/wallet-core'; +import { Translation } from '@suite-native/intl'; +import { prepareNativeStyle, useNativeStyles } from '@trezor/styles'; + +type FirmwareChangelogProps = { + isVisible: boolean; + onClose: () => void; +}; + +const changelogSectionTitleTextStyle = prepareNativeStyle(utils => ({ + ...utils.typography.highlight, + paddingTop: utils.spacings.sp24, +})); + +const buttonContainerStyle = prepareNativeStyle(utils => ({ + marginTop: utils.spacings.sp32, +})); + +const ChangelogSectionTitle = ({ children }: { children: React.ReactNode }) => { + const { applyStyle } = useNativeStyles(); + + return {children}; +}; + +export const FirmwareChangelog = ({ isVisible, onClose }: FirmwareChangelogProps) => { + const firmwareChangelog = useSelector(selectFirmwareChangelog); + const { applyStyle } = useNativeStyles(); + + const formattedChangelog = useMemo(() => { + if (!firmwareChangelog) { + return ( + + + + ); + } + + if (typeof firmwareChangelog === 'string') { + return {firmwareChangelog}; + } + + return firmwareChangelog.map((text, index) => { + const key = text + index; + + if (text.startsWith('#')) { + const strippedText = text.replaceAll('#', '').trim(); + + return {strippedText}; + } + + let formattedText = text; + + if (text.startsWith(' - ')) { + formattedText = formattedText.replace(' - ', ' • '); + } + + return {formattedText}; + }); + }, [firmwareChangelog]); + + return ( + + + + + {formattedChangelog} + + + ); +}; diff --git a/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareChangelogButton.tsx b/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareChangelogButton.tsx new file mode 100644 index 00000000000..986a75c0a8a --- /dev/null +++ b/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareChangelogButton.tsx @@ -0,0 +1,46 @@ +import { TouchableOpacity } from 'react-native'; +import { useState } from 'react'; + +import { Text } from '@suite-native/atoms'; +import { Translation } from '@suite-native/intl'; +import { Icon } from '@suite-native/icons'; +import { prepareNativeStyle, useNativeStyles } from '@trezor/styles'; + +import { FirmwareChangelog } from './FirmwareChangelog'; + +const linkTextStyle = prepareNativeStyle(utils => ({ + color: utils.colors.textSubdued, + textDecorationLine: 'underline', +})); + +const linkContainerStyle = prepareNativeStyle(_utils => ({ + alignItems: 'center', + flexDirection: 'row', + justifyContent: 'flex-end', + gap: 2, +})); + +export const FirmwareChangelogButton = () => { + const { applyStyle } = useNativeStyles(); + const [isVisible, setIsVisible] = useState(false); + + const handlePress = () => { + setIsVisible(true); + }; + + const handleClose = () => { + setIsVisible(false); + }; + + return ( + <> + + + + + + + + + ); +}; diff --git a/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareUpdateScreen.tsx b/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareUpdateScreen.tsx index d6f83caa6af..f1941a8d0b7 100644 --- a/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareUpdateScreen.tsx +++ b/suite-native/module-device-settings/src/screens/FirmwareUpdateScreen/FirmwareUpdateScreen.tsx @@ -23,6 +23,7 @@ import { useAlert } from '@suite-native/alerts'; import { useIsFirmwareUpdateFeatureEnabled } from '@suite-native/firmware'; import { FirmwareUpdateVersionCard } from './FirmwareVersionCard'; +import { FirmwareChangelogButton } from './FirmwareChangelogButton'; const firmwareUpdateButtonStyle = prepareNativeStyle(utils => ({ marginHorizontal: utils.spacings.sp16, @@ -85,7 +86,8 @@ export const FirmwareUpdateScreen = () => { - + + ); };