Skip to content

Commit

Permalink
Merge branch 'develop' into combined-prs
Browse files Browse the repository at this point in the history
  • Loading branch information
brusherru authored Jul 24, 2023
2 parents 25a4672 + 90a8061 commit 690de21
Show file tree
Hide file tree
Showing 35 changed files with 420 additions and 335 deletions.
11 changes: 6 additions & 5 deletions app/basicComponents/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, { useState, useCallback, useRef } from 'react';
import styled, { css, useTheme } from 'styled-components';
import { smColors } from '../vars';
import { useClickAway } from '../hooks/useClickAway';

const Wrapper = styled.div<{
isDisabled: boolean;
Expand Down Expand Up @@ -385,15 +386,14 @@ const DropDown = <T extends ADataItem>({
}: Props<T>) => {
const theme = useTheme();
const [isOpened, setIsOpened] = useState(_isOpened);
const awayContainerRef = useRef(null);

const closeDropdown = useCallback(() => {
setIsOpened(false);
onClose();
}, [onClose]);

useEffect(() => {
window.addEventListener('click', closeDropdown);
return () => window.removeEventListener('click', closeDropdown);
}, [closeDropdown]);
useClickAway(awayContainerRef, closeDropdown);

const isDisabledComputed = isDisabled || !data || !data.length;
const isLightTheme = dark === undefined ? !theme.isDarkMode : dark;
Expand Down Expand Up @@ -455,6 +455,7 @@ const DropDown = <T extends ADataItem>({
e.preventDefault();
e.stopPropagation();
}}
ref={awayContainerRef}
>
{!hideHeader && (
<HeaderWrapper
Expand Down
35 changes: 22 additions & 13 deletions app/basicComponents/ErrorPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import React from 'react';
import styled from 'styled-components';
import { closePopup } from '../assets/images';

const Wrapper = styled.div<{ onClick: (e?: React.MouseEvent) => void }>`
const Wrapper = styled.div<{
onClick: (e?: React.MouseEvent) => void;
messageType;
}>`
position: absolute;
display: flex;
flex-direction: row;
justify-content: center;
background-color: ${({
messageType,
theme: {
popups: {
states: { error },
},
popups: { states },
},
}) => error.backgroundColor};
}) => states[messageType].backgroundColor};
${({ theme }) => `border-radius: ${theme.box.radius}px;`}
`;

Expand All @@ -33,29 +35,36 @@ const CloseImg = styled.img.attrs((props) => ({
}) => iconRadius}px;
`;

const PopupText = styled.div`
const PopupText = styled.div<{
messageType;
}>`
margin: 10px 10px 10px 30px;
font-size: 10px;
line-height: 13px;
color: ${({
messageType,
theme: {
popups: {
states: { error },
},
popups: { states },
},
}) => error.color};
}) => states[messageType].color};
`;

type Props = {
onClick: () => void;
text: string;
style?: any;
messageType?: 'error' | 'warning' | 'infoTooltip' | 'success';
};

const ErrorPopup = ({ onClick, text, style = {} }: Props) => (
<Wrapper onClick={onClick} style={style}>
const ErrorPopup = ({
onClick,
text,
style = {},
messageType = 'error',
}: Props) => (
<Wrapper onClick={onClick} style={style} messageType={messageType}>
<CloseImg src={closePopup} />
<PopupText>{text}</PopupText>
<PopupText messageType={messageType}>{text}</PopupText>
</Wrapper>
);

Expand Down
104 changes: 89 additions & 15 deletions app/components/common/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useState } from 'react';
import styled, { css } from 'styled-components';
import styled, { css, keyframes } from 'styled-components';
import { v4 as uuidv4 } from 'uuid';
import { Button, Link } from '../../basicComponents';
import { Button, Link, Tooltip } from '../../basicComponents';
import { captureReactException, captureReactMessage } from '../../sentry';
import Loader from '../../basicComponents/Loader';
import { smColors } from '../../vars';
import { ExternalLinks } from '../../../shared/constants';
import CopyButton from '../../basicComponents/CopyButton';
import Modal from './Modal';
import BackButton from './BackButton';

Expand Down Expand Up @@ -153,13 +154,63 @@ const StyledTextArea = styled((props) => <textarea {...props} rows={10} />)`
border-radius: ${form.input.boxRadius}px;`};
`;

const fadeInOut = keyframes`
0% { opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% { opacity: 0; }
`;

const CopiedBanner = styled.div`
position: absolute;
z-index: 10;
line-height: 1.466;
color: ${smColors.darkerGreen};
animation: 3s ${fadeInOut} ease-out;
`;

const ErrorIdentifier = styled.div<{ isCopied: boolean }>`
align-self: center;
line-height: 1.466;
cursor: inherit;
white-space: nowrap;
span {
visibility: ${(props) => props.isCopied && 'hidden'};
}
`;

const IdentifierSection = styled.div`
display: flex;
justify-content: space-between;
margin: 10px 0;
align-items: center;
`;

const CopySection = styled.div`
display: flex;
border-radius: 10px;
padding: 10px;
background-color: ${smColors.black80Alpha2};
`;

const IssueDescriptionSection = styled.div`
display: flex;
align-items: center;
`;

interface FormFields {
name: string;
email: string;
description: string;
}

const sendReport = (name: string, email: string, comments: string) =>
const sendReport = (
name: string,
email: string,
comments: string,
uniqID: string
) =>
fetch(
`https://sentry.io/api/0/projects/${process.env.SENTRY_SLUG}/${process.env.SENTRY_PROJECT_SLUG}/user-feedback/`,
{
Expand All @@ -170,7 +221,7 @@ const sendReport = (name: string, email: string, comments: string) =>
},
body: JSON.stringify({
event_id: captureReactMessage(`
User has submitted an issue and asked to check it. id: ${uuidv4()}
User has submitted an issue and asked to check it. id: ${uniqID}
------------------------------------------------------------------
${name}
------------------------------------------------------------------
Expand Down Expand Up @@ -214,9 +265,10 @@ const REGULAR_EXP_FOR_EMAIL_CHECK = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]
const FeedbackButton = () => {
const [showReportDialog, setShowReportDialog] = useState(false);
const [
showReportDialogSuccessMessage,
setShowReportDialogSuccessMessage,
] = useState(false);
uniqIdentifierForSuccessDialog,
setUniqIdentifierForSuccessDialog,
] = useState('');
const [isCopied, setIsCopied] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState(false);
const [userData, setUserData] = useState<FormFields>({
name: '',
Expand Down Expand Up @@ -256,19 +308,20 @@ const FeedbackButton = () => {
const handleReport = () => {
if (validate()) {
setIsLoading(true);
sendReport(userData.name, userData.email, userData.description)
const uniqId = uuidv4();
sendReport(userData.name, userData.email, userData.description, uniqId)
.then(() => {
resetForm();
setIsLoading(false);
setShowReportDialog(false);
return setShowReportDialogSuccessMessage(true);
return setUniqIdentifierForSuccessDialog(uniqId);
})
.catch(captureReactException);
}
};

const handleCloseSuccessMessageModal = () => {
setShowReportDialogSuccessMessage(false);
setUniqIdentifierForSuccessDialog('');
};

const openDiscord = () => window.open(ExternalLinks.DiscordTapAccount);
Expand All @@ -284,17 +337,38 @@ const FeedbackButton = () => {

return (
<Container>
{showReportDialogSuccessMessage && (
{uniqIdentifierForSuccessDialog && (
<Modal header="The report was sent" indicatorColor={smColors.green}>
<SuccemssMessage>
Thanks for the report! Spacemesh team will investigate it and open
an issue on Github. They may ask you to provide some details via
email you have specified. You can join our community.
Thank you for the report! The Spacemesh team will investigate it.
They may ask you to provide more details via email you have
specified.
<br />
<br />
<IdentifierSection>
<IssueDescriptionSection>
Issue ID
<Tooltip
width={140}
text="You can copy and share it with the Spacemesh team."
/>
:
</IssueDescriptionSection>
<CopySection>
<ErrorIdentifier isCopied={isCopied}>
{isCopied && <CopiedBanner>Copied</CopiedBanner>}
<span>{uniqIdentifierForSuccessDialog}</span>
</ErrorIdentifier>
<CopyButton
onClick={(val) => setIsCopied(Boolean(val))}
value={uniqIdentifierForSuccessDialog}
/>
</CopySection>
</IdentifierSection>
<br />
<Link
onClick={openDiscord}
text="join discord channel"
text="Join Our Discord Community"
style={{ fontSize: 16, lineHeight: '22px' }}
/>
</SuccemssMessage>
Expand Down
20 changes: 13 additions & 7 deletions app/components/contacts/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,41 @@ export const validate = (
oldAddress?: string
): ValidateError | null => {
let filteredContacts = contacts;
const trimmedAddress = address.trim();

if (oldAddress) {
filteredContacts = contacts.filter(
(contact) => contact.address !== oldAddress
);
}
const trimmedNickname = nickname.trim();

const nicknameRegex = /^[a-zA-Z0-9_-]*$/;
if (!nicknameRegex.test(nickname) || !nickname) {
if (!nicknameRegex.test(trimmedNickname) || !trimmedNickname) {
return {
type: 'name',
message: `Nickname: ${nickname} is missing or invalid`,
message: `Nickname: ${trimmedNickname} is missing or invalid`,
};
}
if (
filteredContacts.some(
(contact) => contact.nickname.toLowerCase() === nickname.toLowerCase()
(contact) =>
contact.nickname.toLowerCase() === trimmedNickname.toLowerCase()
)
) {
return {
type: 'name',
message: `Nickname should be unique, ${nickname} already in contacts`,
message: `Nickname should be unique, ${trimmedNickname} already in contacts`,
};
}
if (!validateAddress(address)) {
return { type: 'address', message: `Address: ${address} is invalid` };
if (!validateAddress(trimmedAddress)) {
return {
type: 'address',
message: `Address: ${trimmedAddress} is invalid`,
};
}
const repeatedAddress = filteredContacts.find(
(contact) => contact.address === address
(contact) => contact.address === trimmedAddress
);
if (repeatedAddress) {
return {
Expand Down
15 changes: 14 additions & 1 deletion app/components/wallet/TxParams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ const TxParams = ({
}: Props) => {
const [selectedFeeIndex, setSelectedFeeIndex] = useState(0);
const fees = getFees(maxGas);
const [sameAddressError, setSameAddressError] = useState(false);

const selectFee = ({ index }: { index: number }) => {
updateFee({ fee: fees[index].fee });
setSelectedFeeIndex(index);
Expand Down Expand Up @@ -170,7 +172,10 @@ const TxParams = ({
placeholder="Address"
data={contacts || []}
value={address}
onChange={(value: string) => updateTxAddress({ value })}
onChange={(value: string) => {
setSameAddressError(fromAddress === value);
updateTxAddress({ value });
}}
onEnter={(value: string) => updateTxAddress({ value })}
autofocus
/>
Expand All @@ -181,6 +186,14 @@ const TxParams = ({
style={errorPopupStyle}
/>
)}
{sameAddressError && (
<ErrorPopup
onClick={() => setSameAddressError(false)}
text="The address of the sender and recipient is the same."
style={errorPopupStyle1}
messageType="warning"
/>
)}
</DetailsRow>
<DetailsRow>
<DetailsText>From</DetailsText>
Expand Down
17 changes: 17 additions & 0 deletions app/hooks/useClickAway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect } from 'react';

export const useClickAway = (ref, onClose: () => void) => {
useEffect(() => {
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
onClose();
}
}
// Bind the event listener
document.addEventListener('mousedown', handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener('mousedown', handleClickOutside);
};
}, [ref, onClose]);
};
8 changes: 6 additions & 2 deletions app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import 'json-bigint-patch';
import React from 'react';
import { render } from 'react-dom';
import ReactDom from 'react-dom/client';
import App from './App';

const logger = require('electron-log');

logger.transports.console.level = false;

render(<App />, document.getElementById('root'));
const root = ReactDom.createRoot(
document.getElementById('root') as HTMLElement
);

root.render(<App />);
Loading

0 comments on commit 690de21

Please sign in to comment.