feat: new user flow profile editor
This commit is contained in:
@ -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"] {
|
||||
|
49
packages/app/src/Element/AvatarEditor.tsx
Normal file
49
packages/app/src/Element/AvatarEditor.tsx
Normal file
@ -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 (
|
||||
<>
|
||||
<div className="flex f-center">
|
||||
<div style={{ backgroundImage: `url(${picture})` }} className="avatar">
|
||||
<div className={`edit${picture ? "" : " new"}`} onClick={() => uploadFile().catch(console.error)}>
|
||||
<Icon name={picture ? "edit" : "camera-plus"} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{error && <b className="error">{error}</b>}
|
||||
</>
|
||||
);
|
||||
}
|
@ -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 (
|
||||
<div className="main-content">
|
||||
<>
|
||||
{(showFollowAll ?? true) && (
|
||||
<div className="flex mt10 mb10">
|
||||
<div className="f-grow bold">{title}</div>
|
||||
@ -38,6 +38,6 @@ export default function FollowListBase({ pubkeys, title, showFollowAll, showAbou
|
||||
{pubkeys?.map(a => (
|
||||
<ProfilePreview pubkey={a} key={a} options={{ about: showAbout }} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
.hashtag {
|
||||
color: var(--highlight);
|
||||
}
|
||||
|
||||
.hashtag > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
@ -8,6 +8,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link-preview-container > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link-preview-title {
|
||||
padding: 0 10px 10px 10px;
|
||||
}
|
||||
|
Reference in New Issue
Block a user