summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-10-20 14:17:43 +0200
committerJoakim Hulthe <joakim.hulthe@mullvad.net>2025-10-23 10:22:59 +0200
commita0ffef71d4d9843f951353a4dc54ff82ec255782 (patch)
tree06f93f0741ea1ebdcba7289fe78db2ab1fe5315b
parent1145cd7fbd798921aca80c76f8877251532e2c71 (diff)
parentf6d7c2a6d42978c7774e682e30ef7386e6c0b3de (diff)
downloadmullvadvpn-a0ffef71d4d9843f951353a4dc54ff82ec255782.tar.xz
mullvadvpn-a0ffef71d4d9843f951353a4dc54ff82ec255782.zip
Merge branch 'improve-support-for-app-for-rollback-in-app-update-view-des-2629' into prepare-2025.13
-rw-r--r--desktop/packages/mullvad-vpn/locales/messages.pot12
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/AppUpgradeView.tsx22
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/app-upgrade-header.tsx13
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/app-upgrade-header/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/footer/components/initial-footer/components/start-upgrade/StartUpgrade.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/index.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/no-upgrade-available/no-upgrade-available.tsx48
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/UpgradeDetails.tsx82
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/index.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/use-has-upgrade.ts9
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/notifications/app-upgrade-available.ts4
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',