summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOliver <oliver@mohlin.dev>2024-12-10 14:21:04 +0100
committerMarkus Pettersson <markus.pettersson@mullvad.net>2024-12-17 12:15:39 +0100
commit64dadb6e8b2bbc30c9ea2d3d1bfac6f1354dd1f9 (patch)
tree7d75a84cd3b117c891fd36199048ce8443f617be
parent160991aab5a5efd516df229225d66ed26a04a428 (diff)
downloadmullvadvpn-64dadb6e8b2bbc30c9ea2d3d1bfac6f1354dd1f9.tar.xz
mullvadvpn-64dadb6e8b2bbc30c9ea2d3d1bfac6f1354dd1f9.zip
Add app info and changelog views
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/AppRouter.tsx3
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/AppInfoView.tsx48
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/AppVersionListItem.tsx65
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/ChangelogListItem.tsx17
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/index.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/ChangelogView.tsx106
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/routes.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/shared/localization-contexts.ts4
11 files changed, 250 insertions, 1 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/AppRouter.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/AppRouter.tsx
index 3541c095d6..6ad0a9e199 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/AppRouter.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/AppRouter.tsx
@@ -38,6 +38,7 @@ import TooManyDevices from './TooManyDevices';
import TransitionContainer, { TransitionView } from './TransitionContainer';
import UdpOverTcp from './UdpOverTcp';
import UserInterfaceSettings from './UserInterfaceSettings';
+import { AppInfoView, ChangelogView } from './views';
import VpnSettings from './VpnSettings';
import WireguardSettings from './WireguardSettings';
@@ -103,6 +104,8 @@ export default function AppRouter() {
<Route exact path={RoutePath.selectLocation} component={SelectLocation} />
<Route exact path={RoutePath.editCustomBridge} component={EditCustomBridge} />
<Route exact path={RoutePath.filter} component={Filter} />
+ <Route exact path={RoutePath.appInfo} component={AppInfoView} />
+ <Route exact path={RoutePath.changelog} component={ChangelogView} />
</Switch>
</TransitionView>
</TransitionContainer>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/AppInfoView.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/AppInfoView.tsx
new file mode 100644
index 0000000000..41671c46a9
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/AppInfoView.tsx
@@ -0,0 +1,48 @@
+import { messages } from '../../../../shared/gettext';
+import { useHistory } from '../../../lib/history';
+import { BackAction } from '../../KeyboardNavigation';
+import { Layout, SettingsContainer, SettingsGroup, SettingsStack } from '../../Layout';
+import {
+ NavigationBar,
+ NavigationContainer,
+ NavigationItems,
+ NavigationScrollbars,
+ TitleBarItem,
+} from '../../NavigationBar';
+import SettingsHeader, { HeaderTitle } from '../../SettingsHeader';
+import { AppVersionListItem, ChangelogListItem } from './components';
+
+export const AppInfoView = () => {
+ const { pop } = useHistory();
+ return (
+ <BackAction action={pop}>
+ <Layout>
+ <SettingsContainer>
+ <NavigationContainer>
+ <NavigationBar>
+ <NavigationItems>
+ <TitleBarItem>{messages.pgettext('app-info-view', 'App info')}</TitleBarItem>
+ </NavigationItems>
+ </NavigationBar>
+
+ <NavigationScrollbars>
+ <SettingsHeader>
+ <HeaderTitle>{messages.pgettext('app-info-view', 'App info')}</HeaderTitle>
+ </SettingsHeader>
+ <SettingsContainer>
+ <SettingsStack>
+ <SettingsGroup>
+ <AppVersionListItem />
+ </SettingsGroup>
+ <SettingsGroup>
+ <ChangelogListItem />
+ </SettingsGroup>
+ </SettingsStack>
+ </SettingsContainer>
+ </NavigationScrollbars>
+ </NavigationContainer>
+ </SettingsContainer>
+ </Layout>
+ </BackAction>
+ );
+};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/AppVersionListItem.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/AppVersionListItem.tsx
new file mode 100644
index 0000000000..6460515791
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/AppVersionListItem.tsx
@@ -0,0 +1,65 @@
+import { useCallback } from 'react';
+
+import { messages } from '../../../../../shared/gettext';
+import { getDownloadUrl } from '../../../../../shared/version';
+import { useAppContext } from '../../../../context';
+import { useSelector } from '../../../../redux/store';
+import { Colors } from '../../../../tokens';
+import * as Cell from '../../../cell';
+import { LabelStack } from '../../../Layout';
+
+export function AppVersionListItem() {
+ const appVersion = useSelector((state) => state.version.current);
+ const consistentVersion = useSelector((state) => state.version.consistent);
+ const upToDateVersion = useSelector((state) => (state.version.suggestedUpgrade ? false : true));
+ const suggestedIsBeta = useSelector((state) => state.version.suggestedIsBeta ?? false);
+ const isOffline = useSelector((state) => state.connection.isBlocked);
+
+ const { openUrl } = useAppContext();
+ const openDownloadLink = useCallback(
+ () => openUrl(getDownloadUrl(suggestedIsBeta)),
+ [openUrl, suggestedIsBeta],
+ );
+
+ let alertIcon;
+ let footer;
+ if (!consistentVersion || !upToDateVersion) {
+ const inconsistentVersionMessage = messages.pgettext(
+ 'app-info-view',
+ 'App is out of sync. Please quit and restart.',
+ );
+
+ const updateAvailableMessage = messages.pgettext(
+ 'app-info-view',
+ 'Update available. Install the latest app version to stay up to date.',
+ );
+
+ const message = !consistentVersion ? inconsistentVersionMessage : updateAvailableMessage;
+
+ alertIcon = <Cell.UntintedIcon source="icon-alert" width={18} tintColor={Colors.red} />;
+ footer = (
+ <Cell.CellFooter>
+ <Cell.CellFooterText>{message}</Cell.CellFooterText>
+ </Cell.CellFooter>
+ );
+ }
+
+ return (
+ <>
+ <Cell.CellNavigationButton
+ disabled={isOffline}
+ onClick={openDownloadLink}
+ icon={{
+ source: 'icon-extLink',
+ 'aria-label': messages.pgettext('accessibility', 'Opens externally'),
+ }}>
+ <LabelStack>
+ {alertIcon}
+ <Cell.Label>{messages.pgettext('app-info-view', 'App version')}</Cell.Label>
+ </LabelStack>
+ <Cell.SubText>{appVersion}</Cell.SubText>
+ </Cell.CellNavigationButton>
+ {footer}
+ </>
+ );
+}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/ChangelogListItem.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/ChangelogListItem.tsx
new file mode 100644
index 0000000000..c05b0286b6
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/ChangelogListItem.tsx
@@ -0,0 +1,17 @@
+import { useCallback } from 'react';
+
+import { messages } from '../../../../../shared/gettext';
+import { useHistory } from '../../../../lib/history';
+import { RoutePath } from '../../../../lib/routes';
+import * as Cell from '../../../cell';
+
+export function ChangelogListItem() {
+ const history = useHistory();
+ const navigate = useCallback(() => history.push(RoutePath.changelog), [history]);
+
+ return (
+ <Cell.CellNavigationButton onClick={navigate}>
+ <Cell.Label>{messages.pgettext('settings-view', "What's new")}</Cell.Label>
+ </Cell.CellNavigationButton>
+ );
+}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/index.ts
new file mode 100644
index 0000000000..905bc45397
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/components/index.ts
@@ -0,0 +1,2 @@
+export * from './AppVersionListItem';
+export * from './ChangelogListItem';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/index.ts
new file mode 100644
index 0000000000..afbe9686f6
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/app-info/index.ts
@@ -0,0 +1 @@
+export * from './AppInfoView';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/ChangelogView.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/ChangelogView.tsx
new file mode 100644
index 0000000000..99c278c51d
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/ChangelogView.tsx
@@ -0,0 +1,106 @@
+import { useCallback } from 'react';
+import styled from 'styled-components';
+
+import { links } from '../../../../config.json';
+import { messages } from '../../../../shared/gettext';
+import { useAppContext } from '../../../context';
+import { useHistory } from '../../../lib/history';
+import { useSelector } from '../../../redux/store';
+import { Colors, Spacings } from '../../../tokens';
+import { Flex } from '../../common/layout';
+import { Container } from '../../common/layout/Container';
+import { Button } from '../../common/molecules/Button';
+import { BodySmall, TitleBig, TitleLarge } from '../../common/text';
+import ImageView from '../../ImageView';
+import { BackAction } from '../../KeyboardNavigation';
+import { Layout, SettingsContainer } from '../../Layout';
+import {
+ NavigationBar,
+ NavigationContainer,
+ NavigationItems,
+ NavigationScrollbars,
+ TitleBarItem,
+} from '../../NavigationBar';
+import SettingsHeader from '../../SettingsHeader';
+
+const StyledList = styled(Flex)({
+ listStyleType: 'disc',
+ paddingLeft: 0,
+ li: {
+ marginLeft: '1.5em',
+ },
+});
+
+const StyledFooter = styled(Flex)({
+ position: 'sticky',
+ minHeight: '64px',
+ bottom: 0,
+ background: Colors.darkBlue,
+});
+
+export const ChangelogView = () => {
+ const { pop } = useHistory();
+ const { openUrl } = useAppContext();
+ const changelog = useSelector((state) => state.userInterface.changelog);
+ const version = useSelector((state) => state.version.current);
+
+ const url = links.download;
+ const openDownloadLink = useCallback(() => openUrl(url), [openUrl, url]);
+ return (
+ <BackAction action={pop}>
+ <Layout>
+ <SettingsContainer>
+ <NavigationContainer>
+ <NavigationBar>
+ <NavigationItems>
+ <TitleBarItem>{messages.pgettext('changelog-view', "What's new")}</TitleBarItem>
+ </NavigationItems>
+ </NavigationBar>
+
+ <NavigationScrollbars>
+ <SettingsHeader>
+ <TitleBig as={'h1'}>{messages.pgettext('changelog-view', "What's new")}</TitleBig>
+ </SettingsHeader>
+ <Flex $flexDirection="column" $gap={Spacings.spacing3}>
+ <Container size="4">
+ <TitleLarge as="h2">{version}</TitleLarge>
+ </Container>
+ <Container size="3" $flexDirection="column">
+ {changelog.length ? (
+ <StyledList as="ul" $flexDirection="column" $gap={Spacings.spacing5}>
+ {changelog.map((item, i) => (
+ <BodySmall as="li" key={i} color={Colors.white60}>
+ {item}
+ </BodySmall>
+ ))}
+ </StyledList>
+ ) : (
+ <BodySmall>
+ {messages.pgettext(
+ 'changelog-view',
+ 'No updates or changes were made in this release for this platform.',
+ )}
+ </BodySmall>
+ )}
+ </Container>
+ </Flex>
+ </NavigationScrollbars>
+ </NavigationContainer>
+ </SettingsContainer>
+ <StyledFooter $alignItems="center" $justifyContent="center">
+ <Button
+ onClick={openDownloadLink}
+ trailing={
+ <ImageView
+ source="icon-extLink"
+ aria-label={messages.pgettext('accessibility', 'Opens externally')}
+ tintColor={Colors.white}
+ />
+ }>
+ {messages.pgettext('changelog', 'See full changelog')}
+ </Button>
+ </StyledFooter>
+ </Layout>
+ </BackAction>
+ );
+};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/index.ts
new file mode 100644
index 0000000000..2c823d4f13
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/changelog/index.ts
@@ -0,0 +1 @@
+export * from './ChangelogView';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts b/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts
new file mode 100644
index 0000000000..dff5aa7a90
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/views/index.ts
@@ -0,0 +1,2 @@
+export * from './app-info';
+export * from './changelog';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/routes.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/routes.ts
index 89b50c1fb0..73f510ea3a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/routes.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/routes.ts
@@ -31,4 +31,6 @@ export enum RoutePath {
selectLocation = '/select-location',
editCustomBridge = '/select-location/edit-custom-bridge',
filter = '/select-location/filter',
+ appInfo = '/settings/app-info',
+ changelog = '/settings/changelog',
}
diff --git a/desktop/packages/mullvad-vpn/src/shared/localization-contexts.ts b/desktop/packages/mullvad-vpn/src/shared/localization-contexts.ts
index f30212025c..c4d47b1afa 100644
--- a/desktop/packages/mullvad-vpn/src/shared/localization-contexts.ts
+++ b/desktop/packages/mullvad-vpn/src/shared/localization-contexts.ts
@@ -37,4 +37,6 @@ export type LocalizationContexts =
| 'select-language-nav'
| 'tray-icon-context-menu'
| 'tray-icon-tooltip'
- | 'troubleshoot';
+ | 'troubleshoot'
+ | 'app-info-view'
+ | 'changelog-view';