mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-18 22:44:26 +01:00
feat: support lud06 / lud16 in profile input
This commit is contained in:
@@ -3,6 +3,7 @@ import { createSignal, type Component, batch, onMount, For, JSX, Show } from 'so
|
|||||||
import { createMutation } from '@tanstack/solid-query';
|
import { createMutation } from '@tanstack/solid-query';
|
||||||
import ArrowLeft from 'heroicons/24/outline/arrow-left.svg';
|
import ArrowLeft from 'heroicons/24/outline/arrow-left.svg';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
|
import omitBy from 'lodash/omitBy';
|
||||||
|
|
||||||
import Modal from '@/components/Modal';
|
import Modal from '@/components/Modal';
|
||||||
import useConfig from '@/core/useConfig';
|
import useConfig from '@/core/useConfig';
|
||||||
@@ -16,6 +17,16 @@ export type ProfileEditProps = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const LNURLRegexString = 'LNURL1[AC-HJ-NP-Zac-hj-np-z02-9]+';
|
||||||
|
const LightningAddressRegexString = '[-a-zA-Z0-9.]+@[-a-zA-Z0-9.]+';
|
||||||
|
const LUDAddressRegexString = `^(${LNURLRegexString}|${LightningAddressRegexString})$`;
|
||||||
|
|
||||||
|
const LNURLRegex = new RegExp(`^${LNURLRegexString}$`);
|
||||||
|
const LightningAddressRegex = new RegExp(`${LightningAddressRegexString}`);
|
||||||
|
|
||||||
|
const isLNURL = (s: string) => LNURLRegex.test(s);
|
||||||
|
const isLightningAddress = (s: string) => LightningAddressRegex.test(s);
|
||||||
|
|
||||||
const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
||||||
const pubkey = usePubkey();
|
const pubkey = usePubkey();
|
||||||
const { config } = useConfig();
|
const { config } = useConfig();
|
||||||
@@ -33,6 +44,7 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
const [about, setAbout] = createSignal('');
|
const [about, setAbout] = createSignal('');
|
||||||
const [website, setWebsite] = createSignal('');
|
const [website, setWebsite] = createSignal('');
|
||||||
const [nip05, setNIP05] = createSignal('');
|
const [nip05, setNIP05] = createSignal('');
|
||||||
|
const [lightningAddress, setLightningAddress] = createSignal('');
|
||||||
|
|
||||||
const mutation = createMutation({
|
const mutation = createMutation({
|
||||||
mutationKey: ['updateProfile'],
|
mutationKey: ['updateProfile'],
|
||||||
@@ -61,7 +73,17 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
|
|
||||||
const disabled = () => query.isLoading || query.isError || mutation.isLoading;
|
const disabled = () => query.isLoading || query.isError || mutation.isLoading;
|
||||||
const otherProperties = () =>
|
const otherProperties = () =>
|
||||||
omit(profile(), ['picture', 'banner', 'name', 'display_name', 'about', 'website', 'nip05']);
|
omit(profile(), [
|
||||||
|
'picture',
|
||||||
|
'banner',
|
||||||
|
'name',
|
||||||
|
'display_name',
|
||||||
|
'about',
|
||||||
|
'website',
|
||||||
|
'nip05',
|
||||||
|
'lud06',
|
||||||
|
'lud16',
|
||||||
|
]);
|
||||||
|
|
||||||
const handleSubmit: JSX.EventHandler<HTMLFormElement, Event> = (ev) => {
|
const handleSubmit: JSX.EventHandler<HTMLFormElement, Event> = (ev) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
@@ -69,15 +91,20 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
const p = pubkey();
|
const p = pubkey();
|
||||||
if (p == null) return;
|
if (p == null) return;
|
||||||
|
|
||||||
const newProfile: Profile = {
|
const newProfile: Profile = omitBy(
|
||||||
picture: picture(),
|
{
|
||||||
banner: banner(),
|
picture: picture(),
|
||||||
name: name(),
|
banner: banner(),
|
||||||
display_name: displayName(),
|
name: name(),
|
||||||
about: about(),
|
display_name: displayName(),
|
||||||
website: website(),
|
about: about(),
|
||||||
nip05: nip05(),
|
website: website(),
|
||||||
};
|
nip05: nip05(),
|
||||||
|
lud06: isLNURL(lightningAddress()) ? lightningAddress() : null,
|
||||||
|
lud16: isLightningAddress(lightningAddress()) ? lightningAddress() : null,
|
||||||
|
},
|
||||||
|
(v) => v == null || v.length === 0,
|
||||||
|
);
|
||||||
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
relayUrls: config().relayUrls,
|
relayUrls: config().relayUrls,
|
||||||
@@ -103,6 +130,11 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
setAbout((current) => currentProfile.about ?? current);
|
setAbout((current) => currentProfile.about ?? current);
|
||||||
setWebsite((current) => currentProfile.website ?? current);
|
setWebsite((current) => currentProfile.website ?? current);
|
||||||
setNIP05((current) => currentProfile.nip05 ?? current);
|
setNIP05((current) => currentProfile.nip05 ?? current);
|
||||||
|
if (currentProfile.lud16 != null) {
|
||||||
|
setLightningAddress(currentProfile.lud16);
|
||||||
|
} else if (currentProfile.lud06 != null) {
|
||||||
|
setLightningAddress(currentProfile.lud06);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -118,7 +150,7 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
<ArrowLeft />
|
<ArrowLeft />
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="flex h-full flex-col overflow-y-scroll rounded-xl border bg-white pb-16 text-stone-700 shadow-lg">
|
<div class="flex h-full flex-col overflow-y-scroll rounded-xl border bg-white pb-32 text-stone-700 shadow-lg">
|
||||||
<div>
|
<div>
|
||||||
<Show when={banner().length > 0} fallback={<div class="h-12 shrink-0" />} keyed>
|
<Show when={banner().length > 0} fallback={<div class="h-12 shrink-0" />} keyed>
|
||||||
<div class="h-40 w-full shrink-0 sm:h-52">
|
<div class="h-40 w-full shrink-0 sm:h-52">
|
||||||
@@ -210,7 +242,7 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
自己紹介
|
自己紹介
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
class="w-full rounded-md"
|
class="w-full rounded-md focus:border-rose-100 focus:ring-rose-300"
|
||||||
name="about"
|
name="about"
|
||||||
value={about()}
|
value={about()}
|
||||||
rows="5"
|
rows="5"
|
||||||
@@ -233,19 +265,38 @@ const ProfileEdit: Component<ProfileEditProps> = (props) => {
|
|||||||
onKeyDown={ignoreEnter}
|
onKeyDown={ignoreEnter}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="flex flex-col items-start gap-1">
|
||||||
<span class="font-bold">その他の項目</span>
|
<label class="font-bold" for="name">
|
||||||
<div>
|
LNURLアドレス / ライトニングアドレス
|
||||||
<For each={Object.entries(otherProperties())}>
|
</label>
|
||||||
{([key, value]) => (
|
<span class="text-xs">どちらか片方のみが保存されます。</span>
|
||||||
<div class="flex flex-col items-start">
|
<input
|
||||||
<span class="text-sm font-bold">{key}</span>
|
class="w-full rounded-md focus:border-rose-100 focus:ring-rose-300"
|
||||||
<span class="text-sm">{value}</span>
|
type="text"
|
||||||
</div>
|
name="website"
|
||||||
)}
|
value={lightningAddress()}
|
||||||
</For>
|
pattern={LUDAddressRegexString}
|
||||||
</div>
|
placeholder="LNURL1XXXXXX / abcdef@wallet.example.com"
|
||||||
|
disabled={disabled()}
|
||||||
|
onChange={(ev) => setLightningAddress(ev.currentTarget.value)}
|
||||||
|
onKeyDown={ignoreEnter}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<Show when={Object.entries(otherProperties()).length > 0}>
|
||||||
|
<div>
|
||||||
|
<span class="font-bold">その他の項目</span>
|
||||||
|
<div>
|
||||||
|
<For each={Object.entries(otherProperties())}>
|
||||||
|
{([key, value]) => (
|
||||||
|
<div class="flex flex-col items-start ">
|
||||||
|
<span class="text-sm font-bold">{key}</span>
|
||||||
|
<span class="whitespace-pre-wrap break-all text-sm">{value}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
|||||||
Reference in New Issue
Block a user