your personal website on atproto - mirror blento.app
25
fork

Configure Feed

Select the types of activity you want to include in your feed.

at fix-formatting 97 lines 2.5 kB view raw
1<script lang="ts"> 2 import type { Item } from '$lib/types'; 3 import { onMount } from 'svelte'; 4 import { getAdditionalUserData, getDidContext, getHandleContext } from '$lib/website/context'; 5 import { CardDefinitionsByType } from '..'; 6 import AlbumArt from './AlbumArt.svelte'; 7 import { RelativeTime } from '@foxui/time'; 8 9 interface Artist { 10 artistName: string; 11 } 12 13 interface PlayValue { 14 releaseMbId?: string; 15 trackName: string; 16 playedTime?: string; 17 artists?: Artist[]; 18 originUrl?: string; 19 } 20 21 interface Play { 22 uri: string; 23 value: PlayValue; 24 } 25 26 let { item }: { item: Item } = $props(); 27 28 const data = getAdditionalUserData(); 29 // svelte-ignore state_referenced_locally 30 let feed = $state(data[item.cardType] as Play[] | undefined); 31 32 let did = getDidContext(); 33 let handle = getHandleContext(); 34 35 onMount(async () => { 36 if (feed) return; 37 38 feed = (await CardDefinitionsByType[item.cardType]?.loadData?.([], { 39 did, 40 handle 41 })) as Play[] | undefined; 42 43 data[item.cardType] = feed; 44 }); 45 46 function isNumeric(str: string) { 47 if (typeof str != 'string') return false; 48 return !isNaN(Number(str)) && !isNaN(parseFloat(str)); 49 } 50</script> 51 52{#snippet musicItem(play: Play)} 53 <div class="flex w-full items-center gap-3"> 54 <div class="size-10 shrink-0"> 55 <AlbumArt releaseMbId={play.value.releaseMbId} alt="" /> 56 </div> 57 <div class="min-w-0 flex-1"> 58 <div class="inline-flex w-full max-w-full justify-between gap-2"> 59 <div 60 class="text-accent-500 accent:text-accent-950 min-w-0 flex-1 shrink truncate font-semibold" 61 > 62 {play.value.trackName} 63 </div> 64 65 {#if play.value.playedTime} 66 <div class="shrink-0 text-xs"> 67 <RelativeTime 68 date={new Date( 69 isNumeric(play.value.playedTime) 70 ? parseInt(play.value.playedTime) * 1000 71 : play.value.playedTime 72 )} 73 locale="en-US" 74 /> ago 75 </div> 76 {:else} 77 <div></div> 78 {/if} 79 </div> 80 <div class="my-1 min-w-0 gap-2 truncate text-xs whitespace-nowrap"> 81 {(play?.value?.artists ?? []).map((a) => a.artistName).join(', ')} 82 </div> 83 </div> 84 </div> 85{/snippet} 86 87<div class="z-10 flex h-full w-full flex-col gap-4 overflow-y-scroll p-4"> 88 {#each feed ?? [] as play (play.uri)} 89 {#if play.value.originUrl} 90 <a href={play.value.originUrl} target="_blank" rel="noopener noreferrer" class="w-full"> 91 {@render musicItem(play)} 92 </a> 93 {:else} 94 {@render musicItem(play)} 95 {/if} 96 {/each} 97</div>