feat: export keys & new settings page

This commit is contained in:
2023-04-21 21:55:04 +01:00
parent e6daf6536e
commit 45ca273064
9 changed files with 152 additions and 47 deletions

View File

@ -8,6 +8,7 @@ import RelayInfo from "Pages/settings/RelayInfo";
import AccountsPage from "Pages/settings/Accounts";
import { WalletSettingsRoutes } from "Pages/settings/WalletSettings";
import { ManageHandleRoutes } from "Pages/settings/handle";
import ExportKeys from "Pages/settings/Keys";
import messages from "./messages";
@ -49,6 +50,10 @@ export const SettingsRoutes: RouteObject[] = [
path: "accounts",
element: <AccountsPage />,
},
{
path: "keys",
element: <ExportKeys />,
},
...ManageHandleRoutes,
...WalletSettingsRoutes,
];

View File

@ -12,7 +12,12 @@ import messages from "./messages";
const WhatIsSnort = () => {
return (
<CollapsedSection title={<FormattedMessage {...messages.WhatIsSnort} />}>
<CollapsedSection
title={
<h3>
<FormattedMessage {...messages.WhatIsSnort} />
</h3>
}>
<p>
<FormattedMessage {...messages.WhatIsSnortIntro} />
</p>
@ -28,7 +33,12 @@ const WhatIsSnort = () => {
const HowDoKeysWork = () => {
return (
<CollapsedSection title={<FormattedMessage {...messages.HowKeysWork} />}>
<CollapsedSection
title={
<h3>
<FormattedMessage {...messages.HowKeysWork} />
</h3>
}>
<p>
<FormattedMessage {...messages.DigitalSignatures} />
</p>
@ -44,7 +54,12 @@ const HowDoKeysWork = () => {
const Extensions = () => {
return (
<CollapsedSection title={<FormattedMessage {...messages.ImproveSecurity} />}>
<CollapsedSection
title={
<h3>
<FormattedMessage {...messages.ImproveSecurity} />
</h3>
}>
<p>
<FormattedMessage {...messages.Extensions} />
</p>

View File

@ -13,16 +13,30 @@
border-radius: 10px;
cursor: pointer;
gap: 10px;
margin-bottom: 5px;
}
.settings-row:hover {
.settings-row.inner {
padding: 0.8em 0;
background-color: unset;
border-radius: unset;
margin: 0;
}
.settings-group-header {
font-weight: 600;
font-size: 16px;
padding: 0.8em 1em;
background-color: var(--note-bg);
border-radius: 10px;
margin-bottom: 5px;
}
.settings-row:hover,
.settings-group-header:hover {
color: var(--highlight);
}
.settings-row + .settings-row {
margin-top: 10px;
}
.align-end {
margin-left: auto;
}
@ -31,3 +45,7 @@
width: 100%;
height: 100%;
}
.settings-group-header .collapse-icon > svg {
width: 8px;
}

View File

@ -6,6 +6,7 @@ import { LoginStore, logout } from "Login";
import useLogin from "Hooks/useLogin";
import { unwrap } from "Util";
import { getCurrentSubscription } from "Subscription";
import { CollapsedSection } from "Element/Collapsed";
import messages from "./messages";
@ -22,21 +23,56 @@ const SettingsIndex = () => {
return (
<>
<div className="settings-nav">
<div className="settings-row" onClick={() => navigate("profile")}>
<Icon name="profile" />
<FormattedMessage {...messages.Profile} />
<Icon name="arrowFront" />
</div>
<div className="settings-row" onClick={() => navigate("relays")}>
<Icon name="relay" />
<FormattedMessage {...messages.Relays} />
<Icon name="arrowFront" />
</div>
<CollapsedSection
title={
<div className="flex">
<Icon name="user" className="mr10" />
<FormattedMessage defaultMessage="Account" />
</div>
}
className="settings-group-header">
<div className="card">
<div className="settings-row inner" onClick={() => navigate("profile")}>
<Icon name="profile" />
<FormattedMessage {...messages.Profile} />
<Icon name="arrowFront" />
</div>
<div className="settings-row inner" onClick={() => navigate("relays")}>
<Icon name="relay" />
<FormattedMessage {...messages.Relays} />
<Icon name="arrowFront" />
</div>
<div className="settings-row inner" onClick={() => navigate("keys")}>
<Icon name="key" />
<FormattedMessage defaultMessage="Export Keys" />
<Icon name="arrowFront" />
</div>
<div className="settings-row inner" onClick={() => navigate("handle")}>
<Icon name="badge" />
<FormattedMessage defaultMessage="Nostr Adddress" />
<Icon name="arrowFront" />
</div>
<div className="settings-row inner" onClick={() => navigate("/subscribe/manage")}>
<Icon name="diamond" />
<FormattedMessage defaultMessage="Subscription" />
<Icon name="arrowFront" />
</div>
{sub && (
<div className="settings-row inner" onClick={() => navigate("accounts")}>
<Icon name="code-circle" />
<FormattedMessage defaultMessage="Account Switcher" />
<Icon name="arrowFront" />
</div>
)}
</div>
</CollapsedSection>
<div className="settings-row" onClick={() => navigate("preferences")}>
<Icon name="gear" />
<FormattedMessage {...messages.Preferences} />
<Icon name="arrowFront" />
</div>
<div className="settings-row" onClick={() => navigate("wallet")}>
<Icon name="wallet" />
<FormattedMessage defaultMessage="Wallet" />
@ -47,23 +83,7 @@ const SettingsIndex = () => {
<FormattedMessage {...messages.Donate} />
<Icon name="arrowFront" />
</div>
<div className="settings-row" onClick={() => navigate("handle")}>
<Icon name="badge" />
<FormattedMessage defaultMessage="Snort Nostr Adddress" />
<Icon name="arrowFront" />
</div>
<div className="settings-row" onClick={() => navigate("/subscribe/manage")}>
<Icon name="diamond" />
<FormattedMessage defaultMessage="Snort Subscription" />
<Icon name="arrowFront" />
</div>
{sub && (
<div className="settings-row" onClick={() => navigate("accounts")}>
<Icon name="code-circle" />
<FormattedMessage defaultMessage="Accounts" />
<Icon name="arrowFront" />
</div>
)}
<div className="settings-row" onClick={handleLogout}>
<Icon name="logout" />
<FormattedMessage {...messages.LogOut} />

View File

@ -0,0 +1,5 @@
.export-keys > .copy {
padding: 12px 16px;
border: 2px dashed #222222;
border-radius: 16px;
}

View File

@ -0,0 +1,37 @@
import "./Keys.css";
import { FormattedMessage } from "react-intl";
import { encodeTLV, NostrPrefix } from "@snort/nostr";
import Copy from "Element/Copy";
import useLogin from "Hooks/useLogin";
import { hexToMnemonic } from "nip6";
import { hexToBech32 } from "Util";
export default function ExportKeys() {
const { publicKey, privateKey, generatedEntropy } = useLogin();
return (
<div className="export-keys">
<h3>
<FormattedMessage defaultMessage="Public Key" />
</h3>
<Copy text={hexToBech32("npub", publicKey ?? "")} maxSize={48} className="mb10" />
<Copy text={encodeTLV(publicKey ?? "", NostrPrefix.Profile)} maxSize={48} />
{privateKey && (
<>
<h3>
<FormattedMessage defaultMessage="Private Key" />
</h3>
<Copy text={hexToBech32("nsec", privateKey)} maxSize={48} />
</>
)}
{generatedEntropy && (
<>
<h3>
<FormattedMessage defaultMessage="Mnemonic" />
</h3>
<Copy text={hexToMnemonic(generatedEntropy ?? "")} maxSize={48} />
</>
)}
</div>
);
}