diff options
| author | Tobias Järvelöv <tobias.jarvelov@mullvad.net> | 2025-10-20 14:17:43 +0200 |
|---|---|---|
| committer | Joakim Hulthe <joakim.hulthe@mullvad.net> | 2025-10-23 10:22:59 +0200 |
| commit | a0ffef71d4d9843f951353a4dc54ff82ec255782 (patch) | |
| tree | 06f93f0741ea1ebdcba7289fe78db2ab1fe5315b | |
| parent | 1145cd7fbd798921aca80c76f8877251532e2c71 (diff) | |
| parent | f6d7c2a6d42978c7774e682e30ef7386e6c0b3de (diff) | |
| download | mullvadvpn-a0ffef71d4d9843f951353a4dc54ff82ec255782.tar.xz mullvadvpn-a0ffef71d4d9843f951353a4dc54ff82ec255782.zip | |
Merge branch 'improve-support-for-app-for-rollback-in-app-update-view-des-2629' into prepare-2025.13
14 files changed, 148 insertions, 56 deletions
diff --git a/desktop/packages/mullvad-vpn/locales/messages.pot b/desktop/packages/mullvad-vpn/locales/messages.pot index 2317b5923a..89cf65a2a4 100644 --- a/desktop/packages/mullvad-vpn/locales/messages.pot +++ b/desktop/packages/mullvad-vpn/locales/messages.pot @@ -383,7 +383,7 @@ msgctxt "accessibility" msgid "More information" msgstr "" -#. Accessbility label for link to go to download page. +#. Accessibility label for link to go to download page. msgctxt "accessibility" msgid "New version available, click here to go to download page, opens externally" msgstr "" @@ -771,10 +771,15 @@ msgctxt "app-upgrade-view" msgid "Installer quit unexpectedly, please try again or send a problem report." msgstr "" +#. Info about which directory the app update will be downloaded to msgctxt "app-upgrade-view" msgid "Installer will be downloaded to <b>%(cacheDir)s</b>." msgstr "" +msgctxt "app-upgrade-view" +msgid "Latest version: %(version)s" +msgstr "" + #. Text displayed when there are no updates for this platform in the next app version msgctxt "app-upgrade-view" msgid "No updates or changes were made in this release for this platform." @@ -848,6 +853,11 @@ msgctxt "app-upgrade-view" msgid "Version %(version)s" msgstr "" +#. The user has the latest version of the app and does not need to be update +msgctxt "app-upgrade-view" +msgid "You are using the latest version" +msgstr "" + msgctxt "auth-failure" msgid "Blocking internet: account is out of time" msgstr "" diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx index 61080939a6..6d06ad8faa 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx @@ -117,7 +117,7 @@ export default function NotificationArea(props: IProps) { const appUpgradeDownloadProgressValue = useAppUpgradeDownloadProgressValue(); const appUpgradeEventType = useAppUpgradeEventType(); - const appUpgradeStep = convertEventTypeToStep(appUpgradeEventType); // TODO: Remove and read value from redux + const appUpgradeStep = convertEventTypeToStep(appUpgradeEventType); const notificationProviders: InAppNotificationProvider[] = [ new ConnectingNotificationProvider({ tunnelState }), diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/AppUpgradeView.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/AppUpgradeView.tsx index 5d56347a50..f22ff484dd 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/AppUpgradeView.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/AppUpgradeView.tsx @@ -1,9 +1,16 @@ import styled from 'styled-components'; +import { messages } from '../../../../shared/gettext'; import { useHistory } from '../../../lib/history'; +import { AppNavigationHeader } from '../../app-navigation-header'; import { BackAction } from '../../KeyboardNavigation'; +import { SettingsContainer } from '../../Layout'; import { Layout } from '../../Layout'; +import { NavigationContainer } from '../../NavigationContainer'; +import { NavigationScrollbars } from '../../NavigationScrollbars'; import { Footer, UpgradeDetails } from './components'; +import { NoUpgradeAvailable } from './components/no-upgrade-available'; +import { useHasUpgrade } from './hooks'; const StyledFooter = styled.div` // TODO: Use color from Colors @@ -15,11 +22,24 @@ const StyledFooter = styled.div` export const AppUpgradeView = () => { const { pop } = useHistory(); + const hasUpgrade = useHasUpgrade(); return ( <BackAction action={pop}> <Layout> - <UpgradeDetails /> + <SettingsContainer> + <NavigationContainer> + <AppNavigationHeader + title={ + // TRANSLATORS: Title in navigation bar + messages.pgettext('app-upgrade-view', 'Update available') + } + /> + <NavigationScrollbars> + {hasUpgrade ? <UpgradeDetails /> : <NoUpgradeAvailable />} + </NavigationScrollbars> + </NavigationContainer> + </SettingsContainer> <StyledFooter> <Footer /> </StyledFooter> diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/app-upgrade-header.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/app-upgrade-header.tsx new file mode 100644 index 0000000000..c856d6cb4c --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/app-upgrade-header.tsx @@ -0,0 +1,13 @@ +import { Container } from '../../../../../lib/components'; + +export type AppUpgradeHeaderProps = { + children: React.ReactNode; +}; + +export function AppUpgradeHeader({ children }: AppUpgradeHeaderProps) { + return ( + <Container size="4" $flexDirection="column" $gap="small"> + {children} + </Container> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/index.ts new file mode 100644 index 0000000000..57bb146266 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/index.ts @@ -0,0 +1 @@ +export * from './app-upgrade-header'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/footer/components/initial-footer/components/start-upgrade/StartUpgrade.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/footer/components/initial-footer/components/start-upgrade/StartUpgrade.tsx index cf6f6562af..945064b792 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/footer/components/initial-footer/components/start-upgrade/StartUpgrade.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/footer/components/initial-footer/components/start-upgrade/StartUpgrade.tsx @@ -1,12 +1,15 @@ import { messages } from '../../../../../../../../../../shared/gettext'; import { Flex } from '../../../../../../../../../lib/components'; +import { useHasUpgrade } from '../../../../../../hooks'; import { UpgradeButton } from '../../../../../upgrade-button'; export function StartUpgrade() { + const hasUpgrade = useHasUpgrade(); + return ( <Flex $padding="large" $flexDirection="column"> <Flex $flexDirection="column"> - <UpgradeButton> + <UpgradeButton disabled={!hasUpgrade}> { // TRANSLATORS: Button text to download and install an update messages.pgettext('app-upgrade-view', 'Download & install') diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/index.ts index f90ad28315..cf0381de3b 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/index.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/index.ts @@ -1,7 +1,9 @@ +export * from './app-upgrade-header'; export * from './connection-blocked-label'; export * from './download-progress'; export * from './footer'; export * from './launch-installer-button'; +export * from './no-upgrade-available'; export * from './pause-button'; export * from './resume-button'; export * from './upgrade-button'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/index.ts new file mode 100644 index 0000000000..0b9b0d5d64 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/index.ts @@ -0,0 +1 @@ +export * from './no-upgrade-available'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/no-upgrade-available.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/no-upgrade-available.tsx new file mode 100644 index 0000000000..2ac7f09f86 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/no-upgrade-available.tsx @@ -0,0 +1,48 @@ +import { sprintf } from 'sprintf-js'; + +import { messages } from '../../../../../../shared/gettext'; +import { TitleBig } from '../../../../../lib/components'; +import { EmptyState } from '../../../../../lib/components/empty-state'; +import { useVersionCurrent } from '../../../../../redux/hooks'; +import { AppUpgradeHeader } from '../app-upgrade-header'; + +export function NoUpgradeAvailable() { + const { current } = useVersionCurrent(); + + return ( + <AppUpgradeHeader> + <TitleBig as="h2"> + { + // TRANSLATORS: Main title for the update available view + messages.pgettext('app-upgrade-view', 'Update available') + } + </TitleBig> + <EmptyState + variant="success" + $alignSelf="stretch" + $margin={{ + top: 'medium', + }}> + <EmptyState.StatusIcon /> + <EmptyState.TextContainer> + <EmptyState.Title> + { + // TRANSLATORS: The user has the latest version of the app and does not need to be update + messages.pgettext('app-upgrade-view', 'You are using the latest version') + } + </EmptyState.Title> + <EmptyState.Subtitle> + { + // TRANSLATORS: The the latest version of the app + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(version)s - The version number of the latest app version + sprintf(messages.pgettext('app-upgrade-view', 'Latest version: %(version)s'), { + version: current, + }) + } + </EmptyState.Subtitle> + </EmptyState.TextContainer> + </EmptyState> + </AppUpgradeHeader> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/UpgradeDetails.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/UpgradeDetails.tsx index 4d227496de..a717e609fa 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/UpgradeDetails.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/UpgradeDetails.tsx @@ -3,12 +3,9 @@ import { sprintf } from 'sprintf-js'; import { messages } from '../../../../../../shared/gettext'; import { Container, Flex, TitleBig, TitleLarge } from '../../../../../lib/components'; import { formatHtml } from '../../../../../lib/html-formatter'; -import { AppNavigationHeader } from '../../../../app-navigation-header'; import { ChangelogList } from '../../../../changelog-list'; -import { SettingsContainer } from '../../../../Layout'; -import { NavigationContainer } from '../../../../NavigationContainer'; -import { NavigationScrollbars } from '../../../../NavigationScrollbars'; import { HeaderSubTitle } from '../../../../SettingsHeader'; +import { AppUpgradeHeader } from '../app-upgrade-header'; import { NoChangelogUpdates } from './components'; import { useCacheDir, useChangelog, useShowChangelogList, useTitle } from './hooks'; @@ -18,53 +15,40 @@ export function UpgradeDetails() { const title = useTitle(); const cacheDir = useCacheDir(); + const showHeaderSubtitle = cacheDir !== undefined; + return ( - <SettingsContainer> - <NavigationContainer> - <AppNavigationHeader - title={ - // TRANSLATORS: Title in navigation bar + <Flex $flexDirection="column" $gap="large" $padding={{ bottom: 'medium' }}> + <AppUpgradeHeader> + <TitleBig as="h2"> + { + // TRANSLATORS: Main title for the update available view messages.pgettext('app-upgrade-view', 'Update available') } - /> - <NavigationScrollbars> - <Flex $flexDirection="column" $gap="large" $padding={{ bottom: 'medium' }}> - <Container size="4" $flexDirection="column" $gap="small"> - <TitleBig as="h2"> - { - // TRANSLATORS: Main title for the update available view - messages.pgettext('app-upgrade-view', 'Update available') - } - </TitleBig> - {cacheDir !== undefined && ( - <HeaderSubTitle> - {formatHtml( - sprintf( - messages.pgettext( - 'app-upgrade-view', - 'Installer will be downloaded to <b>%(cacheDir)s</b>.', - ), - { cacheDir }, - ), - )} - </HeaderSubTitle> - )} - </Container> - <Flex $flexDirection="column" $gap="small"> - <Container size="4"> - <TitleLarge as="h2">{title}</TitleLarge> - </Container> - <Container size="3" $flexDirection="column"> - {showChangelogList ? ( - <ChangelogList changelog={changelog} /> - ) : ( - <NoChangelogUpdates /> - )} - </Container> - </Flex> - </Flex> - </NavigationScrollbars> - </NavigationContainer> - </SettingsContainer> + </TitleBig> + {showHeaderSubtitle && ( + <HeaderSubTitle> + {formatHtml( + sprintf( + // TRANSLATORS: Info about which directory the app update will be downloaded to + messages.pgettext( + 'app-upgrade-view', + 'Installer will be downloaded to <b>%(cacheDir)s</b>.', + ), + { cacheDir }, + ), + )} + </HeaderSubTitle> + )} + </AppUpgradeHeader> + <Flex $flexDirection="column" $gap="small"> + <Container size="4"> + <TitleLarge as="h2">{title}</TitleLarge> + </Container> + <Container size="3" $flexDirection="column"> + {showChangelogList ? <ChangelogList changelog={changelog} /> : <NoChangelogUpdates />} + </Container> + </Flex> + </Flex> ); } diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/index.ts index 158c43eeac..50bbcb7cd2 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/index.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/index.ts @@ -1,4 +1,4 @@ +export * from './useCacheDir'; export * from './useChangelog'; export * from './useShowChangelogList'; -export * from './useCacheDir'; export * from './useTitle'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/index.ts index edb9a49686..2d489381c9 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/index.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/index.ts @@ -1 +1,2 @@ +export * from './use-has-upgrade'; export * from './useErrorCountExceeded'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/use-has-upgrade.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/use-has-upgrade.ts new file mode 100644 index 0000000000..013df2c9b7 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/use-has-upgrade.ts @@ -0,0 +1,9 @@ +import { useVersionSuggestedUpgrade } from '../../../../redux/hooks'; + +export function useHasUpgrade() { + const { suggestedUpgrade } = useVersionSuggestedUpgrade(); + + const hasUpgrade = suggestedUpgrade !== undefined; + + return hasUpgrade; +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/app-upgrade-available.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/app-upgrade-available.ts index a87d260d1a..4d45c1ac17 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/app-upgrade-available.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/app-upgrade-available.ts @@ -50,7 +50,7 @@ export class AppUpgradeAvailableNotificationProvider implements InAppNotificatio link: { to: getDownloadUrl(suggestedIsBeta ?? false), 'aria-label': - // TRANSLATORS: Accessbility label for link to go to download page. + // TRANSLATORS: Accessibility label for link to go to download page. messages.pgettext( 'accessibility', 'New version available, click here to go to download page, opens externally', @@ -61,7 +61,7 @@ export class AppUpgradeAvailableNotificationProvider implements InAppNotificatio type: 'navigate-internal', link: { to: RoutePath.appUpgrade, - // TRANSLATORS: Accessbility label for link to go to upgrade view. + // TRANSLATORS: Accessibility label for link to go to upgrade view. 'aria-label': messages.pgettext( 'accessibility', 'New version available, click here to go to update view', |
