Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DDW-786] Discreet mode - Create the TopBar icon #2725

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
## vNext

### Features
- Implemented "discreet mode" ([PR 2723](https://github.com/input-output-hk/daedalus/pull/2723), [PR 2724](https://github.com/input-output-hk/daedalus/pull/2724))

- Implemented "discreet mode" ([PR 2723](https://github.com/input-output-hk/daedalus/pull/2723), [PR 2724](https://github.com/input-output-hk/daedalus/pull/2724), [PR 2725](https://github.com/input-output-hk/daedalus/pull/2725))
- Implemented "Catalyst Fund7" voting registration changes ([PR 2732](https://github.com/input-output-hk/daedalus/pull/2732))
- Added Over-saturation warning in delegation wizard ([PR 2733](https://github.com/input-output-hk/daedalus/pull/2733))
- Added Catalyst footer links ([PR 2721](https://github.com/input-output-hk/daedalus/pull/2721))
Expand Down
28 changes: 28 additions & 0 deletions source/renderer/app/components/layout/TopBar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,32 @@
position: absolute;
width: calc(100% - 140px);
}

.discreetModeToggle {
position: absolute;
right: 91px;

&.hasTadaIcon {
right: 149px;
}

svg {
path {
fill: var(--theme-node-sync-icon-color);
}
}
}

.rectangle {
&.hasTadaIcon {
right: 220px;
}

background-color: var(--theme-node-sync-icon-color);
height: 12px;
opacity: 0.3;
position: absolute;
right: 162px;
width: 1px;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.component {
overflow: visible;
position: absolute;
right: 100px;
right: 202px;

&.hasTadaIcon {
right: 162px;
right: 260px;
}

&:hover {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// @flow
import React from 'react';
import SVGInline from 'react-svg-inline';
import classNames from 'classnames';
import { PopOver } from 'react-polymorph/lib/components/PopOver';
import { intlShape, injectIntl } from 'react-intl';
import revealIcon from '../../../assets/images/reveal-key.inline.svg';
import hideIcon from '../../../assets/images/hide-key.inline.svg';
import styles from './DiscreetToggle.scss';
import { messages } from './DiscreetToggle.messages';

type Props = {
className?: string,
intl: intlShape.isRequired,
isDiscreetMode?: Boolean,
onToggle: Function,
};

const DiscreetToggle = ({
className,
intl,
isDiscreetMode = true,
onToggle,
}: Props) => {
return (
<div className={classNames(styles.root, className)}>
<PopOver
content={
<span className={styles.tooltip}>
{intl.formatMessage(
messages[isDiscreetMode ? 'discreetModeOff' : 'discreetModeOn']
)}
</span>
}
>
<button className={styles.button} onClick={onToggle}>
<SVGInline
svg={isDiscreetMode ? hideIcon : revealIcon}
className={classNames(
styles.icon,
isDiscreetMode && styles.hideIcon
)}
/>
</button>
</PopOver>
</div>
);
};

export default injectIntl(DiscreetToggle);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @flow
import { defineMessages } from 'react-intl';

export const messages = defineMessages({
discreetModeOn: {
id: 'widgets.discreetToggle.on',
defaultMessage: '!!!Toggle discreet mode on',
description:
'Text for the tooltip on "discreet mode" button when mode is on',
},
discreetModeOff: {
id: 'widgets.discreetToggle.off',
defaultMessage: '!!!Toggle discreet mode off',
description:
'Text for the tooltip on "discreet mode" button when mode is off',
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.root {
.button {
border-radius: 50%;
cursor: pointer;
height: 44px;
opacity: 0.4;
width: 44px;

&:hover {
background-color: var(
--theme-news-feed-icon-toggle-hover-background-color
);
opacity: 0.8;
}
}

.icon {
svg {
height: 15px;
lucas-barros marked this conversation as resolved.
Show resolved Hide resolved
width: 21px;
}

&.hideIcon {
svg {
height: 18px;
}
}
}
}

.tooltip {
font-family: var(--font-light);
font-size: 14px;
}
206 changes: 110 additions & 96 deletions source/renderer/app/containers/TopBarContainer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// @flow
import React, { Component } from 'react';
import React from 'react';
import { observer, inject } from 'mobx-react';
import classnames from 'classnames';
import TopBar from '../components/layout/TopBar';
import NodeSyncStatusIcon from '../components/widgets/NodeSyncStatusIcon';
import DiscreetToggle from '../components/widgets/discreet-mode/DiscreetToggle';
import NewsFeedIcon from '../components/widgets/NewsFeedIcon';
import TadaButton from '../components/widgets/TadaButton';
import WalletTestEnvironmentLabel from '../components/widgets/WalletTestEnvironmentLabel';
Expand All @@ -12,109 +14,121 @@ import menuIconClosed from '../assets/images/menu-ic.inline.svg';
import { matchRoute } from '../utils/routing';
import { ROUTES } from '../routes-config';
import { IS_TADA_ICON_AVAILABLE } from '../config/topBarConfig';
import topBarStyles from '../components/layout/TopBar.scss';
import { useDiscreetModeFeature } from '../features/discreet-mode';

type Props = InjectedProps;
const TopBarContainer = (
{ actions, stores }: InjectedProps = { actions: null, stores: null }
) => {
const {
sidebar,
app,
networkStatus,
wallets,
newsFeed,
appUpdate,
staking,
} = stores;
const {
isSynced,
syncPercentage,
isShelleyActivated,
isAlonzoActivated,
isAlonzoPending,
} = networkStatus;
const { stakingInfoWasOpen } = staking;
const shouldShowTadaIconAnimation = isAlonzoActivated && !stakingInfoWasOpen;
const shouldShowTadaIcon =
IS_TADA_ICON_AVAILABLE && (isAlonzoPending || isAlonzoActivated);

@inject('stores', 'actions')
@observer
export default class TopBarContainer extends Component<Props> {
static defaultProps = { actions: null, stores: null };
const { active, isWalletRoute, hasAnyWallets, hasRewardsWallets } = wallets;
const {
currentRoute,
environment: { isMainnet, network },
openExternalLink,
} = app;
const walletRoutesMatch = matchRoute(
`${ROUTES.WALLETS.ROOT}/:id(*page)`,
currentRoute
);
const showSubMenuToggle = isWalletRoute && hasAnyWallets;
const activeWallet = walletRoutesMatch && active != null ? active : null;
const leftIconSVG = sidebar.isShowingSubMenus
? menuIconOpened
: menuIconClosed;
const leftIcon = showSubMenuToggle ? leftIconSVG : null;
const testnetLabel = !isMainnet ? (
<WalletTestEnvironmentLabel network={network} />
) : null;

render() {
const { actions, stores } = this.props;
const {
sidebar,
app,
networkStatus,
wallets,
newsFeed,
appUpdate,
staking,
} = stores;
const {
isSynced,
syncPercentage,
isShelleyActivated,
isAlonzoActivated,
isAlonzoPending,
} = networkStatus;
const { stakingInfoWasOpen } = staking;
const shouldShowTadaIconAnimation =
isAlonzoActivated && !stakingInfoWasOpen;
const shouldShowTadaIcon =
IS_TADA_ICON_AVAILABLE && (isAlonzoPending || isAlonzoActivated);
const onWalletAdd = () => {
actions.router.goToRoute.trigger({
route: ROUTES.WALLETS.ADD,
});
};

const { active, isWalletRoute, hasAnyWallets, hasRewardsWallets } = wallets;
const {
currentRoute,
environment: { isMainnet, network },
openExternalLink,
} = app;
const walletRoutesMatch = matchRoute(
`${ROUTES.WALLETS.ROOT}/:id(*page)`,
currentRoute
);
const showSubMenuToggle = isWalletRoute && hasAnyWallets;
const activeWallet = walletRoutesMatch && active != null ? active : null;
const leftIconSVG = sidebar.isShowingSubMenus
? menuIconOpened
: menuIconClosed;
const leftIcon = showSubMenuToggle ? leftIconSVG : null;
const testnetLabel = !isMainnet ? (
<WalletTestEnvironmentLabel network={network} />
) : null;
const onClickTadaButton = () => {
actions.router.goToRoute.trigger({
route: ROUTES.STAKING.INFO,
});
};

const onWalletAdd = () => {
actions.router.goToRoute.trigger({
route: ROUTES.WALLETS.ADD,
});
};
const onTransferFunds = (sourceWalletId: string) =>
actions.wallets.transferFundsSetSourceWalletId.trigger({
sourceWalletId,
});

const onClickTadaButton = () => {
actions.router.goToRoute.trigger({
route: ROUTES.STAKING.INFO,
});
};
const { unread } = newsFeed.newsFeedData;
const { displayAppUpdateNewsItem } = appUpdate;

const onTransferFunds = (sourceWalletId: string) =>
actions.wallets.transferFundsSetSourceWalletId.trigger({
sourceWalletId,
});
const hasUnreadNews = unread.length > 0;

const { unread } = newsFeed.newsFeedData;
const { displayAppUpdateNewsItem } = appUpdate;
const discreetModeFeature = useDiscreetModeFeature();

const hasUnreadNews = unread.length > 0;

return (
<TopBar
leftIcon={leftIcon}
onLeftIconClick={actions.sidebar.toggleSubMenus.trigger}
activeWallet={activeWallet}
onTransferFunds={onTransferFunds}
hasRewardsWallets={hasRewardsWallets}
onWalletAdd={onWalletAdd}
onLearnMore={openExternalLink}
isShelleyActivated={isShelleyActivated}
>
{testnetLabel}
<NodeSyncStatusIcon
isSynced={isSynced}
syncPercentage={syncPercentage}
hasTadaIcon={shouldShowTadaIcon}
/>
{shouldShowTadaIcon && (
<TadaButton
onClick={onClickTadaButton}
shouldAnimate={shouldShowTadaIconAnimation}
/>
return (
<TopBar
leftIcon={leftIcon}
onLeftIconClick={actions.sidebar.toggleSubMenus.trigger}
activeWallet={activeWallet}
onTransferFunds={onTransferFunds}
hasRewardsWallets={hasRewardsWallets}
onWalletAdd={onWalletAdd}
onLearnMore={openExternalLink}
isShelleyActivated={isShelleyActivated}
>
{testnetLabel}
<NodeSyncStatusIcon
isSynced={isSynced}
syncPercentage={syncPercentage}
hasTadaIcon={shouldShowTadaIcon}
/>
<span
className={classnames(
topBarStyles.rectangle,
shouldShowTadaIcon && topBarStyles.hasTadaIcon
)}
<NewsFeedIcon
onNewsFeedIconClick={actions.app.toggleNewsFeed.trigger}
hasNotification={hasUnreadNews}
hasUpdate={displayAppUpdateNewsItem}
/>
<DiscreetToggle
className={classnames(
topBarStyles.discreetModeToggle,
shouldShowTadaIcon && topBarStyles.hasTadaIcon
)}
isDiscreetMode={discreetModeFeature.isDiscreetMode}
onToggle={discreetModeFeature.toggleDiscreetMode}
/>
{shouldShowTadaIcon && (
<TadaButton
onClick={onClickTadaButton}
shouldAnimate={shouldShowTadaIconAnimation}
/>
</TopBar>
);
}
}
)}
<NewsFeedIcon
onNewsFeedIconClick={actions.app.toggleNewsFeed.trigger}
hasNotification={hasUnreadNews}
hasUpdate={displayAppUpdateNewsItem}
/>
</TopBar>
);
};

export default inject('stores', 'actions')(observer(TopBarContainer));
Loading