From e85f69a144e5e0dc1296382380334f02c70b2b09 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 29 Jun 2021 13:48:43 +1000 Subject: [PATCH] use our retrieve status as isOnline status --- js/background.js | 1 - ts/components/LeftPane.tsx | 3 -- ts/components/OnionStatusPathDialog.tsx | 8 ++--- .../session/network/SessionOffline.tsx | 36 ------------------- ts/session/onions/onionSend.ts | 2 +- ts/session/snode_api/SNodeAPI.ts | 11 ++++++ ts/session/snode_api/onions.ts | 8 ++++- ts/session/snode_api/swarmPolling.ts | 12 ++----- ts/state/ducks/onion.tsx | 9 +++-- ts/state/selectors/onions.ts | 5 +++ 10 files changed, 37 insertions(+), 58 deletions(-) delete mode 100644 ts/components/session/network/SessionOffline.tsx diff --git a/js/background.js b/js/background.js index 558c143c6..c58986015 100644 --- a/js/background.js +++ b/js/background.js @@ -450,7 +450,6 @@ }, window.CONSTANTS.NOTIFICATION_ENABLE_TIMEOUT_SECONDS * 1000); window.NewReceiver.queueAllCached(); - window.libsession.Utils.AttachmentDownloads.start({ logger: window.log, }); diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index 4b5e4cfb0..da5a16129 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -7,7 +7,6 @@ import { openConversationExternal } from '../state/ducks/conversations'; import { LeftPaneContactSection } from './session/LeftPaneContactSection'; import { LeftPaneSettingSection } from './session/LeftPaneSettingSection'; import { SessionTheme } from '../state/ducks/SessionTheme'; -import { SessionOffline } from './session/network/SessionOffline'; import { SessionExpiredWarning } from './session/network/SessionExpiredWarning'; import { getFocusedSection } from '../state/selectors/section'; import { useDispatch, useSelector } from 'react-redux'; @@ -44,7 +43,6 @@ const InnerLeftPaneMessageSection = (props: { isExpired: boolean }) => { return ( <> - {props.isExpired && } { return ( <> - dispatch(openConversationExternal(id, messageId)) diff --git a/ts/components/OnionStatusPathDialog.tsx b/ts/components/OnionStatusPathDialog.tsx index 72c386aed..1fef5ad03 100644 --- a/ts/components/OnionStatusPathDialog.tsx +++ b/ts/components/OnionStatusPathDialog.tsx @@ -20,11 +20,10 @@ import { onionPathModal } from '../state/ducks/modalDialog'; import { getFirstOnionPath, getFirstOnionPathLength, + getIsOnline, getOnionPathsCount, } from '../state/selectors/onions'; -// tslint:disable-next-line: no-submodule-imports -import useNetworkState from 'react-use/lib/useNetworkState'; import { SessionSpinner } from './session/SessionSpinner'; import { Flex } from './basic/Flex'; @@ -36,9 +35,10 @@ export type StatusLightType = { const OnionPathModalInner = () => { const onionPath = useSelector(getFirstOnionPath); + const isOnline = useSelector(getIsOnline); // including the device and destination in calculation const glowDuration = onionPath.length + 2; - if (!onionPath || onionPath.length === 0) { + if (!isOnline || !onionPath || onionPath.length === 0) { return ; } @@ -144,7 +144,7 @@ export const ActionPanelOnionStatusLight = (props: { const theme = useTheme(); const onionPathsCount = useSelector(getOnionPathsCount); const firstPathLength = useSelector(getFirstOnionPathLength); - const isOnline = useNetworkState().online; + const isOnline = useSelector(getIsOnline); // Set icon color based on result const red = theme.colors.destructive; diff --git a/ts/components/session/network/SessionOffline.tsx b/ts/components/session/network/SessionOffline.tsx deleted file mode 100644 index 3dbb4a6b4..000000000 --- a/ts/components/session/network/SessionOffline.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; - -// tslint:disable-next-line: no-submodule-imports -import useNetworkState from 'react-use/lib/useNetworkState'; -import styled from 'styled-components'; - -type ContainerProps = { - show: boolean; -}; - -const OfflineContainer = styled.div` - background: ${props => props.theme.colors.accent}; - color: ${props => props.theme.colors.textColor}; - padding: ${props => (props.show ? props.theme.common.margins.sm : '0px')}; - margin: ${props => (props.show ? props.theme.common.margins.xs : '0px')}; - height: ${props => (props.show ? 'auto' : '0px')}; - overflow: hidden; - transition: ${props => props.theme.common.animations.defaultDuration}; -`; - -const OfflineTitle = styled.h3` - padding-top: 0px; - margin-top: 0px; -`; - -const OfflineMessage = styled.div``; - -export const SessionOffline = () => { - const isOnline = useNetworkState().online; - return ( - - {window.i18n('offline')} - {window.i18n('checkNetworkConnection')} - - ); -}; diff --git a/ts/session/onions/onionSend.ts b/ts/session/onions/onionSend.ts index 3af4cd57d..934a18731 100644 --- a/ts/session/onions/onionSend.ts +++ b/ts/session/onions/onionSend.ts @@ -179,7 +179,7 @@ export const sendViaOnion = async ( { retries: 9, // each path can fail 3 times before being dropped, we have 3 paths at most factor: 2, - minTimeout: 1000, + minTimeout: 100, maxTimeout: 4000, onFailedAttempt: e => { window?.log?.warn( diff --git a/ts/session/snode_api/SNodeAPI.ts b/ts/session/snode_api/SNodeAPI.ts index 8df50f5db..bc25631d0 100644 --- a/ts/session/snode_api/SNodeAPI.ts +++ b/ts/session/snode_api/SNodeAPI.ts @@ -24,11 +24,14 @@ import { toHex, } from '../utils/String'; import { Snode } from '../../data/data'; +import { updateIsOnline } from '../../state/ducks/onion'; // ONS name can have [a-zA-Z0-9_-] except that - is not allowed as start or end // do not define a regex but rather create it on the fly to avoid https://stackoverflow.com/questions/3891641/regex-test-only-works-every-other-time export const onsNameRegex = '^\\w([\\w-]*[\\w])?$'; +export const ERROR_CODE_NO_CONNECT = 'ENETUNREACH: No network connection.'; + const getSslAgentForSeedNode = (seedNodeHost: string, isSsl = false) => { let filePrefix = ''; let pubkey256 = ''; @@ -527,9 +530,12 @@ export async function retrieveNextMessages( try { const json = JSON.parse(result.body); + window.inboxStore?.dispatch(updateIsOnline(true)); + return json.messages || []; } catch (e) { window?.log?.warn('exception while parsing json of nextMessage:', e); + window.inboxStore?.dispatch(updateIsOnline(true)); return []; } @@ -538,6 +544,11 @@ export async function retrieveNextMessages( 'Got an error while retrieving next messages. Not retrying as we trigger fetch often:', e ); + if (e.message === ERROR_CODE_NO_CONNECT) { + window.inboxStore?.dispatch(updateIsOnline(false)); + } else { + window.inboxStore?.dispatch(updateIsOnline(true)); + } return []; } } diff --git a/ts/session/snode_api/onions.ts b/ts/session/snode_api/onions.ts index f8c4b7124..1c508fefd 100644 --- a/ts/session/snode_api/onions.ts +++ b/ts/session/snode_api/onions.ts @@ -13,6 +13,7 @@ import { hrefPnServerDev, hrefPnServerProd } from '../../pushnotification/PnServ let snodeFailureCount: Record = {}; import { Snode } from '../../data/data'; +import { ERROR_CODE_NO_CONNECT } from './SNodeAPI'; // tslint:disable-next-line: variable-name export const TEST_resetSnodeFailureCount = () => { @@ -783,6 +784,7 @@ const sendOnionRequest = async ({ // we are talking to a snode... agent: snodeHttpsAgent, abortSignal, + timeout: 5000, }; const guardUrl = `https://${guardNode.ip}:${guardNode.port}/onion_req/v2`; @@ -859,7 +861,7 @@ export async function lokiOnionFetch( return onionFetchRetryable(targetNode, body, associatedWith); }, { - retries: 9, + retries: 4, factor: 1, minTimeout: 1000, maxTimeout: 2000, @@ -875,6 +877,10 @@ export async function lokiOnionFetch( } catch (e) { window?.log?.warn('onionFetchRetryable failed ', e); // console.warn('error to show to user'); + if (e?.errno === 'ENETUNREACH') { + // better handle the no connection state + throw new Error(ERROR_CODE_NO_CONNECT); + } throw e; } } diff --git a/ts/session/snode_api/swarmPolling.ts b/ts/session/snode_api/swarmPolling.ts index 87239c427..40a45c194 100644 --- a/ts/session/snode_api/swarmPolling.ts +++ b/ts/session/snode_api/swarmPolling.ts @@ -51,7 +51,6 @@ export const getSwarmPollingInstance = () => { }; export class SwarmPolling { - private ourPubkey: PubKey | undefined; private groupPolling: Array<{ pubkey: PubKey; lastPolledTimestamp: number }>; private readonly lastHashes: { [key: string]: PubkeyToHash }; @@ -61,7 +60,6 @@ export class SwarmPolling { } public async start(waitForFirstPoll = false): Promise { - this.ourPubkey = UserUtils.getOurPubKeyFromCache(); this.loadGroupIds(); if (waitForFirstPoll) { await this.TEST_pollForAllKeys(); @@ -74,7 +72,6 @@ export class SwarmPolling { * Used fo testing only */ public TEST_reset() { - this.ourPubkey = undefined; this.groupPolling = []; } @@ -88,10 +85,6 @@ export class SwarmPolling { public removePubkey(pk: PubKey | string) { const pubkey = PubKey.cast(pk); window?.log?.info('Swarm removePubkey: removing pubkey from polling', pubkey.key); - - if (this.ourPubkey && PubKey.cast(pk).isEqual(this.ourPubkey)) { - this.ourPubkey = undefined; - } this.groupPolling = this.groupPolling.filter(group => !pubkey.isEqual(group.pubkey)); } @@ -132,9 +125,8 @@ export class SwarmPolling { */ public async TEST_pollForAllKeys() { // we always poll as often as possible for our pubkey - const directPromise = this.ourPubkey - ? this.TEST_pollOnceForKey(this.ourPubkey, false) - : Promise.resolve(); + const ourPubkey = UserUtils.getOurPubKeyFromCache(); + const directPromise = this.TEST_pollOnceForKey(ourPubkey, false); const now = Date.now(); const groupPromises = this.groupPolling.map(async group => { diff --git a/ts/state/ducks/onion.tsx b/ts/state/ducks/onion.tsx index 2c607adf3..4ebedebf2 100644 --- a/ts/state/ducks/onion.tsx +++ b/ts/state/ducks/onion.tsx @@ -3,10 +3,12 @@ import { Snode } from '../../data/data'; export type OnionState = { snodePaths: Array>; + isOnline: boolean; }; export const initialOnionPathState = { snodePaths: new Array>(), + isOnline: false, }; /** @@ -17,12 +19,15 @@ const onionSlice = createSlice({ initialState: initialOnionPathState, reducers: { updateOnionPaths(state: OnionState, action: PayloadAction>>) { - return { snodePaths: action.payload }; + return { ...state, snodePaths: action.payload }; + }, + updateIsOnline(state: OnionState, action: PayloadAction) { + return { ...state, isOnline: action.payload }; }, }, }); // destructures const { actions, reducer } = onionSlice; -export const { updateOnionPaths } = actions; +export const { updateOnionPaths, updateIsOnline } = actions; export const defaultOnionReducer = reducer; diff --git a/ts/state/selectors/onions.ts b/ts/state/selectors/onions.ts index 1e3d95a0d..897e8b3ff 100644 --- a/ts/state/selectors/onions.ts +++ b/ts/state/selectors/onions.ts @@ -21,3 +21,8 @@ export const getFirstOnionPathLength = createSelector( getFirstOnionPath, (state: Array): number => state.length || 0 ); + +export const getIsOnline = createSelector( + getOnionPaths, + (state: OnionState): boolean => state.isOnline +);