feat[WIP]: Add username display and validation to profile page
Some checks failed
Build & Test / build (20.x) (push) Has been cancelled
Build & Test / build (22.x) (push) Has been cancelled

This commit is contained in:
Shibo Lyu 2025-04-16 02:11:16 +08:00
parent fc47399e2c
commit 9e79b29c69
2 changed files with 43 additions and 1 deletions

View file

@ -8,15 +8,17 @@
GroupedListContent, GroupedListContent,
GroupedListItem GroupedListItem
} from '$lib/components/GroupedList'; } from '$lib/components/GroupedList';
import type { BlahProfile } from '@blah-im/core/identity'; import type { BlahIdentity, BlahProfile } from '@blah-im/core/identity';
import ProfilePicture from '$lib/components/ProfilePicture.svelte'; import ProfilePicture from '$lib/components/ProfilePicture.svelte';
import Button from '$lib/components/Button.svelte'; import Button from '$lib/components/Button.svelte';
import RichTextInput from '$lib/components/RichTextInput.svelte'; import RichTextInput from '$lib/components/RichTextInput.svelte';
import { messageSchema } from '$lib/components/RichTextInput/schema'; import { messageSchema } from '$lib/components/RichTextInput/schema';
import { blahRichTextToProseMirrorDoc } from '$lib/richText'; import { blahRichTextToProseMirrorDoc } from '$lib/richText';
import type { Node } from 'prosemirror-model'; import type { Node } from 'prosemirror-model';
import UsernameItem from './UsernameItem.svelte';
const currentAccount = $derived(accountsManager.currentAccount); const currentAccount = $derived(accountsManager.currentAccount);
let identity: BlahIdentity | null = $state(null);
let profile: BlahProfile | null = $state(null); let profile: BlahProfile | null = $state(null);
let initialBio: Node | null = $state(null); let initialBio: Node | null = $state(null);
@ -27,6 +29,9 @@
const snapshot = $state.snapshot(currentAccount.profile.signee.payload); const snapshot = $state.snapshot(currentAccount.profile.signee.payload);
profile = snapshot; profile = snapshot;
initialBio = blahRichTextToProseMirrorDoc([snapshot.bio ?? ''], messageSchema); initialBio = blahRichTextToProseMirrorDoc([snapshot.bio ?? ''], messageSchema);
accountsManager.identityForAccount(currentAccount).then((x) => {
identity = x;
});
} }
}); });
@ -69,5 +74,11 @@
initialDoc={initialBio} initialDoc={initialBio}
/> />
</GroupedListSection> </GroupedListSection>
<GroupedListSection header="Usernames">
{#each profile.id_urls as url (url)}
<UsernameItem {url} {identity} />
{/each}
</GroupedListSection>
</GroupedListContainer> </GroupedListContainer>
{/if} {/if}

View file

@ -0,0 +1,31 @@
<script lang="ts">
import { GroupedListItem } from '$lib/components/GroupedList';
import LoadingIndicator from '$lib/components/LoadingIndicator.svelte';
import { idURLToUsername, validateIDURL } from '$lib/idURL';
import type { BlahIdentity } from '@blah-im/core/identity';
import { ExclamationCircle, ExclamationTriangle, Icon } from 'svelte-hero-icons';
interface Props {
url: string;
identity?: BlahIdentity | null;
}
let { url, identity }: Props = $props();
async function validate() {
if (!identity) return null;
return await validateIDURL(url, identity);
}
</script>
<GroupedListItem>
<span class="before:opacity-80 before:content-['@']">{idURLToUsername(url)}</span>
{#await validate()}
<LoadingIndicator />
{:then result}
{#if result && !result.valid}
<Icon solid src={ExclamationCircle} class="size-5 text-red-500" />
{/if}
{/await}
</GroupedListItem>