From 5c8b0295a9a4ff00478932d4b207a340d271be7e Mon Sep 17 00:00:00 2001 From: Grisha Date: Wed, 6 May 2026 20:26:46 -0400 Subject: [PATCH] feat(widgets): adds Bufo Status zzstoatzz widget --- src/lib/cards/index.ts | 4 +- .../BufoStatusCard/BufoStatusCard.svelte | 70 +++++++++++++++++++ src/lib/cards/social/BufoStatusCard/index.ts | 58 +++++++++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/lib/cards/social/BufoStatusCard/BufoStatusCard.svelte create mode 100644 src/lib/cards/social/BufoStatusCard/index.ts diff --git a/src/lib/cards/index.ts b/src/lib/cards/index.ts index 6be995c..7c9b775 100644 --- a/src/lib/cards/index.ts +++ b/src/lib/cards/index.ts @@ -64,6 +64,7 @@ import { KichRecipeCollectionCardDefinition } from './social/KichRecipeCollectio import { KichCookingLogCardDefinition } from './social/KichCookingLogCard'; import { SecretImageCardDefinition } from './media/SecretImageCard'; import { RPGActorCardDefinition } from './social/RPGActorCard'; +import { BufoStatusCardDefinition } from './social/BufoStatusCard'; // import { Model3DCardDefinition } from './visual/Model3DCard'; export const AllCardDefinitions = [ @@ -133,7 +134,8 @@ export const AllCardDefinitions = [ KichRecipeCollectionCardDefinition, KichCookingLogCardDefinition, SecretImageCardDefinition, - RPGActorCardDefinition + RPGActorCardDefinition, + BufoStatusCardDefinition ] as const; export const CardDefinitionsByType = AllCardDefinitions.reduce( diff --git a/src/lib/cards/social/BufoStatusCard/BufoStatusCard.svelte b/src/lib/cards/social/BufoStatusCard/BufoStatusCard.svelte new file mode 100644 index 0000000..a46228d --- /dev/null +++ b/src/lib/cards/social/BufoStatusCard/BufoStatusCard.svelte @@ -0,0 +1,70 @@ + + + + {#if status} + {#if emojiName} + {emojiName} + {:else} + {status.emoji} + {/if} + {#if status.text} +

{status.text}

+ {/if} + {:else if loaded} + No active status + {:else} + Loading… + {/if} + bufo status +
diff --git a/src/lib/cards/social/BufoStatusCard/index.ts b/src/lib/cards/social/BufoStatusCard/index.ts new file mode 100644 index 0000000..9315679 --- /dev/null +++ b/src/lib/cards/social/BufoStatusCard/index.ts @@ -0,0 +1,58 @@ +import type { CardDefinition } from '../../types'; +import { listRecords } from '$lib/atproto'; +import BufoStatusCard from './BufoStatusCard.svelte'; + +interface StatusRecord { + emoji: string; + text?: string; + expires?: string; + createdAt: string; +} + +export type BufoStatusData = { + emoji: string; + text?: string; + rkey: string; +} | null; + +export const BufoStatusCardDefinition = { + type: 'bufoStatus', + contentComponent: BufoStatusCard, + + createNew: (item) => { + item.w = 2; + item.h = 2; + item.mobileW = 4; + item.mobileH = 2; + }, + + loadData: async (_items, { did }) => { + const records = await listRecords({ + did, + collection: 'io.zzstoatzz.status.record', + limit: 10 + }); + + const now = Date.now(); + const active = records + .map((r) => { + const parts = r.uri.split('/'); + const rkey = parts[parts.length - 1] ?? ''; + const value = r.value as unknown as StatusRecord; + return { ...value, rkey }; + }) + .filter((r) => r.emoji && r.rkey && (!r.expires || new Date(r.expires).getTime() > now)) + .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); + + return active[0] ?? null; + }, + cacheLoadData: { ttl: 300 }, + + minW: 2, + minH: 1, + + name: 'Bufo Status', + keywords: ['bufo', 'status', 'emoji', 'mood', 'zzstoatzz'], + groups: ['Social'], + icon: `` +} as CardDefinition & { type: 'bufoStatus' }; -- 2.51.2