diff --git a/src/features/ui/components/modal-root.tsx b/src/features/ui/components/modal-root.tsx index 7fec9c25c..2f000ef2d 100644 --- a/src/features/ui/components/modal-root.tsx +++ b/src/features/ui/components/modal-root.tsx @@ -30,6 +30,7 @@ import { MentionsModal, MissingDescriptionModal, MuteModal, + NostrLoginModal, NostrSigninModal, ReactionsModal, ReblogsModal, @@ -71,6 +72,7 @@ const MODAL_COMPONENTS: Record> = { 'MENTIONS': MentionsModal, 'MISSING_DESCRIPTION': MissingDescriptionModal, 'MUTE': MuteModal, + 'NOSTR_LOGIN': NostrLoginModal, 'NOSTR_SIGNIN': NostrSigninModal, 'REACTIONS': ReactionsModal, 'REBLOGS': ReblogsModal, diff --git a/src/features/ui/components/modals/nostr-login-modal/components/emoji-graphic.tsx b/src/features/ui/components/modals/nostr-login-modal/components/emoji-graphic.tsx new file mode 100644 index 000000000..541920307 --- /dev/null +++ b/src/features/ui/components/modals/nostr-login-modal/components/emoji-graphic.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +import Emoji from 'soapbox/components/ui/emoji/emoji'; + +interface IEmojiGraphic { + emoji: string; +} + +/** Large emoji with a background for display purposes (eg breaking up a page). */ +const EmojiGraphic: React.FC = ({ emoji }) => { + return ( +
+
+ +
+
+ ); +}; + +export default EmojiGraphic; \ No newline at end of file diff --git a/src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx b/src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx new file mode 100644 index 000000000..78dddd33d --- /dev/null +++ b/src/features/ui/components/modals/nostr-login-modal/components/nostr-extension-indicator.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +import { closeModal } from 'soapbox/actions/modals'; +import { nostrExtensionLogIn } from 'soapbox/actions/nostr'; +import Stack from 'soapbox/components/ui/stack/stack'; +import Text from 'soapbox/components/ui/text/text'; +import { useAppDispatch } from 'soapbox/hooks'; + +const NostrExtensionIndicator: React.FC = () => { + const dispatch = useAppDispatch(); + + const onClick = () => { + dispatch(nostrExtensionLogIn()); + dispatch(closeModal('NOSTR_SIGNIN')); + }; + + return ( + + + {window.nostr ? ( + , + }} + /> + ) : ( + + )} + + + ); +}; + +export default NostrExtensionIndicator; \ No newline at end of file diff --git a/src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx b/src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx new file mode 100644 index 000000000..d3aae0a8a --- /dev/null +++ b/src/features/ui/components/modals/nostr-login-modal/nostr-login-modal.tsx @@ -0,0 +1,29 @@ +import React, { useState } from 'react'; + +import ExtensionStep from './steps/extension-step'; +import KeyAddStep from './steps/key-add-step'; + +type Step = 'extension' | 'key-add'; + +interface INostrLoginModal { + onClose: (type?: string) => void; +} + +const NostrLoginModal: React.FC = ({ onClose }) => { + const [step, setStep] = useState(window.nostr ? 'extension' : 'key-add'); + + const handleClose = () => onClose('NOSTR_SIGNIN'); + + switch (step) { + case 'extension': + return ; + case 'key-add': + return ; + default: + return null; + } +}; + +export default NostrLoginModal; + +export type { Step }; diff --git a/src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx b/src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx new file mode 100644 index 000000000..e155ab06b --- /dev/null +++ b/src/features/ui/components/modals/nostr-login-modal/steps/extension-step.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +import { nostrExtensionLogIn } from 'soapbox/actions/nostr'; +import { Button, Stack, Modal } from 'soapbox/components/ui'; +import { useAppDispatch } from 'soapbox/hooks'; + +import EmojiGraphic from '../components/emoji-graphic'; +import { Step } from '../nostr-login-modal'; + +interface IExtensionStep { + setStep: (step: Step) => void; + onClose(): void; +} + +const ExtensionStep: React.FC = ({ setStep, onClose }) => { + const dispatch = useAppDispatch(); + + const onClick = () => { + dispatch(nostrExtensionLogIn()); + onClose(); + }; + + const onClickAlt = () => setStep('key-add'); + + return ( + } onClose={onClose}> + + + + + + + + + + + ); +}; + +export default ExtensionStep; diff --git a/src/features/ui/components/modals/nostr-signin-modal/steps/key-add-step.tsx b/src/features/ui/components/modals/nostr-login-modal/steps/key-add-step.tsx similarity index 100% rename from src/features/ui/components/modals/nostr-signin-modal/steps/key-add-step.tsx rename to src/features/ui/components/modals/nostr-login-modal/steps/key-add-step.tsx diff --git a/src/features/ui/components/modals/nostr-signin-modal/nostr-signin-modal.tsx b/src/features/ui/components/modals/nostr-signin-modal/nostr-signin-modal.tsx index 9188796ba..6865e56ec 100644 --- a/src/features/ui/components/modals/nostr-signin-modal/nostr-signin-modal.tsx +++ b/src/features/ui/components/modals/nostr-signin-modal/nostr-signin-modal.tsx @@ -1,11 +1,10 @@ import React, { useState } from 'react'; import ExtensionStep from './steps/extension-step'; -import KeyAddStep from './steps/key-add-step'; import KeyStep from './steps/key-step'; import KeygenStep from './steps/keygen-step'; -type Step = 'extension' | 'key' | 'keygen' | 'key-add'; +type Step = 'extension' | 'key' | 'keygen'; interface INostrSigninModal { onClose: (type?: string) => void; @@ -21,8 +20,6 @@ const NostrSigninModal: React.FC = ({ onClose }) => { return ; case 'key': return ; - case 'key-add': - return ; case 'keygen': return ; default: diff --git a/src/features/ui/components/modals/nostr-signin-modal/steps/key-step.tsx b/src/features/ui/components/modals/nostr-signin-modal/steps/key-step.tsx index fef9bd9b1..73a71e501 100644 --- a/src/features/ui/components/modals/nostr-signin-modal/steps/key-step.tsx +++ b/src/features/ui/components/modals/nostr-signin-modal/steps/key-step.tsx @@ -1,7 +1,9 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; +import { openModal } from 'soapbox/actions/modals'; import { Button, Stack, Modal } from 'soapbox/components/ui'; +import { useAppDispatch } from 'soapbox/hooks'; import EmojiGraphic from '../components/emoji-graphic'; import NostrExtensionIndicator from '../components/nostr-extension-indicator'; @@ -13,6 +15,13 @@ interface IKeyStep { } const KeyStep: React.FC = ({ setStep, onClose }) => { + const dispatch = useAppDispatch(); + + const onAltClick = () => { + dispatch(openModal('NOSTR_LOGIN')); + onClose(); + }; + return ( } onClose={onClose}> @@ -25,7 +34,7 @@ const KeyStep: React.FC = ({ setStep, onClose }) => { Generate key - diff --git a/src/features/ui/components/navbar.tsx b/src/features/ui/components/navbar.tsx index 81245a214..0be4e3948 100644 --- a/src/features/ui/components/navbar.tsx +++ b/src/features/ui/components/navbar.tsx @@ -40,7 +40,7 @@ const Navbar = () => { const onOpenSidebar = () => dispatch(openSidebar()); const handleNostrLogin = async () => { - dispatch(openModal('NOSTR_SIGNIN')); + dispatch(openModal('NOSTR_LOGIN')); }; const handleSubmit: React.FormEventHandler = (event) => { diff --git a/src/features/ui/util/async-components.ts b/src/features/ui/util/async-components.ts index d1313e0af..26e86a1ce 100644 --- a/src/features/ui/util/async-components.ts +++ b/src/features/ui/util/async-components.ts @@ -163,3 +163,4 @@ export const FollowedTags = lazy(() => import('soapbox/features/followed-tags')) export const AccountNotePanel = lazy(() => import('soapbox/features/ui/components/panels/account-note-panel')); export const ComposeEditor = lazy(() => import('soapbox/features/compose/editor')); export const NostrSigninModal = lazy(() => import('soapbox/features/ui/components/modals/nostr-signin-modal/nostr-signin-modal')); +export const NostrLoginModal = lazy(() => import('soapbox/features/ui/components/modals/nostr-login-modal/nostr-login-modal'));