Skip to content

Commit

Permalink
Merge branch 'main' into feat/update-post-saga-to-support-media-uploa…
Browse files Browse the repository at this point in the history
…ds-create-optimistic-posts-handle-media-mapping-in-events-and-update-send-post-tests-for-full-functionality
  • Loading branch information
domw30 committed Sep 5, 2024
2 parents 80ff320 + 829e305 commit cdd58b7
Show file tree
Hide file tree
Showing 15 changed files with 278 additions and 96 deletions.
15 changes: 15 additions & 0 deletions src/components/message/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
&--owner {
flex-direction: row-reverse;

.message__block {
background: none !important;

&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--color-secondary-8);
opacity: 0.5;
}
}

.message__block-body {
transition: background-color 0.3s ease-out;
position: relative;
Expand Down
14 changes: 9 additions & 5 deletions src/components/messenger/feed/components/post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const Post = ({ avatarUrl, text, nickname, author, timestamp }: PostProps
);

return (
<div className={styles.Container}>
<div className={styles.Container} has-author={author ? '' : null}>
<div className={styles.Avatar}>
<Avatar size='regular' imageURL={avatarUrl} />
</div>
Expand All @@ -38,10 +38,14 @@ export const Post = ({ avatarUrl, text, nickname, author, timestamp }: PostProps
<Name className={styles.Name} variant='name'>
{nickname}
</Name>
{/* @ts-ignore */}
<Name className={styles.UserName} variant='username'>
{author}
</Name>
{author && (
<>
{/* @ts-ignore */}
<Name className={styles.UserName} variant='username'>
{author}
</Name>
</>
)}
</>
}
options={<Timestamp className={styles.Date} timestamp={timestamp} />}
Expand Down
13 changes: 13 additions & 0 deletions src/components/messenger/feed/components/post/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
.Container {
display: flex;
gap: 8px;

&:not([has-author]) {
[class*='_Header'] {
align-items: center;
margin-top: 8px;
}
}

&[has-author] {
[class*='_Header'] {
margin-top: 4px;
}
}
}

.Post {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Container } from './container';
import { Errors, AccountManagementState } from '../../../../store/account-management';
import { RootState } from '../../../../store/reducer';
import { ConnectionStatus } from '../../../../lib/web3';

describe('Container', () => {
describe('mapState', () => {
const subject = (inputState: Partial<RootState> = {}) => {
const state = {
authentication: { user: {} },
web3: { value: {} },
accountManagement: { errors: [], isWalletSelectModalOpen: false },
accountManagement: { errors: [] },
...inputState,
} as RootState;
return Container.mapState(state);
Expand All @@ -30,6 +31,32 @@ describe('Container', () => {
expect(props.successMessage).toEqual('success');
});

it('connectedWallet', () => {
const props = subject({
web3: { value: { address: 'address123' } } as any,
});

expect(props.connectedWallet).toEqual('address123');
});

describe('isWalletConnected', () => {
it('connected', () => {
const props = subject({
web3: { status: ConnectionStatus.Connected } as any,
});

expect(props.isWalletConnected).toEqual(true);
});

it('disconnected', () => {
const props = subject({
web3: { status: ConnectionStatus.Disconnected } as any,
});

expect(props.isWalletConnected).toEqual(false);
});
});

describe('errors', () => {
test('wallets error: unknown error', () => {
const props = subject({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { connectContainer } from '../../../../store/redux-container';
import { AccountManagementPanel } from './index';
import { openAddEmailAccountModal, closeAddEmailAccountModal, Errors } from '../../../../store/account-management';
import { currentUserSelector } from '../../../../store/authentication/selectors';
import { ConnectionStatus } from '../../../../lib/web3';

export interface PublicProperties {
onClose?: () => void;
Expand All @@ -17,14 +18,19 @@ export interface Properties extends PublicProperties {
successMessage: string;
currentUser: any;
canAddEmail: boolean;
isWalletConnected: boolean;
connectedWallet: string;

openAddEmailAccountModal: () => void;
closeAddEmailAccountModal: () => void;
}

export class Container extends React.Component<Properties> {
static mapState(state: RootState): Partial<Properties> {
const { accountManagement } = state;
const {
accountManagement,
web3: { status, value },
} = state;

const currentUser = currentUserSelector(state);
const primaryEmail = currentUser?.profileSummary.primaryEmail;
Expand All @@ -33,6 +39,8 @@ export class Container extends React.Component<Properties> {
error: Container.mapErrors(accountManagement.errors),
successMessage: accountManagement.successMessage,
isAddEmailModalOpen: accountManagement.isAddEmailAccountModalOpen,
isWalletConnected: status === ConnectionStatus.Connected,
connectedWallet: value?.address,
currentUser: {
userId: currentUser?.id,
firstName: currentUser?.profileSummary.firstName,
Expand Down Expand Up @@ -71,6 +79,8 @@ export class Container extends React.Component<Properties> {
isAddEmailModalOpen={this.props.isAddEmailModalOpen}
currentUser={this.props.currentUser}
canAddEmail={this.props.canAddEmail}
isWalletConnected={this.props.isWalletConnected}
connectedWallet={this.props.connectedWallet}
onOpenAddEmailModal={() => this.props.openAddEmailAccountModal()}
onCloseAddEmailModal={() => this.props.closeAddEmailAccountModal()}
onBack={this.props.onClose}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ import { Properties, AccountManagementPanel } from '.';
import { PanelHeader } from '../../list/panel-header';
import { bem } from '../../../../lib/bem';
import { Button } from '@zero-tech/zui/components/Button';
import { ConnectButton } from '@rainbow-me/rainbowkit';

const featureFlags = { enableAddWallets: true };
jest.mock('../../../../lib/feature-flags', () => ({
featureFlags: featureFlags,
}));

// Mock the ConnectButton from rainbowkit
jest.mock('@rainbow-me/rainbowkit', () => ({
ConnectButton: {
Custom: ({ children }) => children({ account: { address: '0x123' }, openConnectModal: jest.fn() }),
},
}));

const c = bem('.account-management-panel');

Expand All @@ -15,6 +28,8 @@ describe(AccountManagementPanel, () => {
isAddEmailModalOpen: false,
currentUser: {},
canAddEmail: false,
isWalletConnected: false,
connectedWallet: '',

onBack: () => {},
onOpenAddEmailModal: () => {},
Expand Down Expand Up @@ -182,4 +197,47 @@ describe(AccountManagementPanel, () => {
expect(onCloseAddEmailModal).toHaveBeenCalled();
});
});

describe('link new wallet', () => {
it('should render Add Wallet button if user has no wallet linked to his ZERO account', () => {
const wrapper = subject({ currentUser: { primaryEmail: '[email protected]', wallets: [] } });

expect(wrapper.find(ConnectButton.Custom).exists()).toEqual(true);
});

it('should not render Add Wallet button if user has a wallet linked to his ZERO account', () => {
const wrapper = subject({ currentUser: { primaryEmail: '[email protected]', wallets: [{ id: 'wallet-id-1' }] } });
expect(wrapper.find(ConnectButton.Custom).exists()).toEqual(false);
});

it('should open Link Wallet modal when user clicks on Add Wallet, and metamask is connected', () => {
const wrapper = subject({
currentUser: { primaryEmail: '[email protected]', wallets: [] },
isWalletConnected: true,
connectedWallet: '0xA100C16E67884Da7d515211Bb065592079bEcde6',
});

wrapper.setState({ isUserLinkingNewWallet: true });

const linkWalletModal = wrapper.find('Modal').at(1);
expect(linkWalletModal.exists()).toEqual(true);
expect(linkWalletModal.prop('title')).toEqual('Link Wallet');
expect(linkWalletModal.find(c('link-new-wallet-modal')).text()).toEqual(
'You have a wallet connected by the address 0xA100C16E67884Da7d515211Bb065592079bEcde6Do you want to link this wallet with your ZERO account?'
);
});

it('should update isUserLinkingNewWallet state to false when user closes Link Wallet modal', () => {
const wrapper = subject({
currentUser: { primaryEmail: '[email protected]', wallets: [] },
isWalletConnected: true,
});

wrapper.setState({ isUserLinkingNewWallet: true });

const linkWalletModal = wrapper.find('Modal').at(1);
(linkWalletModal as any).props().onClose();
expect(wrapper.state('isUserLinkingNewWallet')).toEqual(false);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react';
import { bemClassName } from '../../../../lib/bem';
import { PanelHeader } from '../../list/panel-header';
import { Button, Variant as ButtonVariant } from '@zero-tech/zui/components/Button';
import { Alert, Modal, IconButton } from '@zero-tech/zui/components';
import { Alert, Modal as ZuiModal, IconButton } from '@zero-tech/zui/components';

import { IconPlus } from '@zero-tech/zui/icons';
import './styles.scss';
Expand All @@ -12,6 +12,9 @@ import { CitizenListItem } from '../../../citizen-list-item';
import { IconXClose } from '@zero-tech/zui/icons';
import { CreateEmailAccountContainer } from '../../../../authentication/create-email-account/container';
import { ScrollbarContainer } from '../../../scrollbar-container';
import { ConnectButton } from '@rainbow-me/rainbowkit';
import { Color, Modal, Variant } from '../../../modal';
import { featureFlags } from '../../../../lib/feature-flags';

const cn = bemClassName('account-management-panel');

Expand All @@ -21,24 +24,58 @@ export interface Properties {
successMessage: string;
currentUser: any;
canAddEmail: boolean;
isWalletConnected: boolean;
connectedWallet: string;

onBack: () => void;
onOpenAddEmailModal: () => void;
onCloseAddEmailModal: () => void;
}

export class AccountManagementPanel extends React.Component<Properties> {
interface State {
isUserLinkingNewWallet: boolean;
}

export class AccountManagementPanel extends React.Component<Properties, State> {
state = {
isUserLinkingNewWallet: false,
};

setIsUserLinkingNewWallet = (isUserLinkingNewWallet: boolean) => {
this.setState({ isUserLinkingNewWallet });
};

back = () => {
this.props.onBack();
};

// note: hiding this for now
renderAddNewWalletButton = () => {
const handleAddWallet = (account, openConnectModal) => {
this.setIsUserLinkingNewWallet(true);

if (!account?.address) {
// Prompt user to connect their wallet if none is connected
openConnectModal();
}

// Otherwise, wallet is already connected, proceed to the next step
};

return (
<div {...cn('add-wallet')}>
<Button variant={ButtonVariant.Secondary} onPress={() => {}} startEnhancer={<IconPlus size={20} isFilled />}>
Add new wallet
</Button>
<ConnectButton.Custom>
{({ account, openConnectModal }) => {
return (
<Button
variant={ButtonVariant.Secondary}
onPress={() => handleAddWallet(account, openConnectModal)}
startEnhancer={<IconPlus size={20} isFilled />}
>
Add wallet
</Button>
);
}}
</ConnectButton.Custom>
</div>
);
};
Expand All @@ -61,6 +98,8 @@ export class AccountManagementPanel extends React.Component<Properties> {
</Alert>
</div>
)}

{featureFlags.enableAddWallets && wallets.length === 0 && this.renderAddNewWalletButton()}
</div>
);
};
Expand Down Expand Up @@ -101,7 +140,7 @@ export class AccountManagementPanel extends React.Component<Properties> {

renderAddEmailAccountModal = () => {
return (
<Modal
<ZuiModal
open={this.props.isAddEmailModalOpen}
onOpenChange={(isOpen) => {
isOpen ? this.props.onOpenAddEmailModal() : this.props.onCloseAddEmailModal();
Expand All @@ -121,6 +160,38 @@ export class AccountManagementPanel extends React.Component<Properties> {

<CreateEmailAccountContainer addAccount />
</div>
</ZuiModal>
);
};

renderLinkNewWalletModal = () => {
const onClose = () => {
this.setIsUserLinkingNewWallet(false);
};

return (
<Modal
title='Link Wallet'
primaryText='Link Wallet'
primaryVariant={Variant.Primary}
primaryColor={Color.Highlight}
secondaryText='Cancel'
secondaryVariant={Variant.Secondary}
secondaryColor={Color.Red}
onPrimary={() => {}}
onSecondary={onClose}
onClose={onClose}
isProcessing={false}
>
<div {...cn('link-new-wallet-modal')}>
You have a wallet connected by the address{' '}
<b>
<i>{this.props.connectedWallet}</i>
</b>
<br />
<br />
Do you want to link this wallet with your ZERO account?
</div>
</Modal>
);
};
Expand Down Expand Up @@ -152,6 +223,7 @@ export class AccountManagementPanel extends React.Component<Properties> {
</div>

{this.renderAddEmailAccountModal()}
{this.state.isUserLinkingNewWallet && this.props.isWalletConnected && this.renderLinkNewWalletModal()}
</div>
</ScrollbarContainer>
</div>
Expand Down
Loading

0 comments on commit cdd58b7

Please sign in to comment.