import { useCallback, useEffect } from 'react'; import { colors, links } from '../../config.json'; import { formatRemainingTime, hasExpired } from '../../shared/account-expiry'; import { messages } from '../../shared/gettext'; import { useAppContext } from '../context'; import { useHistory } from '../lib/history'; import { RoutePath } from '../lib/routes'; import { useSelector } from '../redux/store'; import { AriaDescribed, AriaDescription, AriaDescriptionGroup } from './AriaGroup'; import * as Cell from './cell'; import { BackAction } from './KeyboardNavigation'; import { Layout, SettingsContainer } from './Layout'; import { NavigationBar, NavigationContainer, NavigationItems, TitleBarItem } from './NavigationBar'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; import { StyledCellIcon, StyledContent, StyledNavigationScrollbars, StyledOutOfTimeSubText, StyledQuitButton, StyledSettingsContent, } from './SettingsStyles'; export default function Support() { const history = useHistory(); const { updateAccountData } = useAppContext(); useEffect(() => { if (history.action === 'PUSH') { updateAccountData(); } }, []); const loginState = useSelector((state) => state.account.status); const connectedToDaemon = useSelector((state) => state.userInterface.connectedToDaemon); const showSubSettings = loginState.type === 'ok' && connectedToDaemon; return ( { // TRANSLATORS: Title label in navigation bar messages.pgettext('navigation-bar', 'Settings') } {messages.pgettext('navigation-bar', 'Settings')} {showSubSettings ? ( <> {(window.env.platform === 'linux' || window.env.platform === 'win32') && ( )} ) : ( )} ); } function AccountButton() { const history = useHistory(); const navigate = useCallback(() => history.push(RoutePath.accountSettings), [history]); const accountExpiry = useSelector((state) => state.account.expiry); const isOutOfTime = accountExpiry ? hasExpired(accountExpiry) : false; const formattedExpiry = accountExpiry ? formatRemainingTime(accountExpiry).toUpperCase() : ''; const outOfTimeMessage = messages.pgettext('settings-view', 'OUT OF TIME'); return ( { // TRANSLATORS: Navigation button to the 'Account' view messages.pgettext('settings-view', 'Account') } {isOutOfTime ? outOfTimeMessage : formattedExpiry} ); } function UserInterfaceSettingsButton() { const history = useHistory(); const navigate = useCallback(() => history.push(RoutePath.userInterfaceSettings), [history]); return ( { // TRANSLATORS: Navigation button to the 'User interface settings' view messages.pgettext('settings-view', 'User interface settings') } ); } function VpnSettingsButton() { const history = useHistory(); const navigate = useCallback(() => history.push(RoutePath.vpnSettings), [history]); return ( { // TRANSLATORS: Navigation button to the 'VPN settings' view messages.pgettext('settings-view', 'VPN settings') } ); } function SplitTunnelingButton() { const history = useHistory(); const navigate = useCallback(() => history.push(RoutePath.splitTunneling), [history]); return ( { // TRANSLATORS: Navigation button to the 'Split tunneling' view messages.pgettext('settings-view', 'Split tunneling') } ); } function AppVersionButton() { 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(suggestedIsBeta ? links.betaDownload : links.download), [openUrl, suggestedIsBeta], ); let icon; let footer; if (!consistentVersion || !upToDateVersion) { const inconsistentVersionMessage = messages.pgettext( 'settings-view', 'App is out of sync. Please quit and restart.', ); const updateAvailableMessage = messages.pgettext( 'settings-view', 'Update available. Install the latest app version to stay up to date.', ); const message = !consistentVersion ? inconsistentVersionMessage : updateAvailableMessage; icon = ; footer = ( {message} ); } return ( {icon} {messages.pgettext('settings-view', 'App version')} {appVersion} {footer} ); } function SupportButton() { const history = useHistory(); const navigate = useCallback(() => history.push(RoutePath.support), [history]); return ( {messages.pgettext('settings-view', 'Support')} ); } function QuitButton() { const { quit } = useAppContext(); return ( {messages.pgettext('settings-view', 'Quit app')} ); }