diff --git a/js/modules/signal.js b/js/modules/signal.js index c19b826a0..c7ddabfa3 100644 --- a/js/modules/signal.js +++ b/js/modules/signal.js @@ -13,7 +13,6 @@ const { Message } = require('../../ts/components/conversation/Message'); // Components const { EditProfileDialog } = require('../../ts/components/EditProfileDialog'); -const { OnionStatusDialog } = require('../../ts/components/OnionStatusDialog'); const { UserDetailsDialog } = require('../../ts/components/UserDetailsDialog'); const { SessionSeedModal } = require('../../ts/components/session/SessionSeedModal'); const { SessionNicknameDialog } = require('../../ts/components/session/SessionNicknameDialog'); @@ -142,7 +141,6 @@ exports.setup = (options = {}) => { const Components = { EditProfileDialog, - OnionStatusDialog, UserDetailsDialog, SessionInboxView, UpdateGroupNameDialog, diff --git a/js/views/app_view.js b/js/views/app_view.js index bee6d23ce..bd23dac0e 100644 --- a/js/views/app_view.js +++ b/js/views/app_view.js @@ -126,12 +126,6 @@ const dialog = new Whisper.SessionNicknameDialog(modifiedOptions); this.el.prepend(dialog.el); }, - showOnionStatusDialog() { - // eslint-disable-next-line no-param-reassign - const theme = this.getThemeObject(); - const dialog = new Whisper.OnionStatusDialogView({ theme }); - this.el.prepend(dialog.el); - }, showResetSessionIdDialog() { const theme = this.getThemeObject(); const resetSessionIDDialog = new Whisper.SessionIDResetDialog({ theme }); diff --git a/js/views/onion_status_dialog_view.js b/js/views/onion_status_dialog_view.js index f7f1a843f..2e5b10883 100644 --- a/js/views/onion_status_dialog_view.js +++ b/js/views/onion_status_dialog_view.js @@ -1,37 +1,37 @@ -/* global i18n, Whisper */ +// /* global i18n, Whisper */ -// eslint-disable-next-line func-names -(function() { - 'use strict'; +// // eslint-disable-next-line func-names +// (function() { +// 'use strict'; - window.Whisper = window.Whisper || {}; +// window.Whisper = window.Whisper || {}; - Whisper.OnionStatusDialogView = Whisper.View.extend({ - className: 'loki-dialog modal', - initialize({ theme }) { - this.close = this.close.bind(this); +// Whisper.OnionStatusDialogView = Whisper.View.extend({ +// className: 'loki-dialog modal', +// initialize({ theme }) { +// this.close = this.close.bind(this); - this.theme = theme; +// this.theme = theme; - this.$el.focus(); - this.render(); - }, - render() { - this.dialogView = new Whisper.ReactWrapperView({ - className: 'onion-status-dialog', - Component: window.Signal.Components.OnionStatusDialog, - props: { - onClose: this.close, - i18n, - theme: this.theme, - }, - }); +// this.$el.focus(); +// this.render(); +// }, +// render() { +// this.dialogView = new Whisper.ReactWrapperView({ +// className: 'onion-status-dialog', +// Component: window.Signal.Components.OnionStatusDialog, +// props: { +// onClose: this.close, +// i18n, +// theme: this.theme, +// }, +// }); - this.$el.append(this.dialogView.el); - return this; - }, - close() { - this.remove(); - }, - }); -})(); +// this.$el.append(this.dialogView.el); +// return this; +// }, +// close() { +// this.remove(); +// }, +// }); +// })(); diff --git a/ts/components/EditProfileDialog.tsx b/ts/components/EditProfileDialog.tsx index 84be6a366..11c96659a 100644 --- a/ts/components/EditProfileDialog.tsx +++ b/ts/components/EditProfileDialog.tsx @@ -7,7 +7,6 @@ import { Avatar, AvatarSize } from './Avatar'; import { SessionButton, SessionButtonColor, SessionButtonType } from './session/SessionButton'; import { SessionIconButton, SessionIconSize, SessionIconType } from './session/icon'; -import { SessionModal } from './session/SessionModal'; import { PillDivider } from './session/PillDivider'; import { AttachmentUtils, SyncUtils, ToastUtils, UserUtils } from '../session/utils'; import { DefaultTheme, useTheme } from 'styled-components'; @@ -15,15 +14,15 @@ import { MAX_USERNAME_LENGTH } from './session/registration/RegistrationTabs'; import { SessionSpinner } from './session/SessionSpinner'; import { ConversationTypeEnum } from '../models/conversation'; -import { ConversationController } from '../session/conversations'; -import { useSelector } from 'react-redux'; -import { getOurNumber } from '../state/selectors/user'; import { SessionWrapperModal } from './session/SessionWrapperModal'; -import { times } from 'underscore'; import { AttachmentUtil, } from '../util'; +import { LocalizerType } from '../types/Util'; +import { ConversationController } from '../session/conversations'; + + interface Props { - i18n?: any; + i18n?: LocalizerType; profileName?: string; avatarPath?: string; pubkey?: string; @@ -42,7 +41,7 @@ interface State { export class EditProfileDialog extends React.Component { private readonly inputEl: any; - + private conversationController = ConversationController.getInstance(); constructor(props: any) { super(props); @@ -67,11 +66,11 @@ export class EditProfileDialog extends React.Component { window.addEventListener('keyup', this.onKeyUp); } + + async componentDidMount() { const ourNumber = window.storage.get('primaryDevicePubKey'); - const conversation = await window - .getConversationController() - .getOrCreateAndWait(ourNumber, ConversationTypeEnum.PRIVATE); + const conversation = await this.conversationController.getOrCreateAndWait(ourNumber, ConversationTypeEnum.PRIVATE); const readFile = (attachment: any) => new Promise((resolve, reject) => { @@ -374,7 +373,7 @@ export class EditProfileDialog extends React.Component { private async commitProfileEdits(newName: string, avatar: any) { let ourNumber = window.storage.get('primaryDevicePubKey'); - const conversation = await window.getConversationController().getOrCreateAndWait(ourNumber, ConversationTypeEnum.PRIVATE); + const conversation = await this.conversationController.getOrCreateAndWait(ourNumber, ConversationTypeEnum.PRIVATE); let newAvatarPath = ''; let url: any = null; @@ -467,9 +466,7 @@ export class EditProfileDialog extends React.Component { window.lokiPublicChatAPI.setProfileName(newName); if (avatar) { - window - .getConversationController() - .getConversations() + this.conversationController.getConversations() .filter(convo => convo.isPublic()) .forEach(convo => convo.trigger('ourAvatarChanged', { url, profileKey })); } diff --git a/ts/components/OnionStatusDialog.tsx b/ts/components/OnionStatusDialog.tsx index d74cd7714..9b678be83 100644 --- a/ts/components/OnionStatusDialog.tsx +++ b/ts/components/OnionStatusDialog.tsx @@ -7,7 +7,7 @@ import { getTheme } from '../state/selectors/theme'; import electron from 'electron'; import { useSelector } from 'react-redux'; import { StateType } from '../state/reducer'; -import { SessionIcon, SessionIconSize, SessionIconType } from './session/icon'; +import { SessionIcon, SessionIconButton, SessionIconSize, SessionIconType } from './session/icon'; const { shell } = electron; import { SessionWrapperModal } from '../components/session/SessionWrapperModal'; @@ -16,6 +16,7 @@ import { Snode } from '../session/onions'; import ip2country from 'ip2country'; import countryLookup from 'country-code-lookup'; import { useTheme } from 'styled-components'; +import { useNetwork } from '../hooks/useNetwork'; export type OnionPathModalType = { onConfirm?: () => void; @@ -52,14 +53,12 @@ const OnionPathModalInner = (props: any) => {
{nodes.map((snode: Snode | any, index: number) => { return ( - <> - - + ); })}
@@ -88,11 +87,11 @@ export const OnionNodeStatusLight = (props: OnionNodeStatusLightType): JSX.Eleme } return (
- + > {labelText ? ( <>
{labelText}
@@ -105,25 +104,66 @@ export const OnionNodeStatusLight = (props: OnionNodeStatusLightType): JSX.Eleme /** * An icon with a pulsating glow emission. */ -export const StatusLight = (props: StatusLightType) => { +export const ModalStatusLight = (props: StatusLightType) => { const { glowStartDelay, glowDuration, color } = props; const theme = useSelector(getTheme); return ( - <> - - + ); }; + +/** + * A status light specifically for the action panel. Color is based on aggregate node states instead of individual onion node state + */ +export const ActionPanelOnionStatusLight = (props: { isSelected: boolean, handleClick: () => void }) => { + const { isSelected, handleClick } = props; + + let iconColor; + const theme = useTheme(); + const firstOnionPath = useSelector((state: StateType) => state.onionPaths.snodePath.path); + const hasOnionPath = firstOnionPath.length > 2; + + // Set icon color based on result + const red = theme.colors.destructive; + const green = theme.colors.accent; + const orange = theme.colors.warning; + + + iconColor = hasOnionPath ? theme.colors.accent : theme.colors.destructive; + const onionState = useSelector((state: StateType) => state.onionPaths); + + iconColor = red; + const isOnline = useNetwork(); + if (!(onionState && onionState.snodePath) || !isOnline) { + iconColor = red; + } else { + const onionSnodePath = onionState.snodePath; + if (onionState && onionSnodePath && onionSnodePath.path.length > 0) { + let onionNodeCount = onionSnodePath.path.length; + iconColor = onionNodeCount > 2 ? green : onionNodeCount > 1 ? orange : red; + } + } + + return +} + export const OnionPathModal = (props: OnionPathModalType) => { const onConfirm = () => { shell.openExternal('https://getsession.org/faq/#onion-routing'); diff --git a/ts/components/session/ActionsPanel.tsx b/ts/components/session/ActionsPanel.tsx index 0cf7c0416..e2cb6909c 100644 --- a/ts/components/session/ActionsPanel.tsx +++ b/ts/components/session/ActionsPanel.tsx @@ -11,9 +11,8 @@ import { generateAttachmentKeyIfEmpty, getItemById, hasSyncedInitialConfigurationItem, - removeItemById, } from '../../data/data'; -import { OnionPaths, Snode, SnodePath } from '../../session/onions'; +import { OnionPaths } from '../../session/onions'; import { getMessageQueue } from '../../session/sending'; import { clearSessionsAndPreKeys } from '../../util/accountManager'; import { useDispatch, useSelector } from 'react-redux'; @@ -34,14 +33,9 @@ import { OpenGroupManagerV2 } from '../../opengroup/opengroupV2/OpenGroupManager import { loadDefaultRooms } from '../../opengroup/opengroupV2/ApiUtil'; import { forceRefreshRandomSnodePool } from '../../session/snode_api/snodePool'; import { SwarmPolling } from '../../session/snode_api/swarmPolling'; -import { getOnionPathStatus } from '../../session/onions/onionSend'; -import { Constants } from '../../session'; -import { StateType } from '../../state/reducer'; import _ from 'lodash'; -import { useNetwork } from '../../hooks/useNetwork'; -import { OnionPathModal } from '../OnionStatusDialog'; +import { ActionPanelOnionStatusLight, OnionPathModal } from '../OnionStatusDialog'; import { EditProfileDialog } from '../EditProfileDialog'; -import { useTheme } from 'styled-components'; // tslint:disable-next-line: no-import-side-effect no-submodule-imports @@ -59,13 +53,12 @@ const Section = (props: { setModal?: any; type: SectionType; avatarPath?: string; - hasOnionPath?: boolean; }) => { const ourNumber = useSelector(getOurNumber); const unreadMessageCount = useSelector(getUnreadMessageCount); const theme = useSelector(getTheme); const dispatch = useDispatch(); - const { setModal, type, avatarPath, hasOnionPath } = props; + const { setModal, type, avatarPath } = props; const focusedSection = useSelector(getFocusedSection); const isSelected = focusedSection === props.type; @@ -116,25 +109,6 @@ const Section = (props: { let iconColor = undefined; if (type === SectionType.PathIndicator) { - // Set icon color based on result - const red = theme.colors.destructive; - const green = theme.colors.accent; - const orange = theme.colors.warning; - - iconColor = hasOnionPath ? theme.colors.accent : theme.colors.destructive; - const onionState = useSelector((state: StateType) => state.onionPaths); - - iconColor = red; - const isOnline = useNetwork(); - if (!(onionState && onionState.snodePath) || !isOnline) { - iconColor = Constants.UI.COLORS.DANGER; - } else { - const onionSnodePath = onionState.snodePath; - if (onionState && onionSnodePath && onionSnodePath.path.length > 0) { - let onionNodeCount = onionSnodePath.path.length; - iconColor = onionNodeCount > 2 ? green : onionNodeCount > 1 ? orange : red; - } - } } const unreadToShow = type === SectionType.Message ? unreadMessageCount : undefined; @@ -153,15 +127,18 @@ const Section = (props: { case SectionType.Moon: iconType = SessionIconType.Moon; break; - case SectionType.PathIndicator: - iconType = SessionIconType.Circle; - break; default: iconType = SessionIconType.Moon; } return ( <> + {type === SectionType.PathIndicator ? + + : + } ); }; @@ -245,9 +223,7 @@ const doAppStartUp = (dispatch: Dispatch) => { export const ActionsPanel = () => { const dispatch = useDispatch(); const [startCleanUpMedia, setStartCleanUpMedia] = useState(false); - const [hasOnionPath, setHasOnionPath] = useState(false); const ourPrimaryConversation = useSelector(getOurPrimaryConversation); - const [modal, setModal] = useState(null); // this maxi useEffect is called only once: when the component is mounted. @@ -264,15 +240,6 @@ export const ActionsPanel = () => { return () => global.clearTimeout(timeout); }, []); - const getOnionPathIndicator = () => { - const hasOnionPath = getOnionPathStatus(); - setHasOnionPath(hasOnionPath); - }; - - useInterval(() => { - getOnionPathIndicator(); - }, 1000); - useInterval( () => { cleanUpOldDecryptedMedias(); @@ -300,15 +267,15 @@ export const ActionsPanel = () => { type={SectionType.Profile} avatarPath={ourPrimaryConversation.avatarPath} /> -
-
-
+
+
+
{modal ? modal : null} -
-
+
+
); }; diff --git a/ts/session/onions/onionSend.ts b/ts/session/onions/onionSend.ts index ad47a9460..105ca51d2 100644 --- a/ts/session/onions/onionSend.ts +++ b/ts/session/onions/onionSend.ts @@ -121,28 +121,6 @@ export const getOnionPathForSending = async (requestNumber: number) => { return pathNodes; }; -export const getOnionPathStatus = () => { - let hasOnionPath: boolean = false; - try { - hasOnionPath = OnionPaths.getInstance().hasOnionPath(); - } catch (e) { - window.log.error(`getOnionPathStatus Error ${e.code} ${e.message}`); - } - return hasOnionPath; -}; - -export const getPathNodesIPAddresses = () => { - let pathNodes: Array = []; - let displayNode: Array = []; - try { - pathNodes = OnionPaths.getInstance().getOnionPathNoRebuild(); - displayNode = pathNodes.map(node => node.ip); - } catch (e) { - window.log.error(`getPathNodesIPAddresses Error ${e.code} ${e.message}`); - } - return displayNode; -}; - const initOptionsWithDefaults = (options: OnionFetchBasicOptions) => { const defaultFetchBasicOptions = { retry: 0, diff --git a/ts/window.d.ts b/ts/window.d.ts index b7c282656..065e1536c 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -100,10 +100,5 @@ declare global { darkTheme: DefaultTheme; LokiPushNotificationServer: any; LokiPushNotificationServerApi: any; - - getConversationController: () => ConversationController; - getOrCreateAndWait: () => Promise; - - commitProfileEdits: (string, string) => void; } }