diff options
| author | Tobias Järvelöv <tobias.jarvelov@mullvad.net> | 2025-04-04 17:10:55 +0200 |
|---|---|---|
| committer | Sebastian Holmin <sebastian.holmin@mullvad.net> | 2025-05-28 13:25:24 +0200 |
| commit | 77b8433a08a6610e668de657fe1ff9fdaa421504 (patch) | |
| tree | 0c8720d403127c8159455894904b63abd78e8e91 | |
| parent | 1ad02949c426ccd72f0036319c7259a185148502 (diff) | |
| download | mullvadvpn-77b8433a08a6610e668de657fe1ff9fdaa421504.tar.xz mullvadvpn-77b8433a08a6610e668de657fe1ff9fdaa421504.zip | |
Add app-upgrade view
71 files changed, 875 insertions, 0 deletions
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 new file mode 100644 index 0000000000..0febc7a44c --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/AppUpgradeView.tsx @@ -0,0 +1,74 @@ +import styled from 'styled-components'; + +import { Flex } from '../../../lib/components'; +import { Animate } from '../../../lib/components/animate'; +import { useHistory } from '../../../lib/history'; +import { BackAction } from '../../KeyboardNavigation'; +import { Layout } from '../../Layout'; +import { + CancelButton, + DownloadProgress, + InstallButton, + ReportProblemButton, + RetryUpgradeButton, + UpgradeButton, + UpgradeDetails, + UpgradeLabel, +} from './components'; +import { + usePresent, + useShowCancelButton, + useShowDownloadProgress, + useShowInstallButton, + useShowReportProblemButton, + useShowRetryUpgradeButton, + useShowUpgradeButton, + useShowUpgradeLabel, +} from './hooks'; + +const StyledFooter = styled.div` + // TODO: Use color from Colors + background-color: rgba(21, 39, 58, 1); + position: sticky; + bottom: 0; + width: 100%; +`; + +export const AppUpgradeView = () => { + const { pop } = useHistory(); + const present = usePresent(); + const showCancelButton = useShowCancelButton(); + const showDownloadProgress = useShowDownloadProgress(); + const showInstallButton = useShowInstallButton(); + const showReportProblemButton = useShowReportProblemButton(); + const showRetryUpgradeButton = useShowRetryUpgradeButton(); + const showUpgradeButton = useShowUpgradeButton(); + const showUpgradeLabel = useShowUpgradeLabel(); + + return ( + <BackAction action={pop}> + <Layout> + <UpgradeDetails /> + <StyledFooter> + <Flex $padding="large" $flexDirection="column"> + <Animate + animations={[{ type: 'fade' }, { type: 'wipe', direction: 'vertical' }]} + present={present}> + <Flex $gap="medium" $flexDirection="column" $margin={{ bottom: 'medium' }}> + {showUpgradeLabel && <UpgradeLabel />} + {showDownloadProgress && <DownloadProgress />} + </Flex> + </Animate> + <Flex $gap="medium" $flexDirection="column"> + {showReportProblemButton && <ReportProblemButton />} + {showRetryUpgradeButton && <RetryUpgradeButton />} + {showUpgradeButton && <UpgradeButton />} + {showInstallButton && <InstallButton />} + {showCancelButton && <CancelButton />} + </Flex> + </Flex> + </StyledFooter> + </Layout> + </BackAction> + ); +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/CancelButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/CancelButton.tsx new file mode 100644 index 0000000000..b04e84ccbf --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/CancelButton.tsx @@ -0,0 +1,20 @@ +import { messages } from '../../../../../../shared/gettext'; +import { useAppContext } from '../../../../../context'; +import { Button } from '../../../../../lib/components'; +import { useDisabled } from './hooks'; + +export function CancelButton() { + const disabled = useDisabled(); + const { appUpgradeAbort } = useAppContext(); + + return ( + <Button disabled={disabled} onClick={appUpgradeAbort}> + <Button.Text> + { + // TRANSLATORS: Button text to cancel the download of an update + messages.pgettext('app-upgrade-view', 'Cancel') + } + </Button.Text> + </Button> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/hooks/index.ts new file mode 100644 index 0000000000..73e963a519 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/hooks/index.ts @@ -0,0 +1 @@ +export * from './useDisabled'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/hooks/useDisabled.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/hooks/useDisabled.ts new file mode 100644 index 0000000000..11b4742b5b --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/hooks/useDisabled.ts @@ -0,0 +1,13 @@ +import { useAppUpgradeEventType } from '../../../../../../hooks'; + +export const useDisabled = () => { + const appUpgradeEventType = useAppUpgradeEventType(); + + switch (appUpgradeEventType) { + case 'APP_UPGRADE_STATUS_DOWNLOAD_PROGRESS': + case 'APP_UPGRADE_STATUS_DOWNLOAD_STARTED': + return false; + default: + return true; + } +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/index.ts new file mode 100644 index 0000000000..886c5b0107 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/cancel-button/index.ts @@ -0,0 +1 @@ +export * from './CancelButton'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/DownloadProgress.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/DownloadProgress.tsx new file mode 100644 index 0000000000..fd1a60a0fa --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/DownloadProgress.tsx @@ -0,0 +1,20 @@ +import { useAppUpgradeDownloadProgressValue } from '../../../../../hooks'; +import { Progress } from '../../../../../lib/components/progress'; +import { useMessage } from './hooks'; + +export function DownloadProgress() { + const message = useMessage(); + const value = useAppUpgradeDownloadProgressValue(); + + return ( + <Progress value={value}> + <Progress.Track> + <Progress.Range /> + </Progress.Track> + <Progress.Footer> + <Progress.Percent /> + <Progress.Text>{message}</Progress.Text> + </Progress.Footer> + </Progress> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/index.ts new file mode 100644 index 0000000000..107ba71afc --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/index.ts @@ -0,0 +1 @@ +export * from './useMessage'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/index.ts new file mode 100644 index 0000000000..22e7b37790 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/index.ts @@ -0,0 +1,2 @@ +export * from './useGetMessageError'; +export * from './useGetMessageTimeLeft'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/useGetMessageError.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/useGetMessageError.ts new file mode 100644 index 0000000000..40362deffa --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/useGetMessageError.ts @@ -0,0 +1,21 @@ +import { messages } from '../../../../../../../../../shared/gettext'; +import { useAppUpgradeError } from '../../../../../../../../redux/hooks'; + +export const useGetMessageError = () => { + const { appUpgradeError } = useAppUpgradeError(); + + const getMessageError = () => { + if ( + appUpgradeError === 'START_INSTALLER_FAILED' || + appUpgradeError === 'START_INSTALLER_AUTOMATIC_FAILED' || + appUpgradeError === 'VERIFICATION_FAILED' + ) { + // TRANSLATORS: Status text displayed below a progress bar when the download of an update is complete + return messages.pgettext('app-upgrade-view', 'Download complete!'); + } + + return null; + }; + + return getMessageError; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/useGetMessageTimeLeft.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/useGetMessageTimeLeft.ts new file mode 100644 index 0000000000..ee2bd530d5 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/hooks/useGetMessageTimeLeft.ts @@ -0,0 +1,42 @@ +import { sprintf } from 'sprintf-js'; + +import { messages } from '../../../../../../../../../shared/gettext'; +import { useAppUpgradeEvent } from '../../../../../../../../redux/hooks'; + +export const useGetMessageTimeLeft = () => { + const { appUpgradeEvent } = useAppUpgradeEvent(); + + const getMessageTimeLeft = () => { + if (appUpgradeEvent?.type === 'APP_UPGRADE_STATUS_DOWNLOAD_PROGRESS') { + const { timeLeft } = appUpgradeEvent; + + if (timeLeft > 90) { + const minutes = Math.round(timeLeft / 60); + + return sprintf( + // TRANSLATORS: Status text displayed below a progress bar when the update is being downloaded + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(minutes)s - Will be replaced with remaining minutes until download is complete + messages.pgettext('app-upgrade-view', 'About %(minutes)s minutes remaining...'), + { + minutes, + }, + ); + } + + return sprintf( + // TRANSLATORS: Status text displayed below a progress bar when the update is being downloaded + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(second)s - Will be replaced with remaining seconds until download is complete + messages.pgettext('app-upgrade-view', 'About %(seconds)s seconds remaining...'), + { + seconds: timeLeft, + }, + ); + } + + return null; + }; + + return getMessageTimeLeft; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/index.ts new file mode 100644 index 0000000000..107ba71afc --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/index.ts @@ -0,0 +1 @@ +export * from './useMessage'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/useMessage.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/useMessage.ts new file mode 100644 index 0000000000..711a9f9653 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/hooks/useMessage/useMessage.ts @@ -0,0 +1,37 @@ +import { messages } from '../../../../../../../../shared/gettext'; +import { useAppUpgradeEventType, useHasAppUpgradeError } from '../../../../../../../hooks'; +import { useConnectionIsBlocked } from '../../../../../../../redux/hooks'; +import { useGetMessageError, useGetMessageTimeLeft } from './hooks'; + +export const useMessage = () => { + const { isBlocked } = useConnectionIsBlocked(); + const appUpgradeEventType = useAppUpgradeEventType(); + const getMessageError = useGetMessageError(); + const getMessageTimeLeft = useGetMessageTimeLeft(); + const hasAppUpgradeError = useHasAppUpgradeError(); + + if (isBlocked) { + // TRANSLATORS: Status text displayed below a progress bar when the download of an update has been paused + return messages.pgettext('app-upgrade-view', 'Download paused'); + } + + if (hasAppUpgradeError) { + return getMessageError(); + } + + switch (appUpgradeEventType) { + case 'APP_UPGRADE_STATUS_DOWNLOAD_STARTED': + // TRANSLATORS: Status text displayed below a progress bar when the download of an update is starting + return messages.pgettext('app-upgrade-view', 'Starting download...'); + case 'APP_UPGRADE_STATUS_DOWNLOAD_PROGRESS': + return getMessageTimeLeft(); + case 'APP_UPGRADE_STATUS_STARTED_INSTALLER': + case 'APP_UPGRADE_STATUS_STARTING_INSTALLER': + case 'APP_UPGRADE_STATUS_VERIFIED_INSTALLER': + case 'APP_UPGRADE_STATUS_VERIFYING_INSTALLER': + // TRANSLATORS: Status text displayed below a progress bar when the download of an update is complete + return messages.pgettext('app-upgrade-view', 'Download complete!'); + default: + return null; + } +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/index.ts new file mode 100644 index 0000000000..213bb26f82 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/download-progress/index.ts @@ -0,0 +1 @@ +export * from './DownloadProgress'; 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 new file mode 100644 index 0000000000..b38a80c80e --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/index.ts @@ -0,0 +1,8 @@ +export * from './cancel-button'; +export * from './download-progress'; +export * from './install-button'; +export * from './report-problem-button'; +export * from './retry-upgrade-button'; +export * from './upgrade-button'; +export * from './upgrade-details'; +export * from './upgrade-label'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/install-button/InstallButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/install-button/InstallButton.tsx new file mode 100644 index 0000000000..eeaec246d8 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/install-button/InstallButton.tsx @@ -0,0 +1,18 @@ +import { messages } from '../../../../../../shared/gettext'; +import { useAppContext } from '../../../../../context'; +import { Button } from '../../../../../lib/components'; + +export function InstallButton() { + const { appUpgradeInstallerStart } = useAppContext(); + + return ( + <Button onClick={appUpgradeInstallerStart}> + <Button.Text> + { + // TRANSLATORS: Button text to install an update + messages.pgettext('app-upgrade-view', 'Install update') + } + </Button.Text> + </Button> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/install-button/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/install-button/index.ts new file mode 100644 index 0000000000..5e616d2943 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/install-button/index.ts @@ -0,0 +1 @@ +export * from './InstallButton'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/report-problem-button/ReportProblemButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/report-problem-button/ReportProblemButton.tsx new file mode 100644 index 0000000000..e04762a42c --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/report-problem-button/ReportProblemButton.tsx @@ -0,0 +1,20 @@ +import { messages } from '../../../../../../shared/gettext'; +import { usePushProblemReport } from '../../../../../history/hooks'; +import { Button } from '../../../../../lib/components'; + +export function ReportProblemButton() { + const pushProblemReport = usePushProblemReport({ + search: '?suppress-outdated-version-warning=true', + }); + + return ( + <Button onClick={pushProblemReport}> + <Button.Text> + { + // TRANSLATORS: Button text to report a problem + messages.pgettext('app-upgrade-view', 'Report a problem') + } + </Button.Text> + </Button> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/report-problem-button/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/report-problem-button/index.ts new file mode 100644 index 0000000000..808f304f69 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/report-problem-button/index.ts @@ -0,0 +1 @@ +export * from './ReportProblemButton'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/RetryUpgradeButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/RetryUpgradeButton.tsx new file mode 100644 index 0000000000..7c51580a7e --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/RetryUpgradeButton.tsx @@ -0,0 +1,20 @@ +import { messages } from '../../../../../../shared/gettext'; +import { useAppContext } from '../../../../../context'; +import { Button } from '../../../../../lib/components'; +import { useDisabled } from './hooks'; + +export function RetryUpgradeButton() { + const { appUpgrade } = useAppContext(); + const disabled = useDisabled(); + + return ( + <Button disabled={disabled} onClick={appUpgrade}> + <Button.Text> + { + // TRANSLATORS: Button text to retry download of an update + messages.pgettext('app-upgrade-view', 'Retry download') + } + </Button.Text> + </Button> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/hooks/index.ts new file mode 100644 index 0000000000..73e963a519 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/hooks/index.ts @@ -0,0 +1 @@ +export * from './useDisabled'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/hooks/useDisabled.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/hooks/useDisabled.ts new file mode 100644 index 0000000000..e41c5b12ff --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/hooks/useDisabled.ts @@ -0,0 +1,9 @@ +import { useConnectionIsBlocked } from '../../../../../../redux/hooks'; + +export const useDisabled = () => { + const { isBlocked } = useConnectionIsBlocked(); + + const disabled = isBlocked; + + return disabled; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/index.ts new file mode 100644 index 0000000000..4aebbc2d17 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/retry-upgrade-button/index.ts @@ -0,0 +1 @@ +export * from './RetryUpgradeButton'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/UpgradeButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/UpgradeButton.tsx new file mode 100644 index 0000000000..69380f71a6 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/UpgradeButton.tsx @@ -0,0 +1,20 @@ +import { messages } from '../../../../../../shared/gettext'; +import { useAppContext } from '../../../../../context'; +import { Button } from '../../../../../lib/components'; +import { useDisabled } from './hooks'; + +export function UpgradeButton() { + const { appUpgrade } = useAppContext(); + const disabled = useDisabled(); + + return ( + <Button disabled={disabled} onClick={appUpgrade}> + <Button.Text> + { + // TRANSLATORS: Button text to download and install an update + messages.pgettext('app-upgrade-view', 'Download and install') + } + </Button.Text> + </Button> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/hooks/index.ts new file mode 100644 index 0000000000..73e963a519 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/hooks/index.ts @@ -0,0 +1 @@ +export * from './useDisabled'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/hooks/useDisabled.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/hooks/useDisabled.ts new file mode 100644 index 0000000000..e41c5b12ff --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/hooks/useDisabled.ts @@ -0,0 +1,9 @@ +import { useConnectionIsBlocked } from '../../../../../../redux/hooks'; + +export const useDisabled = () => { + const { isBlocked } = useConnectionIsBlocked(); + + const disabled = isBlocked; + + return disabled; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/index.ts new file mode 100644 index 0000000000..472b50ea34 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-button/index.ts @@ -0,0 +1 @@ +export * from './UpgradeButton'; 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 new file mode 100644 index 0000000000..00cc856c6c --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/UpgradeDetails.tsx @@ -0,0 +1,50 @@ +import { messages } from '../../../../../../shared/gettext'; +import { Container, Flex, TitleBig, TitleLarge } from '../../../../../lib/components'; +import { AppNavigationHeader } from '../../../../app-navigation-header'; +import { ChangelogList } from '../../../../changelog-list'; +import { SettingsContainer } from '../../../../Layout'; +import { NavigationContainer } from '../../../../NavigationContainer'; +import { NavigationScrollbars } from '../../../../NavigationScrollbars'; +import { NoChangelogUpdates } from './components'; +import { useChangelog, useShowChangelogList, useShowNoChangelogUpdates, useTitle } from './hooks'; + +export function UpgradeDetails() { + const changelog = useChangelog(); + const showChangelogList = useShowChangelogList(); + const showNoChangelogUpdates = useShowNoChangelogUpdates(); + const title = useTitle(); + + return ( + <SettingsContainer> + <NavigationContainer> + <AppNavigationHeader + title={ + // TRANSLATORS: Title in navigation bar + messages.pgettext('app-upgrade-view', 'Update available') + } + /> + <NavigationScrollbars> + <Flex $flexDirection="column" $gap="large" $padding={{ bottom: 'medium' }}> + <Container size="4"> + <TitleBig as="h2"> + { + // TRANSLATORS: Main title for the update available view + messages.pgettext('app-upgrade-view', 'Update available') + } + </TitleBig> + </Container> + <Flex $flexDirection="column" $gap="small"> + <Container size="4"> + <TitleLarge as="h2">{title}</TitleLarge> + </Container> + <Container size="3" $flexDirection="column"> + {showChangelogList && <ChangelogList changelog={changelog} />} + {showNoChangelogUpdates && <NoChangelogUpdates />} + </Container> + </Flex> + </Flex> + </NavigationScrollbars> + </NavigationContainer> + </SettingsContainer> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/index.ts new file mode 100644 index 0000000000..e838cd8521 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/index.ts @@ -0,0 +1 @@ +export * from './no-changelog-updates'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/no-changelog-updates/NoChangelogUpdates.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/no-changelog-updates/NoChangelogUpdates.tsx new file mode 100644 index 0000000000..d9179e3029 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/no-changelog-updates/NoChangelogUpdates.tsx @@ -0,0 +1,17 @@ +import { messages } from '../../../../../../../../shared/gettext'; +import { BodySmall } from '../../../../../../../lib/components'; +import { Colors } from '../../../../../../../lib/foundations'; + +export function NoChangelogUpdates() { + return ( + <BodySmall color={Colors.white60}> + { + // TRANSLATORS: Text displayed when there are no updates for this platform in the next app version + messages.pgettext( + 'app-upgrade-view', + 'No updates or changes were made in this release for this platform.', + ) + } + </BodySmall> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/no-changelog-updates/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/no-changelog-updates/index.ts new file mode 100644 index 0000000000..095239a335 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/components/no-changelog-updates/index.ts @@ -0,0 +1 @@ +export * from './NoChangelogUpdates'; 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 new file mode 100644 index 0000000000..91bafea1fb --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/index.ts @@ -0,0 +1,5 @@ +export * from './useChangelog'; +export * from './useHasChangelog'; +export * from './useShowChangelogList'; +export * from './useShowNoChangelogUpdates'; +export * from './useTitle'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useChangelog.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useChangelog.ts new file mode 100644 index 0000000000..25bcb761e7 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useChangelog.ts @@ -0,0 +1,17 @@ +import { useMemo } from 'react'; + +import { useVersionSuggestedUpgrade } from '../../../../../../redux/hooks'; + +export const useChangelog = () => { + const { suggestedUpgrade } = useVersionSuggestedUpgrade(); + + const changelogMemo = useMemo(() => { + if (suggestedUpgrade) { + return suggestedUpgrade.changelog; + } + + return []; + }, [suggestedUpgrade]); + + return changelogMemo; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useHasChangelog.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useHasChangelog.ts new file mode 100644 index 0000000000..b1e232122a --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useHasChangelog.ts @@ -0,0 +1,9 @@ +import { useChangelog } from './useChangelog'; + +export const useHasChangelog = () => { + const changelog = useChangelog(); + + const hasChangeLog = changelog.length > 0; + + return hasChangeLog; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useShowChangelogList.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useShowChangelogList.ts new file mode 100644 index 0000000000..10aa854c15 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useShowChangelogList.ts @@ -0,0 +1,9 @@ +import { useHasChangelog } from './useHasChangelog'; + +export const useShowChangelogList = () => { + const hasChangelog = useHasChangelog(); + + const showChangelogList = hasChangelog; + + return showChangelogList; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useShowNoChangelogUpdates.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useShowNoChangelogUpdates.ts new file mode 100644 index 0000000000..cc30f5c5ac --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useShowNoChangelogUpdates.ts @@ -0,0 +1,9 @@ +import { useHasChangelog } from './useHasChangelog'; + +export const useShowNoChangelogUpdates = () => { + const hasChangelog = useHasChangelog(); + + const showNoChangelogUpdates = !hasChangelog; + + return showNoChangelogUpdates; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useTitle.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useTitle.ts new file mode 100644 index 0000000000..0741d54ea3 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/hooks/useTitle.ts @@ -0,0 +1,20 @@ +import { sprintf } from 'sprintf-js'; + +import { messages } from '../../../../../../../shared/gettext'; +import { useVersionSuggestedUpgrade } from '../../../../../../redux/hooks'; + +export const useTitle = () => { + const { suggestedUpgrade } = useVersionSuggestedUpgrade(); + + const title = sprintf( + // TRANSLATORS: Heading which shows the version of the app which can be upgraded to. + // TRANSLATORS: Available placeholders: + // TRANSLATORS: %(version)s - The new version of the app. + messages.pgettext('app-upgrade-view', 'Version %(version)s'), + { + version: suggestedUpgrade?.version, + }, + ); + + return title; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/index.ts new file mode 100644 index 0000000000..307c9ef208 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-details/index.ts @@ -0,0 +1 @@ +export * from './UpgradeDetails'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/UpgradeLabel.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/UpgradeLabel.tsx new file mode 100644 index 0000000000..d351463faf --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/UpgradeLabel.tsx @@ -0,0 +1,49 @@ +import { + useAppUpgradeEventType, + useHasAppUpgradeError, + useShouldAppUpgradeInstallManually, +} from '../../../../../hooks'; +import { useConnectionIsBlocked } from '../../../../../redux/hooks'; +import { + ConnectionBlocked, + DownloadProgress, + DownloadStarted, + InstallerReady, + StartingInstaller, + UpgradeError, + VerifyingInstaller, +} from './components'; + +export function UpgradeLabel() { + const { isBlocked } = useConnectionIsBlocked(); + const appUpgradeEventType = useAppUpgradeEventType(); + const hasAppUpgradeError = useHasAppUpgradeError(); + const shouldAppUpgradeInstallManually = useShouldAppUpgradeInstallManually(); + + if (shouldAppUpgradeInstallManually) { + return <InstallerReady />; + } + + if (isBlocked) { + return <ConnectionBlocked />; + } + + if (hasAppUpgradeError) { + return <UpgradeError />; + } + + switch (appUpgradeEventType) { + case 'APP_UPGRADE_STATUS_DOWNLOAD_STARTED': + return <DownloadStarted />; + case 'APP_UPGRADE_STATUS_DOWNLOAD_PROGRESS': + return <DownloadProgress />; + case 'APP_UPGRADE_STATUS_VERIFYING_INSTALLER': + return <VerifyingInstaller />; + case 'APP_UPGRADE_STATUS_STARTED_INSTALLER': + case 'APP_UPGRADE_STATUS_STARTING_INSTALLER': + case 'APP_UPGRADE_STATUS_VERIFIED_INSTALLER': + return <StartingInstaller />; + default: + return null; + } +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/ConnectionBlocked.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/ConnectionBlocked.tsx new file mode 100644 index 0000000000..4eb3f03afa --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/ConnectionBlocked.tsx @@ -0,0 +1,14 @@ +import { Flex, LabelTiny } from '../../../../../../../lib/components'; +import { Dot } from '../../../../../../../lib/components/dot'; +import { useMessage } from './hooks'; + +export function ConnectionBlocked() { + const message = useMessage(); + + return ( + <Flex $gap="small" $alignItems="baseline"> + <Dot size="small" variant="error" /> + <LabelTiny>{message}</LabelTiny> + </Flex> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/hooks/index.ts new file mode 100644 index 0000000000..107ba71afc --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/hooks/index.ts @@ -0,0 +1 @@ +export * from './useMessage'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/hooks/useMessage.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/hooks/useMessage.ts new file mode 100644 index 0000000000..60c619ff6d --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/hooks/useMessage.ts @@ -0,0 +1,16 @@ +import { messages } from '../../../../../../../../../shared/gettext'; +import { useConnectionIsBlocked } from '../../../../../../../../redux/hooks'; + +export const useMessage = () => { + const { isBlocked } = useConnectionIsBlocked(); + + if (isBlocked) { + // TRANSLATORS: Label displayed when an error occurred due to the connection being blocked + return messages.pgettext( + 'app-upgrade-view', + 'Connection blocked. Try changing server or other settings', + ); + } + + return null; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/index.ts new file mode 100644 index 0000000000..c24311f6b3 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/connection-blocked/index.ts @@ -0,0 +1 @@ +export * from './ConnectionBlocked'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/DownloadProgress.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/DownloadProgress.tsx new file mode 100644 index 0000000000..1a5a67541f --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/DownloadProgress.tsx @@ -0,0 +1,8 @@ +import { LabelTiny } from '../../../../../../../lib/components'; +import { useMessage } from './hooks'; + +export function DownloadProgress() { + const message = useMessage(); + + return <LabelTiny>{message}</LabelTiny>; +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/hooks/index.ts new file mode 100644 index 0000000000..107ba71afc --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/hooks/index.ts @@ -0,0 +1 @@ +export * from './useMessage'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/hooks/useMessage.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/hooks/useMessage.ts new file mode 100644 index 0000000000..2edfb8c81b --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/hooks/useMessage.ts @@ -0,0 +1,23 @@ +import { sprintf } from 'sprintf-js'; + +import { messages } from '../../../../../../../../../shared/gettext'; +import { useAppUpgradeEvent } from '../../../../../../../../redux/hooks'; + +export const useMessage = () => { + const { appUpgradeEvent } = useAppUpgradeEvent(); + + if (appUpgradeEvent?.type === 'APP_UPGRADE_STATUS_DOWNLOAD_PROGRESS') { + const { server } = appUpgradeEvent; + + return sprintf( + // TRANSLATORS: Label displayed above a progress bar informing the user which server + // TRANSLATORS: the update is downloading from + messages.pgettext('app-upgrade-view', 'Downloading from: %(server)s'), + { + server, + }, + ); + } + + return null; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/index.ts new file mode 100644 index 0000000000..213bb26f82 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-progress/index.ts @@ -0,0 +1 @@ +export * from './DownloadProgress'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-started/DownloadStarted.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-started/DownloadStarted.tsx new file mode 100644 index 0000000000..4fbe251f0f --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-started/DownloadStarted.tsx @@ -0,0 +1,13 @@ +import { messages } from '../../../../../../../../shared/gettext'; +import { LabelTiny } from '../../../../../../../lib/components'; + +export function DownloadStarted() { + return ( + <LabelTiny> + { + // TRANSLATORS: Label displayed above a progress bar when a download is in progress + messages.pgettext('app-upgrade-view', 'Downloading...') + } + </LabelTiny> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-started/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-started/index.ts new file mode 100644 index 0000000000..ed30650883 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/download-started/index.ts @@ -0,0 +1 @@ +export * from './DownloadStarted'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/index.ts new file mode 100644 index 0000000000..e10fc7e8ae --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/index.ts @@ -0,0 +1,7 @@ +export * from './connection-blocked'; +export * from './download-progress'; +export * from './download-started'; +export * from './installer-ready'; +export * from './starting-installer'; +export * from './upgrade-error'; +export * from './verifying-installer'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/installer-ready/InstallerReady.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/installer-ready/InstallerReady.tsx new file mode 100644 index 0000000000..31b6f83a90 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/installer-ready/InstallerReady.tsx @@ -0,0 +1,17 @@ +import { messages } from '../../../../../../../../shared/gettext'; +import { Flex, Icon, LabelTiny } from '../../../../../../../lib/components'; +import { Colors } from '../../../../../../../lib/foundations'; + +export function InstallerReady() { + return ( + <Flex $gap="small"> + <Icon icon="checkmark" color={Colors.green} size="small" /> + <LabelTiny> + { + // TRANSLATORS: Label displayed above a progress bar when the update is ready to be installed + messages.pgettext('app-upgrade-view', 'Verification successful! Ready to install.') + } + </LabelTiny> + </Flex> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/installer-ready/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/installer-ready/index.ts new file mode 100644 index 0000000000..ab9fed2358 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/installer-ready/index.ts @@ -0,0 +1 @@ +export * from './InstallerReady'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/starting-installer/StartingInstaller.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/starting-installer/StartingInstaller.tsx new file mode 100644 index 0000000000..6ebaf95537 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/starting-installer/StartingInstaller.tsx @@ -0,0 +1,17 @@ +import { messages } from '../../../../../../../../shared/gettext'; +import { Flex, Icon, LabelTiny } from '../../../../../../../lib/components'; +import { Colors } from '../../../../../../../lib/foundations'; + +export function StartingInstaller() { + return ( + <Flex $gap="small"> + <Icon icon="checkmark" color={Colors.green} size="small" /> + <LabelTiny> + { + // TRANSLATORS: Label displayed above a progress bar when the update is ready to be installed + messages.pgettext('app-upgrade-view', 'Verification successful! Starting installer...') + } + </LabelTiny> + </Flex> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/starting-installer/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/starting-installer/index.ts new file mode 100644 index 0000000000..f324d568b0 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/starting-installer/index.ts @@ -0,0 +1 @@ +export * from './StartingInstaller'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/UpgradeError.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/UpgradeError.tsx new file mode 100644 index 0000000000..85e3c7bf8e --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/UpgradeError.tsx @@ -0,0 +1,18 @@ +import { Flex, Icon, LabelTiny } from '../../../../../../../lib/components'; +import { Colors } from '../../../../../../../lib/foundations'; +import { useMessage } from './hooks'; + +export function UpgradeError() { + const message = useMessage(); + + return ( + <Flex $gap="small" $flexDirection="row"> + <div> + <Icon size="small" icon="alert-circle" color={Colors.red} /> + </div> + <Flex $flexDirection="column"> + <LabelTiny>{message}</LabelTiny> + </Flex> + </Flex> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/hooks/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/hooks/index.ts new file mode 100644 index 0000000000..107ba71afc --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/hooks/index.ts @@ -0,0 +1 @@ +export * from './useMessage'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/hooks/useMessage.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/hooks/useMessage.ts new file mode 100644 index 0000000000..ffd4272244 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/hooks/useMessage.ts @@ -0,0 +1,43 @@ +import { messages } from '../../../../../../../../../shared/gettext'; +import { useAppUpgradeError } from '../../../../../../../../redux/hooks'; + +export const useMessage = () => { + const { appUpgradeError } = useAppUpgradeError(); + + switch (appUpgradeError) { + case 'DOWNLOAD_FAILED': + return [ + // TRANSLATORS: Label displayed when an error occurred due to the download failing + messages.pgettext( + 'app-upgrade-view', + 'Unable to download update. Check your connection and/or firewall then try again. If this problem persists, please contact support.', + ), + ]; + case 'START_INSTALLER_AUTOMATIC_FAILED': + case 'START_INSTALLER_FAILED': + return [ + // TRANSLATORS: Label displayed when an error occurred due to the installer failing to start + // TRANSLATORS: and the suggested resolution is to download the update again. + messages.pgettext( + 'app-upgrade-view', + 'Could not start the update installer, try downloading it again. If this problem persists, please contact support.', + ), + ]; + case 'VERIFICATION_FAILED': + return [ + // TRANSLATORS: Label displayed when an error occurred due to the installer failed verification + messages.pgettext( + 'app-upgrade-view', + 'Verification failed. Try again. If this problem persists, please contact support.', + ), + ]; + default: + return [ + // TRANSLATORS: Label displayed when an unknown error occurred + messages.pgettext( + 'app-upgrade-view', + 'An unknown error occurred. Please try again. If this problem persists, please contact support.', + ), + ]; + } +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/index.ts new file mode 100644 index 0000000000..91d0d9f595 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/upgrade-error/index.ts @@ -0,0 +1 @@ +export * from './UpgradeError'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/verifying-installer/VerifyingInstaller.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/verifying-installer/VerifyingInstaller.tsx new file mode 100644 index 0000000000..b2ed866f05 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/verifying-installer/VerifyingInstaller.tsx @@ -0,0 +1,16 @@ +import { messages } from '../../../../../../../../shared/gettext'; +import { Flex, LabelTiny, Spinner } from '../../../../../../../lib/components'; + +export function VerifyingInstaller() { + return ( + <Flex $gap="small"> + <Spinner size="small" /> + <LabelTiny> + { + // TRANSLATORS: Label displayed above a progress bar when the update is being verified + messages.pgettext('app-upgrade-view', 'Verifying installer...') + } + </LabelTiny> + </Flex> + ); +} diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/verifying-installer/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/verifying-installer/index.ts new file mode 100644 index 0000000000..29fba8f5bb --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/components/verifying-installer/index.ts @@ -0,0 +1 @@ +export * from './VerifyingInstaller'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/index.ts new file mode 100644 index 0000000000..fa5638908e --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/components/upgrade-label/index.ts @@ -0,0 +1 @@ +export * from './UpgradeLabel'; 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 new file mode 100644 index 0000000000..8c34ac2d52 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/index.ts @@ -0,0 +1,8 @@ +export * from './usePresent'; +export * from './useShowCancelButton'; +export * from './useShowDownloadProgress'; +export * from './useShowInstallButton'; +export * from './useShowReportProblemButton'; +export * from './useShowRetryUpgradeButton'; +export * from './useShowUpgradeButton'; +export * from './useShowUpgradeLabel'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/usePresent.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/usePresent.ts new file mode 100644 index 0000000000..40cb594078 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/usePresent.ts @@ -0,0 +1,11 @@ +import { useShowDownloadProgress } from './useShowDownloadProgress'; +import { useShowUpgradeLabel } from './useShowUpgradeLabel'; + +export const usePresent = () => { + const showUpgradeLabel = useShowUpgradeLabel(); + const showDownloadProgress = useShowDownloadProgress(); + + const present = showUpgradeLabel || showDownloadProgress; + + return present; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowCancelButton.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowCancelButton.ts new file mode 100644 index 0000000000..3a42a68b53 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowCancelButton.ts @@ -0,0 +1,9 @@ +import { useIsAppUpgradeInProgress } from '../../../../hooks'; + +export const useShowCancelButton = () => { + const isAppUpgradeInProgress = useIsAppUpgradeInProgress(); + + const showCancelButton = isAppUpgradeInProgress; + + return showCancelButton; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowDownloadProgress.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowDownloadProgress.ts new file mode 100644 index 0000000000..8faea2713d --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowDownloadProgress.ts @@ -0,0 +1,28 @@ +import { + useHasAppUpgradeError, + useHasAppUpgradeInitiated, + useIsAppUpgradePending, +} from '../../../../hooks'; +import { useAppUpgradeError, useConnectionIsBlocked } from '../../../../redux/hooks'; + +export const useShowDownloadProgress = () => { + const { isBlocked } = useConnectionIsBlocked(); + const { appUpgradeError } = useAppUpgradeError(); + const hasAppUpgradeInitiated = useHasAppUpgradeInitiated(); + const hasAppUpgradeError = useHasAppUpgradeError(); + const isAppUpgradePending = useIsAppUpgradePending(); + + if (isBlocked && hasAppUpgradeInitiated) { + return true; + } + + if (hasAppUpgradeError) { + if (appUpgradeError === 'VERIFICATION_FAILED') { + return true; + } + + return false; + } + + return isAppUpgradePending; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowInstallButton.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowInstallButton.ts new file mode 100644 index 0000000000..3c4f65ba9f --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowInstallButton.ts @@ -0,0 +1,9 @@ +import { useShouldAppUpgradeInstallManually } from '../../../../hooks'; + +export const useShowInstallButton = () => { + const shouldAppUpgradeInstallManually = useShouldAppUpgradeInstallManually(); + + const showInstallButton = shouldAppUpgradeInstallManually; + + return showInstallButton; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowReportProblemButton.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowReportProblemButton.ts new file mode 100644 index 0000000000..adc8c23400 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowReportProblemButton.ts @@ -0,0 +1,14 @@ +import { useAppUpgradeError } from '../../../../redux/hooks'; + +export const useShowReportProblemButton = () => { + const { appUpgradeError } = useAppUpgradeError(); + + switch (appUpgradeError) { + case 'DOWNLOAD_FAILED': + case 'GENERAL_ERROR': + case 'VERIFICATION_FAILED': + return true; + default: + return false; + } +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowRetryUpgradeButton.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowRetryUpgradeButton.ts new file mode 100644 index 0000000000..ba4f77e89d --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowRetryUpgradeButton.ts @@ -0,0 +1,20 @@ +import { useHasAppUpgradeError } from '../../../../hooks'; +import { useAppUpgradeError } from '../../../../redux/hooks'; + +export const useShowRetryUpgradeButton = () => { + const { appUpgradeError } = useAppUpgradeError(); + const hasAppUpgradeError = useHasAppUpgradeError(); + + if (hasAppUpgradeError) { + switch (appUpgradeError) { + case 'DOWNLOAD_FAILED': + case 'GENERAL_ERROR': + case 'VERIFICATION_FAILED': + return true; + default: + return false; + } + } + + return false; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowUpgradeButton.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowUpgradeButton.ts new file mode 100644 index 0000000000..254aff3521 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowUpgradeButton.ts @@ -0,0 +1,23 @@ +import { + useAppUpgradeEventType, + useHasAppUpgradeError, + useHasAppUpgradeInitiated, +} from '../../../../hooks'; + +export const useShowUpgradeButton = () => { + const appUpgradeEventType = useAppUpgradeEventType(); + const hasAppUpgradeError = useHasAppUpgradeError(); + const hasAppUpgradeInitiated = useHasAppUpgradeInitiated(); + + if (hasAppUpgradeError) { + return false; + } + + // If we don't have an event type yet it is because the user has not attempted + // an upgrade yet. + if (!hasAppUpgradeInitiated || appUpgradeEventType === 'APP_UPGRADE_STATUS_ABORTED') { + return true; + } + + return false; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowUpgradeLabel.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowUpgradeLabel.ts new file mode 100644 index 0000000000..8ecead9ad4 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/hooks/useShowUpgradeLabel.ts @@ -0,0 +1,16 @@ +import { useHasAppUpgradeError, useIsAppUpgradePending } from '../../../../hooks'; +import { useConnectionIsBlocked } from '../../../../redux/hooks'; + +export const useShowUpgradeLabel = () => { + const { isBlocked } = useConnectionIsBlocked(); + const hasAppUpgradeError = useHasAppUpgradeError(); + const isAppUpgradePending = useIsAppUpgradePending(); + + if (isBlocked || hasAppUpgradeError) { + return true; + } + + const showUpgradeLabel = isAppUpgradePending; + + return showUpgradeLabel; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/index.ts new file mode 100644 index 0000000000..481653229f --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-upgrade/index.ts @@ -0,0 +1 @@ +export * from './AppUpgradeView'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts index 2ff7a5978b..686a4bbbd3 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts @@ -1,3 +1,4 @@ export * from './app-info'; +export * from './app-upgrade'; export * from './changelog'; export * from './settings'; |
