summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2025-04-04 13:22:59 +0200
committerMarkus Pettersson <markus.pettersson@mullvad.net>2025-04-04 13:22:59 +0200
commitc2b5b5cba079346edc9584927413bbce4e294dc6 (patch)
tree0592afa1a86901c54e54dbc2cf2d7a4b28d2191c
parent5415661e9828c37e4f252ab3b36a810611159327 (diff)
parent208552f7f48f92b866387d3648e8cbb4d9d76720 (diff)
downloadmullvadvpn-c2b5b5cba079346edc9584927413bbce4e294dc6.tar.xz
mullvadvpn-c2b5b5cba079346edc9584927413bbce4e294dc6.zip
Merge branch 'wireguard-blocked-state-gives-no-openvpn-servers-available-des-1965'
-rw-r--r--desktop/packages/mullvad-vpn/locales/messages.pot2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ExternalLink.tsx18
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/InternalLink.tsx4
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/NotificationSubtitle.tsx13
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx15
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/components/link/Link.tsx (renamed from desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/Link.tsx)18
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/LinkIcon.tsx14
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/index.ts1
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/index.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts5
10 files changed, 61 insertions, 31 deletions
diff --git a/desktop/packages/mullvad-vpn/locales/messages.pot b/desktop/packages/mullvad-vpn/locales/messages.pot
index a8410b1718..32c43ea5a2 100644
--- a/desktop/packages/mullvad-vpn/locales/messages.pot
+++ b/desktop/packages/mullvad-vpn/locales/messages.pot
@@ -955,7 +955,7 @@ msgstr ""
#. Available placeholders:
#. %(wireGuard)s - Will be replaced with WireGuard
msgctxt "in-app-notifications"
-msgid "change tunnel protocol to %(wireGuard)s"
+msgid "change tunnel protocol to %(wireGuard)s."
msgstr ""
msgctxt "in-app-notifications"
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ExternalLink.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ExternalLink.tsx
index 6ef57cc4eb..0acba13623 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ExternalLink.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ExternalLink.tsx
@@ -1,4 +1,5 @@
import { useCallback } from 'react';
+import styled from 'styled-components';
import { Url } from '../../shared/constants';
import { useAppContext } from '../context';
@@ -8,7 +9,12 @@ export type ExternalLinkProps = Omit<LinkProps<'a'>, 'href' | 'as'> & {
to: Url;
};
-export const ExternalLink = ({ to, onClick, ...props }: ExternalLinkProps) => {
+const StyledLink = styled(Link)`
+ display: inline-flex;
+ width: fit-content;
+`;
+
+function ExternalLink({ to, onClick, ...props }: ExternalLinkProps) {
const { openUrl } = useAppContext();
const navigate = useCallback(
(e: React.MouseEvent<HTMLAnchorElement>) => {
@@ -20,5 +26,11 @@ export const ExternalLink = ({ to, onClick, ...props }: ExternalLinkProps) => {
},
[onClick, openUrl, to],
);
- return <Link href="" onClick={navigate} {...props} />;
-};
+ return <StyledLink href="" onClick={navigate} {...props} />;
+}
+
+const ExternalLinkNamespace = Object.assign(ExternalLink, {
+ Icon: Link.Icon,
+});
+
+export { ExternalLinkNamespace as ExternalLink };
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/InternalLink.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/InternalLink.tsx
index 6b45d99fee..70f8b7c496 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/InternalLink.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/InternalLink.tsx
@@ -8,7 +8,7 @@ export type InternalLinkProps = Omit<LinkProps<'a'>, 'href' | 'as'> & {
to: RoutePath;
};
-export const InternalLink = ({ to, onClick, ...props }: InternalLinkProps) => {
+export function InternalLink({ to, onClick, ...props }: InternalLinkProps) {
const history = useHistory();
const navigate = useCallback(
(e: React.MouseEvent<HTMLAnchorElement>) => {
@@ -21,4 +21,4 @@ export const InternalLink = ({ to, onClick, ...props }: InternalLinkProps) => {
[history, to, onClick],
);
return <Link href="" onClick={navigate} {...props} />;
-};
+}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/NotificationSubtitle.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/NotificationSubtitle.tsx
index fc5a4600d1..68d2572a62 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/NotificationSubtitle.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/NotificationSubtitle.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import styled from 'styled-components';
import { InAppNotificationSubtitle } from '../../shared/notifications';
-import { Icon, LabelTiny } from '../lib/components';
+import { LabelTiny } from '../lib/components';
import { Colors } from '../lib/foundations';
import { formatHtml } from '../lib/html-formatter';
import { ExternalLink } from './ExternalLink';
@@ -12,9 +12,8 @@ export type NotificationSubtitleProps = {
subtitle?: string | InAppNotificationSubtitle[];
};
-const StyledIcon = styled(Icon)`
- display: inline-flex;
- vertical-align: middle;
+const StyledExternalLink = styled(ExternalLink)`
+ display: flex;
`;
const formatSubtitle = (subtitle: InAppNotificationSubtitle) => {
@@ -29,10 +28,10 @@ const formatSubtitle = (subtitle: InAppNotificationSubtitle) => {
);
case 'navigate-external':
return (
- <ExternalLink variant="labelTiny" {...subtitle.action.link}>
+ <StyledExternalLink variant="labelTiny" {...subtitle.action.link}>
{content}
- <StyledIcon icon="external" size="small" />
- </ExternalLink>
+ <ExternalLink.Icon icon="external" size="small" />
+ </StyledExternalLink>
);
default:
break;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx
index a4077a6128..f0388c8a3e 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/VpnSettings.tsx
@@ -7,7 +7,6 @@ import { IDnsOptions, TunnelProtocol } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
import { useAppContext } from '../context';
-import { Flex, Icon } from '../lib/components';
import { useRelaySettingsUpdater } from '../lib/constraint-updater';
import { Colors, spacings } from '../lib/foundations';
import { useHistory } from '../lib/history';
@@ -759,14 +758,12 @@ function TunnelProtocolSetting() {
</Cell.CellFooterText>
</AriaDescription>
<ExternalLink variant="labelTiny" to={urls.removingOpenVpnBlog}>
- <Flex>
- {sprintf(
- // TRANSLATORS: Link in tunnel protocol selector footer to blog post
- // TRANSLATORS: about OpenVPN support ending.
- messages.pgettext('vpn-settings-view', 'Read more'),
- )}
- <Icon icon="external" size="small" />
- </Flex>
+ {sprintf(
+ // TRANSLATORS: Link in tunnel protocol selector footer to blog post
+ // TRANSLATORS: about OpenVPN support ending.
+ messages.pgettext('vpn-settings-view', 'Read more'),
+ )}
+ <ExternalLink.Icon icon="external" size="small" />
</ExternalLink>
</Cell.CellFooter>
)}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/Link.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/Link.tsx
index eb1d75917c..f9b423b37a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/Link.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/Link.tsx
@@ -2,7 +2,8 @@ import React from 'react';
import styled from 'styled-components';
import { Colors, Radius } from '../../foundations';
-import { Text, TextProps } from './Text';
+import { Text, TextProps } from '../typography';
+import { LinkIcon } from './components';
export type LinkProps<T extends React.ElementType = 'a'> = TextProps<T> & {
onClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
@@ -14,8 +15,7 @@ const StyledText = styled(Text)<{
background: 'transparent',
cursor: 'default',
textDecoration: 'none',
- display: 'inline-flex',
- alignItems: 'center',
+ display: 'inline',
'&&:hover': {
textDecorationLine: 'underline',
@@ -38,11 +38,11 @@ const getHoverColor = (color: Colors | undefined) => {
}
};
-export const Link = <T extends React.ElementType = 'a'>({
+function Link<T extends React.ElementType = 'a'>({
as: forwardedAs,
color,
...props
-}: LinkProps<T>) => {
+}: LinkProps<T>) {
// If `as` is provided we need to pass it as `forwardedAs` for it to
// be correctly passed to the `Text` component.
const componentProps = forwardedAs ? { ...props, forwardedAs } : props;
@@ -54,4 +54,10 @@ export const Link = <T extends React.ElementType = 'a'>({
{...componentProps}
/>
);
-};
+}
+
+const LinkNamespace = Object.assign(Link, {
+ Icon: LinkIcon,
+});
+
+export { LinkNamespace as Link };
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/LinkIcon.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/LinkIcon.tsx
new file mode 100644
index 0000000000..7af4b28045
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/LinkIcon.tsx
@@ -0,0 +1,14 @@
+import styled from 'styled-components';
+
+import { Icon, IconProps } from '../../icon';
+
+type LinkIconProps = IconProps;
+
+export const StyledIcon = styled(Icon)`
+ vertical-align: middle;
+ display: inline-flex;
+`;
+
+export function LinkIcon({ ...props }: LinkIconProps) {
+ return <StyledIcon size="small" {...props} />;
+}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/index.ts
new file mode 100644
index 0000000000..1718f57d55
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/link/components/index.ts
@@ -0,0 +1 @@
+export * from './LinkIcon';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/index.ts
index cb0ef82111..5e73f059c8 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/index.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/typography/index.ts
@@ -6,5 +6,5 @@ export * from './Text';
export * from './TitleBig';
export * from './TitleLarge';
export * from './TitleMedium';
-export * from './Link';
+export * from '../link/Link';
export * from './Label';
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts
index dc8819835a..d84466b0ba 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts
@@ -26,8 +26,9 @@ export class NoOpenVpnServerAvailableNotificationProvider implements InAppNotifi
public constructor(private context: NoOpenVpnServerAvailableNotificationContext) {}
public mayDisplay = () => {
- const { tunnelState } = this.context;
+ const { tunnelState, tunnelProtocol } = this.context;
return (
+ tunnelProtocol === 'openvpn' &&
tunnelState.state === 'error' &&
tunnelState.details.cause === ErrorStateCause.tunnelParameterError &&
tunnelState.details.parameterError === TunnelParameterError.noMatchingRelay
@@ -88,7 +89,7 @@ export class NoOpenVpnServerAvailableNotificationProvider implements InAppNotifi
// TRANSLATORS: Will navigate the user to the VPN settings.
// TRANSLATORS: Available placeholders:
// TRANSLATORS: %(wireGuard)s - Will be replaced with WireGuard
- messages.pgettext('in-app-notifications', 'change tunnel protocol to %(wireGuard)s'),
+ messages.pgettext('in-app-notifications', 'change tunnel protocol to %(wireGuard)s.'),
{ wireGuard: strings.wireguard },
),
action: {