Skip to content

Commit

Permalink
feat(mobile): FW update changelog (#16205)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nodonisko authored Jan 30, 2025
1 parent 4387e33 commit 313c85a
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 1 deletion.
11 changes: 11 additions & 0 deletions suite-common/wallet-core/src/device/deviceReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1036,3 +1036,14 @@ export const selectDeviceUpdateFirmwareVersion = (state: DeviceRootState) => {

return device ? getFwUpdateVersion(device) : null;
};

export const selectFirmwareChangelog = (state: DeviceRootState) => {
const device = selectSelectedDevice(state);
const isBitcoinOnlyFirmware = selectHasBitcoinOnlyFirmware(state);

if (isBitcoinOnlyFirmware) {
return device?.firmwareRelease?.changelog?.[0]?.changelog_bitcoinonly;
}

return device?.firmwareRelease?.changelog?.[0]?.changelog;
};
6 changes: 6 additions & 0 deletions suite-native/intl/src/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,12 @@ 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?',
closeButton: 'Close',
changelogUnavailable: 'No changelog available',
},
},
firmwareUpdateProgress: {
initializing: { title: 'Preparing your Trezor' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
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 <Text style={applyStyle(changelogSectionTitleTextStyle)}>{children}</Text>;
};

export const FirmwareChangelog = ({ isVisible, onClose }: FirmwareChangelogProps) => {
const firmwareChangelog = useSelector(selectFirmwareChangelog);
const { applyStyle } = useNativeStyles();

const formattedChangelog = useMemo(() => {
if (!firmwareChangelog) {
return (
<Text>
<Translation id="moduleDeviceSettings.firmware.firmwareUpdateScreen.changelog.changelogUnavailable" />
</Text>
);
}

let firmwareChangelogLines: string[] = [];
if (typeof firmwareChangelog === 'string') {
firmwareChangelogLines = firmwareChangelog.split('\n');
} else {
firmwareChangelogLines = firmwareChangelog;
}

return firmwareChangelogLines.map((text, index) => {
const key = text + index;

// Match any number of '#' at the start of the line followed by text
if (/^#+\s*(.+)/.test(text)) {
const strippedText = text.replace(/^#+\s*/, '').trim();

return <ChangelogSectionTitle key={key}>{strippedText}</ChangelogSectionTitle>;
}

// Match common list item markers with optional spaces
const listItemRegex = /^\s*[-+*]\s+(.+)/;
if (listItemRegex.test(text)) {
const formattedText = text.replace(listItemRegex, ' • $1');

return <Text key={key}>{formattedText}</Text>;
}

return <Text key={key}>{text}</Text>;
});
}, [firmwareChangelog]);

return (
<BottomSheet isVisible={isVisible} onClose={onClose} isScrollable isCloseDisplayed={false}>
<Text variant="titleSmall" color="textDefault">
<Translation id="moduleDeviceSettings.firmware.firmwareUpdateScreen.changelog.title" />
</Text>
{formattedChangelog}
<Button
onPress={onClose}
style={applyStyle(buttonContainerStyle)}
colorScheme="tertiaryElevation0"
>
<Translation id="moduleDeviceSettings.firmware.firmwareUpdateScreen.changelog.closeButton" />
</Button>
</BottomSheet>
);
};
Original file line number Diff line number Diff line change
@@ -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 (
<>
<TouchableOpacity style={applyStyle(linkContainerStyle)} onPress={handlePress}>
<Icon name="question" size="medium" color="iconSubdued" />
<Text variant="body" color="textSubdued" style={applyStyle(linkTextStyle)}>
<Translation id="moduleDeviceSettings.firmware.firmwareUpdateScreen.changelog.button" />
</Text>
</TouchableOpacity>
<FirmwareChangelog isVisible={isVisible} onClose={handleClose} />
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -86,7 +87,8 @@ export const FirmwareUpdateScreen = () => {
<Translation id="moduleDeviceSettings.firmware.firmwareUpdateScreen.subtitle" />
</Text>
</Box>
<FirmwareUpdateVersionCard marginTop="sp32" />
<FirmwareUpdateVersionCard marginTop="sp32" marginBottom="sp12" />
<FirmwareChangelogButton />
</Screen>
);
};

0 comments on commit 313c85a

Please sign in to comment.