Making some PR changes.

pull/1665/head
Warrick Corfe-Tan 4 years ago
parent ec39f7ae9b
commit e435b6c932

@ -13,7 +13,6 @@ const { Message } = require('../../ts/components/conversation/Message');
// Components // Components
const { EditProfileDialog } = require('../../ts/components/EditProfileDialog'); const { EditProfileDialog } = require('../../ts/components/EditProfileDialog');
const { OnionStatusDialog } = require('../../ts/components/OnionStatusDialog');
const { UserDetailsDialog } = require('../../ts/components/UserDetailsDialog'); const { UserDetailsDialog } = require('../../ts/components/UserDetailsDialog');
const { SessionSeedModal } = require('../../ts/components/session/SessionSeedModal'); const { SessionSeedModal } = require('../../ts/components/session/SessionSeedModal');
const { SessionNicknameDialog } = require('../../ts/components/session/SessionNicknameDialog'); const { SessionNicknameDialog } = require('../../ts/components/session/SessionNicknameDialog');
@ -142,7 +141,6 @@ exports.setup = (options = {}) => {
const Components = { const Components = {
EditProfileDialog, EditProfileDialog,
OnionStatusDialog,
UserDetailsDialog, UserDetailsDialog,
SessionInboxView, SessionInboxView,
UpdateGroupNameDialog, UpdateGroupNameDialog,

@ -126,12 +126,6 @@
const dialog = new Whisper.SessionNicknameDialog(modifiedOptions); const dialog = new Whisper.SessionNicknameDialog(modifiedOptions);
this.el.prepend(dialog.el); 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() { showResetSessionIdDialog() {
const theme = this.getThemeObject(); const theme = this.getThemeObject();
const resetSessionIDDialog = new Whisper.SessionIDResetDialog({ theme }); const resetSessionIDDialog = new Whisper.SessionIDResetDialog({ theme });

@ -1,37 +1,37 @@
/* global i18n, Whisper */ // /* global i18n, Whisper */
// eslint-disable-next-line func-names // // eslint-disable-next-line func-names
(function() { // (function() {
'use strict'; // 'use strict';
window.Whisper = window.Whisper || {}; // window.Whisper = window.Whisper || {};
Whisper.OnionStatusDialogView = Whisper.View.extend({ // Whisper.OnionStatusDialogView = Whisper.View.extend({
className: 'loki-dialog modal', // className: 'loki-dialog modal',
initialize({ theme }) { // initialize({ theme }) {
this.close = this.close.bind(this); // this.close = this.close.bind(this);
this.theme = theme; // this.theme = theme;
this.$el.focus(); // this.$el.focus();
this.render(); // this.render();
}, // },
render() { // render() {
this.dialogView = new Whisper.ReactWrapperView({ // this.dialogView = new Whisper.ReactWrapperView({
className: 'onion-status-dialog', // className: 'onion-status-dialog',
Component: window.Signal.Components.OnionStatusDialog, // Component: window.Signal.Components.OnionStatusDialog,
props: { // props: {
onClose: this.close, // onClose: this.close,
i18n, // i18n,
theme: this.theme, // theme: this.theme,
}, // },
}); // });
this.$el.append(this.dialogView.el); // this.$el.append(this.dialogView.el);
return this; // return this;
}, // },
close() { // close() {
this.remove(); // this.remove();
}, // },
}); // });
})(); // })();

@ -7,7 +7,6 @@ import { Avatar, AvatarSize } from './Avatar';
import { SessionButton, SessionButtonColor, SessionButtonType } from './session/SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from './session/SessionButton';
import { SessionIconButton, SessionIconSize, SessionIconType } from './session/icon'; import { SessionIconButton, SessionIconSize, SessionIconType } from './session/icon';
import { SessionModal } from './session/SessionModal';
import { PillDivider } from './session/PillDivider'; import { PillDivider } from './session/PillDivider';
import { AttachmentUtils, SyncUtils, ToastUtils, UserUtils } from '../session/utils'; import { AttachmentUtils, SyncUtils, ToastUtils, UserUtils } from '../session/utils';
import { DefaultTheme, useTheme } from 'styled-components'; import { DefaultTheme, useTheme } from 'styled-components';
@ -15,15 +14,15 @@ import { MAX_USERNAME_LENGTH } from './session/registration/RegistrationTabs';
import { SessionSpinner } from './session/SessionSpinner'; import { SessionSpinner } from './session/SessionSpinner';
import { ConversationTypeEnum } from '../models/conversation'; 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 { SessionWrapperModal } from './session/SessionWrapperModal';
import { times } from 'underscore';
import { AttachmentUtil, } from '../util'; import { AttachmentUtil, } from '../util';
import { LocalizerType } from '../types/Util';
import { ConversationController } from '../session/conversations';
interface Props { interface Props {
i18n?: any; i18n?: LocalizerType;
profileName?: string; profileName?: string;
avatarPath?: string; avatarPath?: string;
pubkey?: string; pubkey?: string;
@ -42,7 +41,7 @@ interface State {
export class EditProfileDialog extends React.Component<Props, State> { export class EditProfileDialog extends React.Component<Props, State> {
private readonly inputEl: any; private readonly inputEl: any;
private conversationController = ConversationController.getInstance();
constructor(props: any) { constructor(props: any) {
super(props); super(props);
@ -67,11 +66,11 @@ export class EditProfileDialog extends React.Component<Props, State> {
window.addEventListener('keyup', this.onKeyUp); window.addEventListener('keyup', this.onKeyUp);
} }
async componentDidMount() { async componentDidMount() {
const ourNumber = window.storage.get('primaryDevicePubKey'); const ourNumber = window.storage.get('primaryDevicePubKey');
const conversation = await window const conversation = await this.conversationController.getOrCreateAndWait(ourNumber, ConversationTypeEnum.PRIVATE);
.getConversationController()
.getOrCreateAndWait(ourNumber, ConversationTypeEnum.PRIVATE);
const readFile = (attachment: any) => const readFile = (attachment: any) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
@ -374,7 +373,7 @@ export class EditProfileDialog extends React.Component<Props, State> {
private async commitProfileEdits(newName: string, avatar: any) { private async commitProfileEdits(newName: string, avatar: any) {
let ourNumber = window.storage.get('primaryDevicePubKey'); 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 newAvatarPath = '';
let url: any = null; let url: any = null;
@ -467,9 +466,7 @@ export class EditProfileDialog extends React.Component<Props, State> {
window.lokiPublicChatAPI.setProfileName(newName); window.lokiPublicChatAPI.setProfileName(newName);
if (avatar) { if (avatar) {
window this.conversationController.getConversations()
.getConversationController()
.getConversations()
.filter(convo => convo.isPublic()) .filter(convo => convo.isPublic())
.forEach(convo => convo.trigger('ourAvatarChanged', { url, profileKey })); .forEach(convo => convo.trigger('ourAvatarChanged', { url, profileKey }));
} }

@ -7,7 +7,7 @@ import { getTheme } from '../state/selectors/theme';
import electron from 'electron'; import electron from 'electron';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { StateType } from '../state/reducer'; import { StateType } from '../state/reducer';
import { SessionIcon, SessionIconSize, SessionIconType } from './session/icon'; import { SessionIcon, SessionIconButton, SessionIconSize, SessionIconType } from './session/icon';
const { shell } = electron; const { shell } = electron;
import { SessionWrapperModal } from '../components/session/SessionWrapperModal'; import { SessionWrapperModal } from '../components/session/SessionWrapperModal';
@ -16,6 +16,7 @@ import { Snode } from '../session/onions';
import ip2country from 'ip2country'; import ip2country from 'ip2country';
import countryLookup from 'country-code-lookup'; import countryLookup from 'country-code-lookup';
import { useTheme } from 'styled-components'; import { useTheme } from 'styled-components';
import { useNetwork } from '../hooks/useNetwork';
export type OnionPathModalType = { export type OnionPathModalType = {
onConfirm?: () => void; onConfirm?: () => void;
@ -52,14 +53,12 @@ const OnionPathModalInner = (props: any) => {
<div className="onion__node-list"> <div className="onion__node-list">
{nodes.map((snode: Snode | any, index: number) => { {nodes.map((snode: Snode | any, index: number) => {
return ( return (
<> <OnionNodeStatusLight
<OnionNodeStatusLight glowDuration={glowDuration}
glowDuration={glowDuration} glowStartDelay={index}
glowStartDelay={index} label={snode.label}
label={snode.label} snode={snode}
snode={snode} />
></OnionNodeStatusLight>
</>
); );
})} })}
</div> </div>
@ -88,11 +87,11 @@ export const OnionNodeStatusLight = (props: OnionNodeStatusLightType): JSX.Eleme
} }
return ( return (
<div className="onion__node"> <div className="onion__node">
<StatusLight <ModalStatusLight
glowDuration={glowDuration} glowDuration={glowDuration}
glowStartDelay={glowStartDelay} glowStartDelay={glowStartDelay}
color={theme.colors.accent} color={theme.colors.accent}
></StatusLight> ></ModalStatusLight>
{labelText ? ( {labelText ? (
<> <>
<div className="onion-node__country">{labelText}</div> <div className="onion-node__country">{labelText}</div>
@ -105,25 +104,66 @@ export const OnionNodeStatusLight = (props: OnionNodeStatusLightType): JSX.Eleme
/** /**
* An icon with a pulsating glow emission. * An icon with a pulsating glow emission.
*/ */
export const StatusLight = (props: StatusLightType) => { export const ModalStatusLight = (props: StatusLightType) => {
const { glowStartDelay, glowDuration, color } = props; const { glowStartDelay, glowDuration, color } = props;
const theme = useSelector(getTheme); const theme = useSelector(getTheme);
return ( return (
<> <SessionIcon
<SessionIcon borderRadius={50}
borderRadius={50} iconColor={color}
iconColor={color} glowDuration={glowDuration}
glowDuration={glowDuration} glowStartDelay={glowStartDelay}
glowStartDelay={glowStartDelay} iconType={SessionIconType.Circle}
iconType={SessionIconType.Circle} iconSize={SessionIconSize.Medium}
iconSize={SessionIconSize.Medium} theme={theme}
theme={theme} />
/>
</>
); );
}; };
/**
* 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 <SessionIconButton
iconSize={SessionIconSize.Medium}
iconType={SessionIconType.Circle}
iconColor={iconColor}
onClick={handleClick}
isSelected={isSelected}
theme={theme}
/>
}
export const OnionPathModal = (props: OnionPathModalType) => { export const OnionPathModal = (props: OnionPathModalType) => {
const onConfirm = () => { const onConfirm = () => {
shell.openExternal('https://getsession.org/faq/#onion-routing'); shell.openExternal('https://getsession.org/faq/#onion-routing');

@ -11,9 +11,8 @@ import {
generateAttachmentKeyIfEmpty, generateAttachmentKeyIfEmpty,
getItemById, getItemById,
hasSyncedInitialConfigurationItem, hasSyncedInitialConfigurationItem,
removeItemById,
} from '../../data/data'; } from '../../data/data';
import { OnionPaths, Snode, SnodePath } from '../../session/onions'; import { OnionPaths } from '../../session/onions';
import { getMessageQueue } from '../../session/sending'; import { getMessageQueue } from '../../session/sending';
import { clearSessionsAndPreKeys } from '../../util/accountManager'; import { clearSessionsAndPreKeys } from '../../util/accountManager';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
@ -34,14 +33,9 @@ import { OpenGroupManagerV2 } from '../../opengroup/opengroupV2/OpenGroupManager
import { loadDefaultRooms } from '../../opengroup/opengroupV2/ApiUtil'; import { loadDefaultRooms } from '../../opengroup/opengroupV2/ApiUtil';
import { forceRefreshRandomSnodePool } from '../../session/snode_api/snodePool'; import { forceRefreshRandomSnodePool } from '../../session/snode_api/snodePool';
import { SwarmPolling } from '../../session/snode_api/swarmPolling'; 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 _ from 'lodash';
import { useNetwork } from '../../hooks/useNetwork'; import { ActionPanelOnionStatusLight, OnionPathModal } from '../OnionStatusDialog';
import { OnionPathModal } from '../OnionStatusDialog';
import { EditProfileDialog } from '../EditProfileDialog'; import { EditProfileDialog } from '../EditProfileDialog';
import { useTheme } from 'styled-components';
// tslint:disable-next-line: no-import-side-effect no-submodule-imports // tslint:disable-next-line: no-import-side-effect no-submodule-imports
@ -59,13 +53,12 @@ const Section = (props: {
setModal?: any; setModal?: any;
type: SectionType; type: SectionType;
avatarPath?: string; avatarPath?: string;
hasOnionPath?: boolean;
}) => { }) => {
const ourNumber = useSelector(getOurNumber); const ourNumber = useSelector(getOurNumber);
const unreadMessageCount = useSelector(getUnreadMessageCount); const unreadMessageCount = useSelector(getUnreadMessageCount);
const theme = useSelector(getTheme); const theme = useSelector(getTheme);
const dispatch = useDispatch(); const dispatch = useDispatch();
const { setModal, type, avatarPath, hasOnionPath } = props; const { setModal, type, avatarPath } = props;
const focusedSection = useSelector(getFocusedSection); const focusedSection = useSelector(getFocusedSection);
const isSelected = focusedSection === props.type; const isSelected = focusedSection === props.type;
@ -116,25 +109,6 @@ const Section = (props: {
let iconColor = undefined; let iconColor = undefined;
if (type === SectionType.PathIndicator) { 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; const unreadToShow = type === SectionType.Message ? unreadMessageCount : undefined;
@ -153,15 +127,18 @@ const Section = (props: {
case SectionType.Moon: case SectionType.Moon:
iconType = SessionIconType.Moon; iconType = SessionIconType.Moon;
break; break;
case SectionType.PathIndicator:
iconType = SessionIconType.Circle;
break;
default: default:
iconType = SessionIconType.Moon; iconType = SessionIconType.Moon;
} }
return ( return (
<> <>
{type === SectionType.PathIndicator ?
<ActionPanelOnionStatusLight
handleClick={handleClick}
isSelected={isSelected}
/>
:
<SessionIconButton <SessionIconButton
iconSize={SessionIconSize.Medium} iconSize={SessionIconSize.Medium}
iconType={iconType} iconType={iconType}
@ -171,6 +148,7 @@ const Section = (props: {
isSelected={isSelected} isSelected={isSelected}
theme={theme} theme={theme}
/> />
}
</> </>
); );
}; };
@ -245,9 +223,7 @@ const doAppStartUp = (dispatch: Dispatch<any>) => {
export const ActionsPanel = () => { export const ActionsPanel = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [startCleanUpMedia, setStartCleanUpMedia] = useState(false); const [startCleanUpMedia, setStartCleanUpMedia] = useState(false);
const [hasOnionPath, setHasOnionPath] = useState<boolean>(false);
const ourPrimaryConversation = useSelector(getOurPrimaryConversation); const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
const [modal, setModal] = useState<any>(null); const [modal, setModal] = useState<any>(null);
// this maxi useEffect is called only once: when the component is mounted. // this maxi useEffect is called only once: when the component is mounted.
@ -264,15 +240,6 @@ export const ActionsPanel = () => {
return () => global.clearTimeout(timeout); return () => global.clearTimeout(timeout);
}, []); }, []);
const getOnionPathIndicator = () => {
const hasOnionPath = getOnionPathStatus();
setHasOnionPath(hasOnionPath);
};
useInterval(() => {
getOnionPathIndicator();
}, 1000);
useInterval( useInterval(
() => { () => {
cleanUpOldDecryptedMedias(); cleanUpOldDecryptedMedias();
@ -300,15 +267,15 @@ export const ActionsPanel = () => {
type={SectionType.Profile} type={SectionType.Profile}
avatarPath={ourPrimaryConversation.avatarPath} avatarPath={ourPrimaryConversation.avatarPath}
/> />
<Section setModal={setModal} type={SectionType.Message} /> <Section type={SectionType.Message} />
<Section setModal={setModal} type={SectionType.Contact} /> <Section type={SectionType.Contact} />
<Section setModal={setModal} type={SectionType.Settings} /> <Section type={SectionType.Settings} />
{modal ? modal : null} {modal ? modal : null}
<SessionToastContainer /> <SessionToastContainer />
<Section setModal={setModal} type={SectionType.PathIndicator} hasOnionPath={hasOnionPath} /> <Section setModal={setModal} type={SectionType.PathIndicator} />
<Section setModal={setModal} type={SectionType.Moon} /> <Section type={SectionType.Moon} />
</div> </div>
); );
}; };

@ -121,28 +121,6 @@ export const getOnionPathForSending = async (requestNumber: number) => {
return pathNodes; 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<Snode> = [];
let displayNode: Array<string> = [];
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 initOptionsWithDefaults = (options: OnionFetchBasicOptions) => {
const defaultFetchBasicOptions = { const defaultFetchBasicOptions = {
retry: 0, retry: 0,

5
ts/window.d.ts vendored

@ -100,10 +100,5 @@ declare global {
darkTheme: DefaultTheme; darkTheme: DefaultTheme;
LokiPushNotificationServer: any; LokiPushNotificationServer: any;
LokiPushNotificationServerApi: any; LokiPushNotificationServerApi: any;
getConversationController: () => ConversationController;
getOrCreateAndWait: () => Promise<ConversationModel>;
commitProfileEdits: (string, string) => void;
} }
} }

Loading…
Cancel
Save