your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { marked } from 'marked';
3 import { sanitize } from '$lib/sanitize';
4 import type { WebsiteData } from '$lib/types';
5 import { getDescription, getImage, getName, getProfilePosition } from '$lib/helper';
6 import { page } from '$app/state';
7 import { qrOverlay } from '$lib/components/qr/qrOverlay.svelte';
8 import MadeWithBlento from './MadeWithBlento.svelte';
9 import { Avatar } from '@foxui/core';
10 import Pronouns from './Pronouns.svelte';
11
12 let {
13 data,
14 hideBlento = false
15 }: {
16 data: WebsiteData;
17 hideBlento?: boolean;
18 } = $props();
19
20 const renderer = new marked.Renderer();
21 renderer.link = ({ href, title, text }) =>
22 `<a target="_blank" href="${href}" title="${title ?? ''}">${text}</a>`;
23
24 const profileUrl = $derived(`${page.url.origin}/${data.handle}`);
25 const profilePosition = $derived(getProfilePosition(data));
26</script>
27
28<!-- lg:fixed lg:h-screen lg:w-1/4 lg:max-w-none lg:px-12 lg:pt-24 xl:w-1/3 -->
29<div
30 class={[
31 'mx-auto flex max-w-lg flex-col justify-between px-8',
32 profilePosition === 'side'
33 ? '@5xl/wrapper:fixed @5xl/wrapper:h-screen @5xl/wrapper:w-1/4 @5xl/wrapper:max-w-none @5xl/wrapper:px-12'
34 : '@5xl/wrapper:max-w-4xl @5xl/wrapper:px-12'
35 ]}
36>
37 <div
38 class={[
39 'flex flex-col gap-4 pt-16 pb-4',
40 profilePosition === 'side' && '@5xl/wrapper:h-screen @5xl/wrapper:pt-24'
41 ]}
42 >
43 <a
44 href={profileUrl}
45 class="w-fit"
46 use:qrOverlay={{
47 context: {
48 title: getName(data) + "'s blento"
49 }
50 }}
51 >
52 <Avatar
53 src={getImage(data.publication, data.did, 'icon') || data.profile.avatar}
54 class={[
55 'border-base-400 dark:border-base-800 size-32 shrink-0 rounded-full border object-cover',
56 profilePosition === 'side' && '@5xl/wrapper:size-44'
57 ]}
58 />
59 </a>
60
61 <div class="text-4xl font-bold wrap-anywhere">
62 {getName(data)}
63 </div>
64
65 {#if data.pronounsRecord?.value?.sets?.length}
66 <Pronouns {data} />
67 {/if}
68
69 <div class="scrollbar -mx-4 grow overflow-x-hidden overflow-y-scroll px-4">
70 <div
71 class="text-base-600 dark:text-base-400 prose dark:prose-invert prose-a:text-accent-500 prose-a:no-underline whitespace-pre-wrap"
72 >
73 {@html sanitize(
74 marked.parse(getDescription(data), {
75 renderer
76 }) as string,
77 { ADD_ATTR: ['target'] }
78 )}
79 </div>
80 </div>
81
82 {#if !hideBlento}
83 <MadeWithBlento class="hidden {profilePosition === 'side' && '@5xl/wrapper:block'}" />
84 {/if}
85 </div>
86</div>