/** @jsx h */ import { createRef, Fragment, h } from "https://esm.sh/preact@10.17.1"; import { Avatar } from "./components/avatar.tsx"; import { CenterClass, DividerClass, InputClass, LinearGradientsClass, NoOutlineClass, } from "./components/tw.ts"; import { ProfileData } from "../features/profile.ts"; import { DividerBackgroundColor, ErrorColor, HintLinkColor, HintTextColor, HoverButtonBackgroudColor, PrimaryTextColor, SecondaryBackgroundColor, } from "./style/colors.ts"; import { Component, ComponentChildren } from "https://esm.sh/preact@10.11.3"; import { ProfileGetter } from "./search.tsx"; import { NostrAccountContext } from "../lib/nostr-ts/nostr.ts"; import { emitFunc } from "../event-bus.ts"; export type SaveProfile = { type: "SaveProfile"; profile: ProfileData; ctx: NostrAccountContext; }; type profileItem = { key: string; value?: string; hint?: ComponentChildren; }; type Props = { ctx: NostrAccountContext; profileGetter: ProfileGetter; emit: emitFunc; }; type State = { profile: ProfileData | undefined; newFieldKeyError: string; }; export class EditProfile extends Component { styles = { container: `py-4 bg-[${SecondaryBackgroundColor}]`, banner: { container: `h-72 w-full rounded-lg mb-20 relative`, avatar: `w-24 h-24 m-auto absolute top-60 left-1/2 box-border border-2 border-[${PrimaryTextColor}] -translate-x-2/4`, }, avatar: `w-24 h-24 m-auto box-border border-2 border-[${PrimaryTextColor}]`, field: { title: `text-[${PrimaryTextColor}] mt-8`, input: `${InputClass}`, hint: { text: `text-sm text-[${HintTextColor}]`, link: `text-[${HintLinkColor}]`, }, }, addButton: `w-full mt-6 p-3 rounded-lg ${NoOutlineClass} text-[${PrimaryTextColor}] bg-[${DividerBackgroundColor}] hover:bg-[${HoverButtonBackgroudColor}] ${CenterClass}`, submitButton: `w-full p-3 rounded-lg ${NoOutlineClass} text-[${PrimaryTextColor}] ${CenterClass} ${LinearGradientsClass} hover:bg-gradient-to-l`, divider: `${DividerClass}`, custom: { title: `text-[${PrimaryTextColor}] font-bold text-sm`, text: `text-[${HintTextColor}] text-sm`, error: `text-sm text-[${ErrorColor}]`, }, }; componentDidMount() { const { ctx, profileGetter } = this.props; this.setState({ profile: profileGetter.getProfilesByPublicKey(ctx.publicKey)?.profile, }); } shouldComponentUpdate(_: Readonly, nextState: Readonly, __: any): boolean { return JSON.stringify(this.state.profile) != JSON.stringify(nextState.profile); } newFieldKey = createRef(); newFieldValue = createRef(); onInput = (e: h.JSX.TargetedEvent, key?: string) => { const lines = e.currentTarget.value.split("\n"); e.currentTarget.setAttribute( "rows", `${lines.length}`, ); if (key) { const value = e.currentTarget.value; this.setState({ profile: { ...this.state.profile, [key]: value, }, }); } }; addField = () => { if (!this.newFieldKey.current || !this.newFieldValue.current) { return; } if (this.newFieldKey.current.value.trim() == "") { this.setState({ newFieldKeyError: "Key is required.", }); return; } this.setState({ profile: { ...this.state.profile, [this.newFieldKey.current.value]: this.newFieldValue.current.value, }, newFieldKeyError: "", }); this.newFieldKey.current.value = ""; this.newFieldValue.current.value = ""; }; onSubmit = () => { if (!this.state.profile) { return; } this.props.emit({ type: "SaveProfile", ctx: this.props.ctx, profile: this.state.profile, }); }; render() { const profileItems: profileItem[] = [ { key: "name", value: this.state.profile?.name, }, { key: "banner", value: this.state.profile?.banner, }, { key: "picture", value: this.state.profile?.picture, hint: ( You can upload your images on websites like{" "} nostr.build ), }, { key: "about", value: this.state.profile?.about, }, { key: "website", value: this.state.profile?.website, }, ]; if (this.state.profile) { for (const [key, value] of Object.entries(this.state.profile)) { if (["name", "picture", "about", "website", "banner"].includes(key) || !value) { continue; } profileItems.push({ key: key, value: value, }); } } const banner = this.state.profile?.banner ? (
) : ( ); const items = profileItems.map((item) => (

{item.key}

{item.hint}
)); return (
{banner} {items}

Custom Fields

Create your own custom fields, anything goes!

Field name

{this.state.newFieldKeyError}

Field value

); } }