diff --git a/packages/app/public/icons.svg b/packages/app/public/icons.svg index f40715f4..27b9b9d1 100644 --- a/packages/app/public/icons.svg +++ b/packages/app/public/icons.svg @@ -145,5 +145,12 @@ + + + + + + + \ No newline at end of file diff --git a/packages/app/src/Element/Avatar.css b/packages/app/src/Element/Avatar.css index 18305b12..178f52d4 100644 --- a/packages/app/src/Element/Avatar.css +++ b/packages/app/src/Element/Avatar.css @@ -8,6 +8,7 @@ background-clip: content-box, border-box; background-size: cover; box-sizing: border-box; + background-color: var(--gray); } .avatar[data-domain="snort.social"] { diff --git a/packages/app/src/Element/AvatarEditor.tsx b/packages/app/src/Element/AvatarEditor.tsx new file mode 100644 index 00000000..690fc189 --- /dev/null +++ b/packages/app/src/Element/AvatarEditor.tsx @@ -0,0 +1,49 @@ +import Icon from "Icons/Icon"; +import { useState } from "react"; +import useFileUpload from "Upload"; +import { openFile, unwrap } from "Util"; + +interface AvatarEditorProps { + picture?: string; + onPictureChange?: (newPicture: string) => void; +} + +export default function AvatarEditor({ picture, onPictureChange }: AvatarEditorProps) { + const uploader = useFileUpload(); + const [error, setError] = useState(""); + + async function uploadFile() { + setError(""); + try { + const f = await openFile(); + if (f) { + const rsp = await uploader.upload(f, f.name); + console.log(rsp); + if (typeof rsp?.error === "string") { + setError(`Upload failed: ${rsp.error}`); + } else { + onPictureChange?.(unwrap(rsp.url)); + } + } + } catch (e) { + if (e instanceof Error) { + setError(`Upload failed: ${e.message}`); + } else { + setError(`Upload failed`); + } + } + } + + return ( + <> +
+
+
uploadFile().catch(console.error)}> + +
+
+
+ {error && {error}} + + ); +} diff --git a/packages/app/src/Element/FollowListBase.tsx b/packages/app/src/Element/FollowListBase.tsx index c072bfcf..8465f83d 100644 --- a/packages/app/src/Element/FollowListBase.tsx +++ b/packages/app/src/Element/FollowListBase.tsx @@ -1,12 +1,12 @@ import { ReactNode } from "react"; import { FormattedMessage } from "react-intl"; +import { HexKey } from "@snort/nostr"; import useEventPublisher from "Feed/EventPublisher"; -import { HexKey } from "@snort/nostr"; import ProfilePreview from "Element/ProfilePreview"; +import useLogin from "Hooks/useLogin"; import messages from "./messages"; -import useLogin from "Hooks/useLogin"; export interface FollowListBaseProps { pubkeys: HexKey[]; @@ -26,7 +26,7 @@ export default function FollowListBase({ pubkeys, title, showFollowAll, showAbou } return ( -
+ <> {(showFollowAll ?? true) && (
{title}
@@ -38,6 +38,6 @@ export default function FollowListBase({ pubkeys, title, showFollowAll, showAbou {pubkeys?.map(a => ( ))} -
+ ); } diff --git a/packages/app/src/Element/Hashtag.css b/packages/app/src/Element/Hashtag.css index 52232cc2..ad81ad4d 100644 --- a/packages/app/src/Element/Hashtag.css +++ b/packages/app/src/Element/Hashtag.css @@ -1,3 +1,7 @@ .hashtag { color: var(--highlight); } + +.hashtag > a { + text-decoration: none; +} diff --git a/packages/app/src/Element/LinkPreview.css b/packages/app/src/Element/LinkPreview.css index ab4d37a7..d7ab0e69 100644 --- a/packages/app/src/Element/LinkPreview.css +++ b/packages/app/src/Element/LinkPreview.css @@ -8,6 +8,10 @@ cursor: pointer; } +.link-preview-container > a { + text-decoration: none; +} + .link-preview-title { padding: 0 10px 10px 10px; } diff --git a/packages/app/src/Pages/ProfilePage.tsx b/packages/app/src/Pages/ProfilePage.tsx index 968ad110..41f4a56c 100644 --- a/packages/app/src/Pages/ProfilePage.tsx +++ b/packages/app/src/Pages/ProfilePage.tsx @@ -264,14 +264,7 @@ export default function ProfilePage() { } case FOLLOWS: { if (isMe) { - return ( - <> - - ; - - ); + return ; } else { return ; } @@ -379,7 +372,7 @@ export default function ProfilePage() { {isMe && blocked.length > 0 && renderTab(ProfileTab.Blocked)}
- {tabContent()} +
{tabContent()}
); } diff --git a/packages/app/src/Pages/new/DiscoverFollows.tsx b/packages/app/src/Pages/new/DiscoverFollows.tsx index 468e7e29..53d0ca1f 100644 --- a/packages/app/src/Pages/new/DiscoverFollows.tsx +++ b/packages/app/src/Pages/new/DiscoverFollows.tsx @@ -44,7 +44,7 @@ export default function DiscoverFollows() {

-
{sortedReccomends.length > 0 && }
+ {sortedReccomends.length > 0 && } ); diff --git a/packages/app/src/Pages/new/NewUserFlow.tsx b/packages/app/src/Pages/new/NewUserFlow.tsx index d319f82a..b63fb724 100644 --- a/packages/app/src/Pages/new/NewUserFlow.tsx +++ b/packages/app/src/Pages/new/NewUserFlow.tsx @@ -9,6 +9,7 @@ import { hexToMnemonic } from "nip6"; import useLogin from "Hooks/useLogin"; import messages from "./messages"; +import { PROFILE } from "."; const WhatIsSnort = () => { return ( @@ -107,7 +108,7 @@ export default function NewUserFlow() {
-
diff --git a/packages/app/src/Pages/new/NewUsername.tsx b/packages/app/src/Pages/new/ProfileSetup.tsx similarity index 53% rename from packages/app/src/Pages/new/NewUsername.tsx rename to packages/app/src/Pages/new/ProfileSetup.tsx index e6a19446..20d6864d 100644 --- a/packages/app/src/Pages/new/NewUsername.tsx +++ b/packages/app/src/Pages/new/ProfileSetup.tsx @@ -1,26 +1,47 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useIntl, FormattedMessage } from "react-intl"; import { useNavigate } from "react-router-dom"; import Logo from "Element/Logo"; import useEventPublisher from "Feed/EventPublisher"; +import useLogin from "Hooks/useLogin"; +import { useUserProfile } from "Hooks/useUserProfile"; +import { mapEventToProfile, UserCache } from "Cache"; +import AvatarEditor from "Element/AvatarEditor"; import messages from "./messages"; +import { DISCOVER } from "."; -export default function NewUserName() { +export default function ProfileSetup() { + const login = useLogin(); + const myProfile = useUserProfile(login.publicKey); const [username, setUsername] = useState(""); + const [picture, setPicture] = useState(""); const { formatMessage } = useIntl(); const publisher = useEventPublisher(); const navigate = useNavigate(); - const nextPage = "/new/discover"; + useEffect(() => { + if (myProfile) { + setUsername(myProfile.name ?? ""); + setPicture(myProfile.picture ?? ""); + } + }, [myProfile]); const onNext = async () => { - if (username.length > 0 && publisher) { - const ev = await publisher.metadata({ name: username }); + if ((username.length > 0 || picture.length > 0) && publisher) { + const ev = await publisher.metadata({ + ...myProfile, + name: username, + picture, + }); publisher.broadcast(ev); + const profile = mapEventToProfile(ev); + if (profile) { + UserCache.set(profile); + } } - navigate(nextPage); + navigate(DISCOVER); }; return ( @@ -30,13 +51,14 @@ export default function NewUserName() {

- +

-

- -

- + +

+ setPicture(p)} /> +

+

-
)} {(props.banner ?? true) && ( diff --git a/packages/app/src/index.css b/packages/app/src/index.css index 4e0a3c95..f9e3a792 100644 --- a/packages/app/src/index.css +++ b/packages/app/src/index.css @@ -374,7 +374,6 @@ input:disabled { a { color: inherit; line-height: 1.3em; - text-decoration: none; } a.ext {