your personal website on atproto - mirror
blento.app
1// animated emojis from
2// https://googlefonts.github.io/noto-emoji-animation/
3
4import type { CardDefinition } from '../../types';
5import { listRecords, putRecord } from '$lib/atproto';
6import StatusphereCard from './StatusphereCard.svelte';
7import EditStatusphereCard from './EditStatusphereCard.svelte';
8import icons from './icons.json';
9import * as TID from '@atcute/tid';
10
11export const StatusphereCardDefinition = {
12 type: 'statusphere',
13 contentComponent: StatusphereCard,
14 editingContentComponent: EditStatusphereCard,
15
16 createNew: (item) => {},
17
18 loadData: async (items, { did }) => {
19 const data = await listRecords({ did, collection: 'xyz.statusphere.status', limit: 1 });
20
21 return data[0];
22 },
23 upload: async (item) => {
24 if (item.cardData.hasUpdate) {
25 await putRecord({
26 rkey: TID.now(),
27 collection: 'xyz.statusphere.status',
28 record: {
29 status: item.cardData.emoji,
30 createdAt: new Date().toISOString()
31 }
32 });
33 delete item.cardData.hasUpdate;
34 // Keep item.cardData.emoji so each card can have its own status
35 }
36
37 return item;
38 },
39
40 migrate: (item) => {
41 if (item.cardData.title && !item.cardData.label) {
42 item.cardData.label = item.cardData.title;
43 }
44 },
45 canHaveLabel: true,
46
47 name: 'Emoji',
48 keywords: ['status', 'mood', 'reaction', 'statusphere'],
49 groups: ['Media'],
50 icon: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-4"><path stroke-linecap="round" stroke-linejoin="round" d="M15.182 15.182a4.5 4.5 0 0 1-6.364 0M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0ZM9.75 9.75c0 .414-.168.75-.375.75S9 10.164 9 9.75 9.168 9 9.375 9s.375.336.375.75Zm-.375 0h.008v.015h-.008V9.75Zm5.625 0c0 .414-.168.75-.375.75s-.375-.336-.375-.75.168-.75.375-.75.375.336.375.75Zm-.375 0h.008v.015h-.008V9.75Z" /></svg>`
51} as CardDefinition & { type: 'statusphere' };
52
53export function emojiToNotoAnimatedWebp(emoji: string | undefined): string | undefined {
54 if (!emoji) return;
55 // Convert emoji to lowercase hex codepoints joined by "-"
56 const codepoints: string[] = [];
57 for (const char of emoji) {
58 codepoints.push(char.codePointAt(0)!.toString(16).toLowerCase());
59 }
60
61 let key = codepoints.join('_');
62
63 if (icons.icons.find((v) => v.codepoint == key)) {
64 return `https://fonts.gstatic.com/s/e/notoemoji/latest/${key}/512.webp`;
65 }
66
67 key = codepoints.filter((cp) => cp !== 'fe0f' && cp !== 'fe0e').join('_');
68 if (icons.icons.find((v) => v.codepoint == key))
69 return `https://fonts.gstatic.com/s/e/notoemoji/latest/${key}/512.webp`;
70}