your personal website on atproto - mirror

Functional test of BlueskyTopEight

Woovie df440dec b20b24aa

+103
+45
src/lib/cards/BlueskyTopEight/BlueskyTopEightCard.svelte
··· 1 + <script lang="ts"> 2 + import { getAdditionalUserData } from '$lib/website/context'; 3 + import { AppBskyActorDefs } from '@atcute/bluesky'; 4 + 5 + import type { ContentComponentProps } from '../types'; 6 + 7 + let { item }: ContentComponentProps = $props(); 8 + 9 + const data = getAdditionalUserData(); 10 + 11 + // svelte-ignore state_referenced_locally 12 + const profiles = data[item.cardType][item.id] as AppBskyActorDefs.ProfileViewDetailed[]; 13 + </script> 14 + 15 + <div class="flex h-full flex-col justify-center-safe overflow-y-scroll p-4"> 16 + <div class="topEightTitle">favorite posters</div> 17 + <div class="topEightContainer"> 18 + {#each profiles as profile (profile.did)} 19 + <img 20 + class="topEightProfilePicture" 21 + src={profile.avatar} 22 + alt="Profile picture of {profile.handle}" 23 + /> 24 + {/each} 25 + </div> 26 + </div> 27 + 28 + <style scoped> 29 + .topEightTitle { 30 + line-height: 1.5rem; 31 + } 32 + 33 + .topEightContainer { 34 + flex-grow: 1; 35 + overflow: hidden; 36 + display: flex; 37 + flex-direction: row; 38 + flex-wrap: wrap; 39 + justify-content: space-evenly; 40 + } 41 + 42 + .topEightProfilePicture { 43 + padding: 0.5rem; 44 + } 45 + </style>
+20
src/lib/cards/BlueskyTopEight/SidebarItemBlueskyTopEightCard.svelte
··· 1 + <script lang="ts"> 2 + import { Button } from '@foxui/core'; 3 + 4 + let { onclick }: { onclick: () => void } = $props(); 5 + </script> 6 + 7 + <Button {onclick} variant="ghost" class="w-full justify-start"> 8 + <svg 9 + xmlns="http://www.w3.org/2000/svg" 10 + version="1.1" 11 + class="text-accent-600 dark:text-accent-400 size-4" 12 + viewBox="0 0 600 530" 13 + > 14 + <path 15 + d="m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z" 16 + fill="currentColor" 17 + /> 18 + </svg> 19 + Favorite Bluesky Posters 20 + </Button>
+38
src/lib/cards/BlueskyTopEight/index.ts
··· 1 + import { AtpBaseClient } from '@atproto/api'; 2 + import type { CardDefinition } from '../types'; 3 + import BlueskyTopEightCard from './BlueskyTopEightCard.svelte'; 4 + import SidebarItemBlueskyTopEightCard from './SidebarItemBlueskyTopEightCard.svelte'; 5 + 6 + export const BlueskyTopEightCardDefinition = { 7 + type: 'topEight', 8 + contentComponent: BlueskyTopEightCard, 9 + createNew: (card) => { 10 + card.cardType = 'topEight'; 11 + card.w = 8; 12 + card.mobileW = 8; 13 + card.h = 4; 14 + card.mobileH = 8; 15 + }, 16 + sidebarComponent: SidebarItemBlueskyTopEightCard, 17 + loadData: async (items, { did, handle, cache: undefined }) => { 18 + const agent = new AtpBaseClient({ service: 'https://api.bsky.app' }); 19 + 20 + const profiles: Record<string, Array<Object>> = {}; 21 + 22 + for (const card of items) { 23 + profiles[card.id] = []; 24 + for (const memberHandle of card.cardData.handles) { 25 + const profileDetails = await agent.app.bsky.actor.getProfile({ actor: memberHandle }) 26 + const data = profileDetails.data 27 + profiles[card.id].push({ 28 + did: data.did, 29 + handle: data.handle, 30 + displayName: data.displayName, 31 + avatar: data.avatar 32 + }) 33 + } 34 + } 35 + 36 + return profiles 37 + }, 38 + } as CardDefinition & { type: 'topEight' };