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
add germ card
Florian
2 weeks ago
34efea62
dd0079fd
+121
-2
4 changed files
expand all
collapse all
unified
split
src
lib
cards
index.ts
social
GermDMCard
GermDMCard.svelte
index.ts
website
Context.svelte
+3
-1
src/lib/cards/index.ts
···
49
49
import { PlyrFMCardDefinition, PlyrFMCollectionCardDefinition } from './media/PlyrFMCard';
50
50
import { MarginCardDefinition } from './social/MarginCard';
51
51
import { SembleCollectionCardDefinition } from './social/SembleCollectionCard';
52
52
+
import { GermDMCardDefinition } from './social/GermDMCard';
52
53
// import { Model3DCardDefinition } from './visual/Model3DCard';
53
54
54
55
export const AllCardDefinitions = [
···
103
104
PlyrFMCardDefinition,
104
105
PlyrFMCollectionCardDefinition,
105
106
MarginCardDefinition,
106
106
-
SembleCollectionCardDefinition
107
107
+
SembleCollectionCardDefinition,
108
108
+
GermDMCardDefinition
107
109
] as const;
108
110
109
111
export const CardDefinitionsByType = AllCardDefinitions.reduce(
+73
src/lib/cards/social/GermDMCard/GermDMCard.svelte
···
1
1
+
<script lang="ts">
2
2
+
import { onMount } from 'svelte';
3
3
+
import { getAdditionalUserData, getDidContext, getHandleContext } from '$lib/website/context';
4
4
+
import type { ContentComponentProps } from '../../types';
5
5
+
import { CardDefinitionsByType } from '../..';
6
6
+
import { user } from '$lib/atproto/auth.svelte';
7
7
+
import { platformsData } from '../BigSocialCard';
8
8
+
9
9
+
let { item = $bindable(), isEditing }: ContentComponentProps = $props();
10
10
+
11
11
+
const data = getAdditionalUserData();
12
12
+
13
13
+
let germData = $state(
14
14
+
data[item.cardType] as { messageMeUrl: string; showButtonTo: string } | null | undefined
15
15
+
);
16
16
+
17
17
+
let did = getDidContext();
18
18
+
let handle = getHandleContext();
19
19
+
let isLoaded = $state(false);
20
20
+
21
21
+
onMount(async () => {
22
22
+
if (!germData) {
23
23
+
germData = (await CardDefinitionsByType[item.cardType]?.loadData?.([], {
24
24
+
did,
25
25
+
handle
26
26
+
})) as { messageMeUrl: string; showButtonTo: string } | null | undefined;
27
27
+
28
28
+
data[item.cardType] = germData;
29
29
+
isLoaded = true;
30
30
+
}
31
31
+
});
32
32
+
33
33
+
const brandColor = `#${platformsData.germ.hex}`;
34
34
+
35
35
+
const dmUrl = $derived.by(() => {
36
36
+
if (!germData?.messageMeUrl) return undefined;
37
37
+
const viewerDid = user.did;
38
38
+
const fragment = viewerDid ? `${did}+${viewerDid}` : `${did}`;
39
39
+
return `${germData.messageMeUrl}/web#${fragment}`;
40
40
+
});
41
41
+
</script>
42
42
+
43
43
+
{#if germData && dmUrl}
44
44
+
<div
45
45
+
class="flex h-full w-full items-center justify-center p-10"
46
46
+
style="background-color: {brandColor}"
47
47
+
>
48
48
+
<div
49
49
+
class="flex aspect-square max-h-full max-w-full items-center justify-center [&_svg]:size-full [&_svg]:max-w-60 [&_svg]:fill-white"
50
50
+
>
51
51
+
{@html platformsData.germ.svg}
52
52
+
</div>
53
53
+
</div>
54
54
+
55
55
+
{#if !isEditing}
56
56
+
<a href={dmUrl} target="_blank" rel="noopener noreferrer">
57
57
+
<div class="absolute inset-0 z-50"></div>
58
58
+
<span class="sr-only">Message me on Germ</span>
59
59
+
</a>
60
60
+
{/if}
61
61
+
{:else if isLoaded}
62
62
+
<div
63
63
+
class="text-base-500 dark:text-base-400 accent:text-white/70 flex h-full w-full items-center justify-center p-4 text-center text-sm"
64
64
+
>
65
65
+
Germ DM not available
66
66
+
</div>
67
67
+
{:else}
68
68
+
<div
69
69
+
class="text-base-500 dark:text-base-400 accent:text-white/70 flex h-full w-full items-center justify-center p-4 text-center text-sm"
70
70
+
>
71
71
+
Loading...
72
72
+
</div>
73
73
+
{/if}
+42
src/lib/cards/social/GermDMCard/index.ts
···
1
1
+
import { getRecord } from '$lib/atproto';
2
2
+
import type { CardDefinition } from '../../types';
3
3
+
import { platformsData } from '../BigSocialCard';
4
4
+
import GermDMCard from './GermDMCard.svelte';
5
5
+
6
6
+
const germ = platformsData.germ;
7
7
+
8
8
+
export const GermDMCardDefinition = {
9
9
+
type: 'germDM',
10
10
+
contentComponent: GermDMCard,
11
11
+
createNew: (card) => {
12
12
+
card.w = 2;
13
13
+
card.h = 2;
14
14
+
card.mobileW = 4;
15
15
+
card.mobileH = 4;
16
16
+
card.cardData.label = 'Message me';
17
17
+
},
18
18
+
loadData: async (_items, { did }) => {
19
19
+
try {
20
20
+
const record = await getRecord({
21
21
+
did,
22
22
+
collection: 'com.germnetwork.declaration',
23
23
+
rkey: 'self'
24
24
+
});
25
25
+
const value = record?.value;
26
26
+
if (!value?.messageMe) return null;
27
27
+
return {
28
28
+
messageMeUrl: value.messageMe.messageMeUrl,
29
29
+
showButtonTo: value.messageMe.showButtonTo
30
30
+
};
31
31
+
} catch {
32
32
+
return null;
33
33
+
}
34
34
+
},
35
35
+
defaultColor: 'transparent',
36
36
+
allowSetColor: false,
37
37
+
canHaveLabel: true,
38
38
+
name: 'DM on Germ',
39
39
+
keywords: ['germ', 'dm', 'message', 'chat', 'encrypted'],
40
40
+
groups: ['Social'],
41
41
+
icon: `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="size-4">${germ.svg.replace(/<svg[^>]*>/, '').replace(/<\/svg>/, '')}</svg>`
42
42
+
} as CardDefinition & { type: 'germDM' };
+3
-1
src/lib/website/Context.svelte
···
20
20
setAdditionalUserData(data.additionalData);
21
21
22
22
setCanEdit(
23
23
-
() => (dev && isEditing === true) || (user.isLoggedIn && user.profile?.did === data.did && isEditing === true)
23
23
+
() =>
24
24
+
(dev && isEditing === true) ||
25
25
+
(user.isLoggedIn && user.profile?.did === data.did && isEditing === true)
24
26
);
25
27
26
28
// svelte-ignore state_referenced_locally