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

TW-1544 Networks management #1202

Merged
merged 53 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
130b27a
TW-1555 Update some design and fix some bugs
keshan3262 Sep 13, 2024
b2dad24
TW-1555 Make some modals close after their backdrop is clicked
keshan3262 Sep 13, 2024
1414857
TW-1542 Resolve merge conflicts
keshan3262 Sep 13, 2024
6b250f3
TW-1542 Revert harmful changes
keshan3262 Sep 13, 2024
6dbdca1
TW-1542 Remove unused components
keshan3262 Sep 13, 2024
982e447
TW-1542 Implement new Settings menu design
keshan3262 Sep 13, 2024
4fb9a56
TW-1542 Remove some unused translations
keshan3262 Sep 13, 2024
6fcb3d7
TW-1542 Fix find-deadcode errors
keshan3262 Sep 13, 2024
f18b05d
TW-1542 Add changes from comments
keshan3262 Sep 16, 2024
f97bee1
TW-1543 Redesign 'General' settings section
keshan3262 Sep 16, 2024
3bbbc88
TW-1543 Refactoring
keshan3262 Sep 17, 2024
25b2037
TW-1542 Move localStorage clearing to frontend
keshan3262 Sep 17, 2024
03342d6
TW-1542 Update a label
keshan3262 Sep 17, 2024
9cdeb5c
TW-1555 Some more bugfixes
keshan3262 Sep 17, 2024
de837fa
Merge branch 'TW-1555-final-epic-testing' of https://github.com/madfi…
keshan3262 Sep 17, 2024
cf85bbd
Merge branch 'TW-1542-apply-design-for-settings-page' of https://gith…
keshan3262 Sep 17, 2024
74041ca
TW-1543 Change error output
keshan3262 Sep 17, 2024
93bd61d
TW-1543 Apply design updates
keshan3262 Sep 17, 2024
06f82f7
TW-1555 Remove some commented out code
keshan3262 Sep 17, 2024
ba0dc8a
TW-1543 Remove excessive locales loading checks
keshan3262 Sep 17, 2024
4dee114
TW-1555 Refactor setting classes
keshan3262 Sep 18, 2024
1feeace
TW-1555 Fix prettier problem
keshan3262 Sep 18, 2024
b3df9cc
TW-1555 Agree styles for app content wrapper and action modals
keshan3262 Sep 18, 2024
375d0c9
TW-1543 Bugfixes according to the comment from Figma
keshan3262 Sep 18, 2024
c885837
Merge branch 'TW-1555-final-epic-testing' of https://github.com/madfi…
keshan3262 Sep 18, 2024
f448902
TW-1542 Change a label
keshan3262 Sep 18, 2024
6aa1703
TW-1542 Fix font size for page header
keshan3262 Sep 18, 2024
9fcfbb8
Merge branch 'TW-1542-apply-design-for-settings-page' of https://gith…
keshan3262 Sep 18, 2024
438ab67
TW-1543 Remove an unused import
keshan3262 Sep 18, 2024
58f3ece
TW-1544 Implement RPCs and block explorers management (raw version)
keshan3262 Sep 20, 2024
3b02db6
TW-1544 Fix some bugs
keshan3262 Sep 23, 2024
9bb455e
TW-1542: Apply design for settings menu (#1199)
keshan3262 Sep 24, 2024
b1a95a9
TW-1543: 'General' section update (#1200)
keshan3262 Sep 24, 2024
625167f
TW-1544 Implement whole networks management
keshan3262 Sep 25, 2024
ce71784
TW-1544 Resolve merge conflicts
keshan3262 Sep 25, 2024
9a1ffa7
TW-1544 Some bugfixes
keshan3262 Sep 25, 2024
ff03850
TW-1544 Some bugfixes
keshan3262 Sep 26, 2024
48b25c5
TW-1544 Additional refactoring
keshan3262 Sep 26, 2024
c3d4c3b
TW-1544 Major refactoring
keshan3262 Sep 30, 2024
db0eb51
TW-1544 Refactoring according to comments
keshan3262 Oct 1, 2024
3172936
TW-1544 Fix a linting error
keshan3262 Oct 1, 2024
0b0585a
TW-1544 Additional refactoring according to comments
keshan3262 Oct 1, 2024
1e6bf34
TW-1548: Redesign 'Advanced Features' section (#1205)
keshan3262 Oct 7, 2024
e5db334
Merge branch 'TW-1541-epic-evm-settings' of https://github.com/madfis…
keshan3262 Oct 9, 2024
ce6d43e
Fix some bugs from comments in Jira
keshan3262 Oct 10, 2024
8e00f6c
TW-1544 Fix rest of bugs from comments in Jira
keshan3262 Oct 11, 2024
7ddbba2
TW-1544 Implmenent reserving space for an error below FormField
keshan3262 Oct 11, 2024
3239ec4
TW-1544 Resolve merge conflicts
keshan3262 Oct 11, 2024
1b145b7
TW-1544 Remove an unused import
keshan3262 Oct 14, 2024
7e1ef85
Merge branch 'development-2' of https://github.com/madfish-solutions/…
keshan3262 Oct 24, 2024
5ebde31
TW-1544 Prevent disabling main Tezos and EVM networks
keshan3262 Oct 24, 2024
71849a3
TW-1544 Minor refactoring
keshan3262 Oct 25, 2024
3c68cd2
TW-1544 Resolve merge conflicts
keshan3262 Oct 28, 2024
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
Prev Previous commit
Next Next commit
TW-1542 Revert harmful changes
  • Loading branch information
keshan3262 committed Sep 13, 2024
commit 6b250f33e632e44ab8b8e67b12b59e9aede78622
2 changes: 2 additions & 0 deletions e2e/src/page-objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { InternalConfirmationPage } from './pages/internal-confirmation.page';
import { ManualBackupModalPage } from './pages/modal/manual-backup-modal.page';
import { NewsletterModalPage } from './pages/modal/newsletter-modal.page';
import { OnRumModalPage } from './pages/modal/on-rum-modal.page';
import { RevealSecretsPage } from './pages/reveal-secrets.page';
import { SendPage } from './pages/send.page';
import { SettingsPage } from './pages/settings.page';
import { setWalletPage } from './pages/setWalletPassword.page';
Expand All @@ -29,6 +30,7 @@ export const Pages = {
ImportExistingWallet: new ImportExistingWalletPage(),
SetWallet: new setWalletPage(),
Settings: new SettingsPage(),
RevealSecrets: new RevealSecretsPage(),
UnlockScreen: new UnlockScreenPage(),
DelegateTab: new DelegateTab(),
DelegateForm: new DelegateFormPage(),
Expand Down
16 changes: 16 additions & 0 deletions e2e/src/page-objects/pages/reveal-secrets.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { RevealSecretsSelectors } from 'src/app/templates/RevealSecrets/RevealSecrets.selectors';

import { Page } from '../../classes/page.class';
import { createPageElement } from '../../utils/search.utils';

export class RevealSecretsPage extends Page {
revealButton = createPageElement(RevealSecretsSelectors.RevealButton);
revealPasswordField = createPageElement(RevealSecretsSelectors.RevealPasswordInput);
revealSecretsProtectedMask = createPageElement(RevealSecretsSelectors.RevealSecretsProtectedMask);
revealSecretsValue = createPageElement(RevealSecretsSelectors.RevealSecretsValue);

async isVisible() {
await this.revealButton.waitForDisplayed();
await this.revealPasswordField.waitForDisplayed();
}
}
32 changes: 32 additions & 0 deletions src/app/templates/HelpAndCommunity/ResourceLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { FC, SVGProps } from 'react';

import { Anchor } from 'app/atoms/Anchor';
import { TestIDProps } from 'lib/analytics';

interface Props extends TestIDProps {
title: string;
href: string;
background?: string;
Icon: React.FC<SVGProps<SVGSVGElement>>;
}

export const ResourceLink: FC<Props> = ({ title, href, background, Icon, testID, testIDProperties }) => {
return (
<li>
<Anchor
href={href}
className="flex items-center py-1 my-1 hover:underline text-blue-600"
testID={testID}
testIDProperties={testIDProperties}
>
<div
className="mr-4 w-8 h-8 flex justify-center items-center rounded-md"
style={{ background, padding: background ? '0.375rem' : 0 }}
>
<Icon className="h-full w-auto" />
</div>
{title}
</Anchor>
</li>
);
};
99 changes: 99 additions & 0 deletions src/app/templates/HelpAndCommunity/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { FC, useMemo } from 'react';

import { ReactComponent as CannyIcon } from 'app/icons/canny.svg';
import { ReactComponent as DiscordIcon } from 'app/icons/discord.svg';
import { ReactComponent as HelpCrunchIcon } from 'app/icons/helpcrunch.svg';
import { ReactComponent as RedditIcon } from 'app/icons/reddit.svg';
import { ReactComponent as TelegramIcon } from 'app/icons/telegram.svg';
import { ReactComponent as TwitterIcon } from 'app/icons/twitter.svg';
import { ReactComponent as YoutubeIcon } from 'app/icons/youtube.svg';
import { T } from 'lib/i18n';

import { ResourceLink } from './ResourceLink';
import { HelpAndCommunitySelectors } from './selectors';

const HelpAndCommunity: FC = () => {
const generalLinks = useMemo(
() => [
{
title: 'Knowledge Base',
href: 'https://madfish.crunch.help/temple-wallet',
background: '#2182f7',
Icon: HelpCrunchIcon,
testID: HelpAndCommunitySelectors.knowledgeBaseLinkButton
},
{
title: 'Feature Request',
href: 'https://madfish.canny.io/feature-requests',
Icon: CannyIcon,
testID: HelpAndCommunitySelectors.featureRequestLinkButton
}
],
[]
);

const socialMediaLinks = useMemo(
() => [
{
title: 'Twitter',
href: 'https://twitter.com/madfishofficial',
background: '#1DA1F2',
Icon: TwitterIcon
},
{
title: 'Telegram',
href: 'https://t.me/MadFishCommunity',
background: '#26A5E4',
Icon: TelegramIcon
},
{
title: 'Discord',
href: 'https://www.madfish.solutions/discord',
background: '#7289DA',
Icon: DiscordIcon
},
{
title: 'Reddit',
href: 'https://www.reddit.com/r/MadFishCommunity',
background: '#FF4500',
Icon: RedditIcon
},
{
title: 'Youtube',
href: 'https://www.youtube.com/channel/UCUp80EXfJEigks3xU5hiwyA',
background: '#FF0000',
Icon: YoutubeIcon
}
],
[]
);

return (
<div className="w-full max-w-sm mx-auto my-8 text-sm text-gray-700">
<p>
<T id="communityResourcesTitle" />
</p>

<ul className="my-2">
{generalLinks.map(({ title, ...props }) => (
<ResourceLink key={title} title={title} {...props} />
))}
{socialMediaLinks.map(({ title, ...props }) => (
<ResourceLink
key={title}
title={title}
{...props}
testID={HelpAndCommunitySelectors.socialMediaLinkButton}
testIDProperties={{ media: title }}
/>
))}
</ul>

<p>
<T id="joinPrompt" />
</p>
</div>
);
};

export default HelpAndCommunity;
5 changes: 5 additions & 0 deletions src/app/templates/HelpAndCommunity/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum HelpAndCommunitySelectors {
knowledgeBaseLinkButton = 'Help & Community/Knowledge Base Link Button',
featureRequestLinkButton = 'Help & Community/Feature Request Link Button',
socialMediaLinkButton = 'Help & Community/Social Media Link Button'
}
72 changes: 72 additions & 0 deletions src/app/templates/RevealSecrets/PasswordForRevealField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { memo, useRef, useCallback, useLayoutEffect } from 'react';

import { OnSubmit, useForm } from 'react-hook-form';

import { FormField, FormSubmitButton } from 'app/atoms';
import { TID, T, t } from 'lib/i18n';

import { RevealSecretsSelectors } from './RevealSecrets.selectors';

interface Props {
labelDescriptionForName: TID;
onSubmit: (password: string) => Promise<void>;
}

const SUBMIT_ERROR_TYPE = 'submit-error';

interface FormData {
password: string;
}

export const PasswordForRevealField = memo<Props>(({ labelDescriptionForName, onSubmit }) => {
const { register, handleSubmit, errors, setError, clearError, formState } = useForm<FormData>();
const submitting = formState.isSubmitting;

const formRef = useRef<HTMLFormElement>(null);

const focusPasswordField = useCallback(() => {
formRef.current?.querySelector<HTMLInputElement>("input[name='password']")?.focus();
}, []);

useLayoutEffect(() => {
focusPasswordField();
}, [focusPasswordField]);

const onSubmitLocal = useCallback<OnSubmit<FormData>>(
({ password }) => {
if (submitting) return;

clearError('password');

onSubmit(password).catch(err => {
console.error(err);

setError('password', SUBMIT_ERROR_TYPE, err.message);
focusPasswordField();
});
},
[onSubmit, submitting, clearError, setError, focusPasswordField]
);

return (
<form ref={formRef} onSubmit={handleSubmit(onSubmitLocal)}>
<FormField
ref={register({ required: t('required') })}
label={t('password')}
labelDescription={t('revealSecretPasswordInputDescription', t(labelDescriptionForName))}
id="reveal-secret-password"
type="password"
name="password"
placeholder="********"
errorCaption={errors.password?.message}
containerClassName="mb-4"
onChange={() => clearError()}
testID={RevealSecretsSelectors.RevealPasswordInput}
/>

<FormSubmitButton loading={submitting} testID={RevealSecretsSelectors.RevealButton}>
<T id="reveal" />
</FormSubmitButton>
</form>
);
});
120 changes: 120 additions & 0 deletions src/app/templates/RevealSecrets/RevealPrivateKeys.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React, { FC, memo, useCallback, useMemo } from 'react';

import clsx from 'clsx';

import { Alert } from 'app/atoms';
import { getAccountBadgeTitle } from 'app/defaults';
import AccountBanner from 'app/templates/AccountBanner';
import { T, t } from 'lib/i18n';
import { useTempleClient } from 'lib/temple/front';
import { TempleAccountType } from 'lib/temple/types';
import { useDidUpdate, useVanishingState } from 'lib/ui/hooks';
import { AccountForChain } from 'temple/accounts';
import { useAccountForEvm, useAccountForTezos } from 'temple/front';
import { TempleChainTitle } from 'temple/types';

import { PasswordForRevealField } from './PasswordForRevealField';
import { SecretField } from './SecretField';

export const RevealPrivateKeys = memo(() => {
const accForTezos = useAccountForTezos();
const accForEvm = useAccountForEvm();

return (
<>
{accForTezos ? <RevealForChain account={accForTezos} /> : null}
{accForEvm ? <RevealForChain account={accForEvm} /> : null}
</>
);
});

interface RevealForChainProps {
account: AccountForChain;
}

const RevealForChain: FC<RevealForChainProps> = ({ account }) => {
const { chain, address } = account;

const { revealPrivateKey } = useTempleClient();

const [secret, setSecret] = useVanishingState();

// eslint-disable-next-line react-hooks/exhaustive-deps
useDidUpdate(() => void setSecret(null), [account.id, setSecret]);

const onPasswordSubmit = useCallback(
async (password: string) => revealPrivateKey(address, password).then(scrt => void setSecret(scrt)),
[address, setSecret, revealPrivateKey]
);

const mainContent = useMemo(() => {
const forbidRevealing = [
TempleAccountType.Ledger,
TempleAccountType.ManagedKT,
TempleAccountType.WatchOnly
].includes(account.type);

if (forbidRevealing) {
return (
<Alert
title={t('privateKeyCannotBeRevealed')}
description={
<p>
<T
id="youCannotGetPrivateKeyFromThisAccountType"
substitutions={[
<span
key="account-type"
className="rounded-sm border px-1 py-px font-normal leading-tight border-current"
style={{
fontSize: '0.75em'
}}
>
{getAccountBadgeTitle(account.type)}
</span>
]}
/>
</p>
}
className="my-4"
/>
);
}

if (secret) return <SecretField value={secret} revealType="private-key" />;

return <PasswordForRevealField labelDescriptionForName="privateKey" onSubmit={onPasswordSubmit} />;
}, [account.type, secret, onPasswordSubmit]);

return (
<div className="mt-6 w-full max-w-sm p-2 mx-auto">
<AccountBanner
account={account}
label={`${TempleChainTitle[chain]} Account`}
labelDescription={t('ifYouWantToRevealPrivateKeyFromOtherAccount')}
className="mb-6"
/>

{account.derivationPath && (
<div className="mb-6 flex flex-col">
<label className="mb-4 flex flex-col">
<span className="text-base font-semibold text-gray-700">
<T id="derivationPath" />
</span>
</label>
<input
className={clsx(
'appearance-none w-full py-3 pl-4',
'rounded-md border-2 border-gray-300',
'bg-transparent text-gray-700 text-lg leading-tight'
)}
disabled={true}
value={account.derivationPath}
/>
</div>
)}

{mainContent}
</div>
);
};
6 changes: 6 additions & 0 deletions src/app/templates/RevealSecrets/RevealSecrets.selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum RevealSecretsSelectors {
RevealButton = 'Reveal Secrets/Reveal Button',
RevealPasswordInput = 'Reveal Secrets/Reveal Password Input',
RevealSecretsProtectedMask = 'Reveal Secrets/Reveal Secrets Protected Mask',
RevealSecretsValue = 'Reveal Secrets/Reveal Secrets Value'
}
Loading