tangled
alpha
login
or
join now
flo-bit.dev
/
blento
21
fork
atom
your personal website on atproto - mirror
blento.app
21
fork
atom
overview
issues
pulls
pipelines
some refactoring
Florian
2 weeks ago
96fe2c3a
fb4d93d0
+76
-147
9 changed files
expand all
collapse all
unified
split
src
lib
actor.ts
routes
[[actor=actor]]
(pages)
+layout.server.ts
.well-known
site.standard.publication
+server.ts
api
refresh
+server.ts
e
+page.server.ts
+page.svelte
[rkey]
+page.server.ts
+page.svelte
og.png
+server.ts
+40
src/lib/actor.ts
···
1
1
+
import type { ActorIdentifier, Did } from '@atcute/lexicons';
2
2
+
import type { CacheService } from './cache';
3
3
+
import { env as publicEnv } from '$env/dynamic/public';
4
4
+
import { resolveHandle } from './atproto';
5
5
+
import { isHandle } from '@atcute/lexicons/syntax';
6
6
+
7
7
+
export async function getActor({
8
8
+
request,
9
9
+
paramActor,
10
10
+
platform,
11
11
+
blockBoth = true
12
12
+
}: {
13
13
+
request: Request;
14
14
+
paramActor?: ActorIdentifier;
15
15
+
platform: Readonly<App.Platform> | undefined;
16
16
+
blockBoth?: boolean;
17
17
+
}): Promise<Did | undefined> {
18
18
+
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
19
19
+
let actor = paramActor;
20
20
+
21
21
+
if (!actor) {
22
22
+
const kv = platform?.env?.CUSTOM_DOMAINS;
23
23
+
24
24
+
if (kv && customDomain) {
25
25
+
try {
26
26
+
const did = await kv.get(customDomain);
27
27
+
28
28
+
if (did) actor = did as ActorIdentifier;
29
29
+
} catch (error) {
30
30
+
console.error('failed to get custom domain kv', error);
31
31
+
}
32
32
+
} else {
33
33
+
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
34
34
+
}
35
35
+
} else if (customDomain && paramActor && blockBoth) {
36
36
+
actor = undefined;
37
37
+
}
38
38
+
39
39
+
return isHandle(actor) ? await resolveHandle({ handle: actor }) : actor;
40
40
+
}
+2
-23
src/routes/[[actor=actor]]/(pages)/+layout.server.ts
···
2
2
import { env } from '$env/dynamic/private';
3
3
import { error } from '@sveltejs/kit';
4
4
import { createCache } from '$lib/cache';
5
5
-
import type { ActorIdentifier } from '@atcute/lexicons';
6
6
-
import { env as publicEnv } from '$env/dynamic/public';
5
5
+
import { getActor } from '$lib/actor.js';
7
6
8
7
export async function load({ params, platform, request }) {
9
8
if (env.PUBLIC_IS_SELFHOSTED) error(404);
10
9
11
10
const cache = createCache(platform);
12
11
13
13
-
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
14
14
-
15
15
-
let actor: ActorIdentifier | undefined = params.actor;
16
16
-
17
17
-
if (!actor) {
18
18
-
const kv = platform?.env?.CUSTOM_DOMAINS;
19
19
-
20
20
-
if (kv && customDomain) {
21
21
-
try {
22
22
-
const did = await kv.get(customDomain);
23
23
-
24
24
-
if (did) actor = did as ActorIdentifier;
25
25
-
} catch (error) {
26
26
-
console.error('failed to get custom domain kv', error);
27
27
-
}
28
28
-
} else {
29
29
-
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
30
30
-
}
31
31
-
} else if (customDomain && params.actor) {
32
32
-
actor = undefined;
33
33
-
}
12
12
+
const actor = await getActor({ request, paramActor: params.actor, platform });
34
13
35
14
if (!actor) {
36
15
throw error(404, 'Page not found');
+2
-24
src/routes/[[actor=actor]]/.well-known/site.standard.publication/+server.ts
···
1
1
import { loadData } from '$lib/website/load';
2
2
import { createCache } from '$lib/cache';
3
3
import { env } from '$env/dynamic/private';
4
4
-
import { env as publicEnv } from '$env/dynamic/public';
5
5
-
import type { ActorIdentifier } from '@atcute/lexicons';
6
6
-
7
4
import { error } from '@sveltejs/kit';
8
5
import { text } from '@sveltejs/kit';
6
6
+
import { getActor } from '$lib/actor.js';
9
7
10
8
export async function GET({ params, platform, request }) {
11
9
const cache = createCache(platform);
12
10
13
13
-
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
14
14
-
15
15
-
let actor: ActorIdentifier | undefined = params.actor;
16
16
-
17
17
-
if (!actor) {
18
18
-
const kv = platform?.env?.CUSTOM_DOMAINS;
19
19
-
20
20
-
if (kv && customDomain) {
21
21
-
try {
22
22
-
const did = await kv.get(customDomain);
23
23
-
24
24
-
if (did) actor = did as ActorIdentifier;
25
25
-
} catch (error) {
26
26
-
console.error('failed to get custom domain kv', error);
27
27
-
}
28
28
-
} else {
29
29
-
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
30
30
-
}
31
31
-
} else if (customDomain && params.actor) {
32
32
-
actor = undefined;
33
33
-
}
11
11
+
const actor = await getActor({ request, paramActor: params.actor, platform });
34
12
35
13
if (!actor) {
36
14
throw error(404, 'Page not found');
+2
-21
src/routes/[[actor=actor]]/api/refresh/+server.ts
···
1
1
import { createCache } from '$lib/cache';
2
2
import { loadData } from '$lib/website/load.js';
3
3
import { env } from '$env/dynamic/private';
4
4
-
import { env as publicEnv } from '$env/dynamic/public';
5
5
-
import type { ActorIdentifier } from '@atcute/lexicons';
6
4
import { error, json } from '@sveltejs/kit';
5
5
+
import { getActor } from '$lib/actor';
7
6
8
7
export async function GET({ params, platform, request }) {
9
8
const cache = createCache(platform);
10
9
if (!cache) return json('no cache');
11
10
12
12
-
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
13
13
-
14
14
-
let actor: ActorIdentifier | undefined = params.actor;
15
15
-
16
16
-
if (!actor) {
17
17
-
const kv = platform?.env?.CUSTOM_DOMAINS;
18
18
-
19
19
-
if (kv && customDomain) {
20
20
-
try {
21
21
-
const did = await kv.get(customDomain);
22
22
-
23
23
-
if (did) actor = did as ActorIdentifier;
24
24
-
} catch (error) {
25
25
-
console.error('failed to get custom domain kv', error);
26
26
-
}
27
27
-
} else {
28
28
-
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
29
29
-
}
30
30
-
}
11
11
+
const actor = await getActor({ request, paramActor: params.actor, platform });
31
12
32
13
if (!actor) {
33
14
throw error(404, 'Page not found');
+4
-27
src/routes/[[actor=actor]]/e/+page.server.ts
···
1
1
import { error } from '@sveltejs/kit';
2
2
import type { EventData } from '$lib/cards/social/EventCard';
3
3
-
import { getBlentoOrBskyProfile, resolveHandle } from '$lib/atproto/methods.js';
4
4
-
import { isHandle } from '@atcute/lexicons/syntax';
3
3
+
import { getBlentoOrBskyProfile } from '$lib/atproto/methods.js';
5
4
import { createCache, type CachedProfile } from '$lib/cache';
6
6
-
import type { ActorIdentifier, Did } from '@atcute/lexicons';
7
7
-
import { env as publicEnv } from '$env/dynamic/public';
5
5
+
import type { Did } from '@atcute/lexicons';
6
6
+
import { getActor } from '$lib/actor.js';
8
7
9
8
export async function load({ params, platform, request }) {
10
9
const cache = createCache(platform);
11
10
12
12
-
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
13
13
-
14
14
-
let actor: ActorIdentifier | undefined = params.actor;
15
15
-
16
16
-
if (!actor) {
17
17
-
const kv = platform?.env?.CUSTOM_DOMAINS;
18
18
-
19
19
-
if (kv && customDomain) {
20
20
-
try {
21
21
-
const did = await kv.get(customDomain);
22
22
-
23
23
-
if (did) actor = did as ActorIdentifier;
24
24
-
} catch (error) {
25
25
-
console.error('failed to get custom domain kv', error);
26
26
-
}
27
27
-
} else {
28
28
-
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
29
29
-
}
30
30
-
} else if (customDomain && params.actor) {
31
31
-
actor = undefined;
32
32
-
}
33
33
-
34
34
-
const did = isHandle(actor) ? await resolveHandle({ handle: actor }) : actor;
11
11
+
const did = await getActor({ request, paramActor: params.actor, platform });
35
12
36
13
if (!did) {
37
14
throw error(404, 'Events not found');
+21
-8
src/routes/[[actor=actor]]/e/+page.svelte
···
11
11
let hostProfile = $derived(data.hostProfile);
12
12
13
13
let hostName = $derived(hostProfile?.displayName || hostProfile?.handle || did);
14
14
+
let hostUrl = $derived(
15
15
+
hostProfile?.url ?? `https://bsky.app/profile/${hostProfile?.handle || did}`
16
16
+
);
14
17
15
18
function formatDate(dateStr: string): string {
16
19
const date = new Date(dateStr);
···
88
91
<meta name="twitter:description" content="Events hosted by {hostName}" />
89
92
</svelte:head>
90
93
91
91
-
<div class="bg-base-50 dark:bg-base-950 min-h-screen px-8 py-8 sm:py-12">
94
94
+
<div class="bg-base-50 dark:bg-base-950 min-h-screen px-6 py-12 sm:py-12">
92
95
<div class="mx-auto max-w-4xl">
93
96
<!-- Header -->
94
94
-
<div class="mb-8 flex items-center gap-3">
95
95
-
<FoxAvatar src={hostProfile?.avatar} alt={hostName} class="size-10 shrink-0" />
96
96
-
<div>
97
97
-
<h1 class="text-base-900 dark:text-base-50 text-2xl font-bold sm:text-3xl">Events</h1>
98
98
-
<p class="text-base-500 dark:text-base-400 text-sm">Hosted by {hostName}</p>
97
97
+
<div class="mb-8">
98
98
+
<h1 class="text-base-900 dark:text-base-50 mb-2 text-2xl font-bold sm:text-3xl">
99
99
+
Upcoming events
100
100
+
</h1>
101
101
+
<div class="flex items-center gap-2">
102
102
+
<span class="text-base-500 dark:text-base-400 text-sm">Hosted by</span>
103
103
+
<a
104
104
+
href={hostUrl}
105
105
+
target={hostProfile?.hasBlento ? undefined : '_blank'}
106
106
+
rel={hostProfile?.hasBlento ? undefined : 'noopener noreferrer'}
107
107
+
class="flex items-center gap-1.5 hover:underline"
108
108
+
>
109
109
+
<FoxAvatar src={hostProfile?.avatar} alt={hostName} class="size-5 shrink-0" />
110
110
+
<span class="text-base-900 dark:text-base-100 text-sm font-medium">{hostName}</span>
111
111
+
</a>
99
112
</div>
100
113
</div>
101
114
···
116
129
<img
117
130
src={thumbnail.url}
118
131
alt={thumbnail.alt}
119
119
-
class="aspect-[3/2] w-full object-cover"
132
132
+
class="aspect-square w-full object-cover"
120
133
/>
121
134
{:else}
122
135
<div
123
123
-
class="bg-base-100 dark:bg-base-900 aspect-[3/2] w-full [&>svg]:h-full [&>svg]:w-full"
136
136
+
class="bg-base-100 dark:bg-base-900 aspect-square w-full [&>svg]:h-full [&>svg]:w-full"
124
137
>
125
138
<Avatar
126
139
size={400}
+2
-23
src/routes/[[actor=actor]]/e/[rkey]/+page.server.ts
···
5
5
import { createCache, type CachedProfile } from '$lib/cache';
6
6
import type { ActorIdentifier, Did } from '@atcute/lexicons';
7
7
import { env as publicEnv } from '$env/dynamic/public';
8
8
+
import { getActor } from '$lib/actor';
8
9
9
10
export async function load({ params, platform, request }) {
10
11
const { rkey } = params;
11
12
12
13
const cache = createCache(platform);
13
14
14
14
-
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
15
15
-
16
16
-
let actor: ActorIdentifier | undefined = params.actor;
17
17
-
18
18
-
if (!actor) {
19
19
-
const kv = platform?.env?.CUSTOM_DOMAINS;
20
20
-
21
21
-
if (kv && customDomain) {
22
22
-
try {
23
23
-
const did = await kv.get(customDomain);
24
24
-
25
25
-
if (did) actor = did as ActorIdentifier;
26
26
-
} catch (error) {
27
27
-
console.error('failed to get custom domain kv', error);
28
28
-
}
29
29
-
} else {
30
30
-
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
31
31
-
}
32
32
-
} else if (customDomain && params.actor) {
33
33
-
actor = undefined;
34
34
-
}
35
35
-
36
36
-
const did = isHandle(actor) ? await resolveHandle({ handle: actor }) : actor;
15
15
+
const did = await getActor({ request, paramActor: params.actor, platform });
37
16
38
17
if (!did || !rkey) {
39
18
throw error(404, 'Event not found');
+1
-1
src/routes/[[actor=actor]]/e/[rkey]/+page.svelte
···
106
106
<meta name="twitter:image" content={ogImageUrl} />
107
107
</svelte:head>
108
108
109
109
-
<div class="bg-base-50 dark:bg-base-950 min-h-screen px-8 py-8 sm:py-12">
109
109
+
<div class="bg-base-50 dark:bg-base-950 min-h-screen px-6 py-12 sm:py-12">
110
110
<div class="mx-auto max-w-4xl">
111
111
<!-- Two-column layout: image left, details right -->
112
112
<div
+2
-20
src/routes/[[actor=actor]]/e/[rkey]/og.png/+server.ts
···
7
7
import { ImageResponse } from '@ethercorps/sveltekit-og';
8
8
import { error } from '@sveltejs/kit';
9
9
import EventOgImage from './EventOgImage.svelte';
10
10
+
import { getActor } from '$lib/actor';
10
11
11
12
function formatDate(dateStr: string): string {
12
13
const date = new Date(dateStr);
···
19
20
export async function GET({ params, platform, request }) {
20
21
const { rkey } = params;
21
22
22
22
-
const customDomain = request.headers.get('X-Custom-Domain')?.toLowerCase();
23
23
-
24
24
-
let actor: ActorIdentifier | undefined = params.actor;
25
25
-
26
26
-
if (!actor) {
27
27
-
const kv = platform?.env?.CUSTOM_DOMAINS;
28
28
-
29
29
-
if (kv && customDomain) {
30
30
-
try {
31
31
-
const did = await kv.get(customDomain);
32
32
-
if (did) actor = did as ActorIdentifier;
33
33
-
} catch (error) {
34
34
-
console.error('failed to get custom domain kv', error);
35
35
-
}
36
36
-
} else {
37
37
-
actor = publicEnv.PUBLIC_HANDLE as ActorIdentifier;
38
38
-
}
39
39
-
}
40
40
-
41
41
-
const did = isHandle(actor) ? await resolveHandle({ handle: actor }) : actor;
23
23
+
const did = await getActor({ request, paramActor: params.actor, platform });
42
24
43
25
if (!did || !rkey) {
44
26
throw error(404, 'Event not found');