import { Image } from 'expo-image'; import { Linking, Pressable, StyleSheet, Text, View } from 'react-native'; import { openUrl, timeAgo, type ProfileDTO, type RecentPlayDTO, type StreamingService } from '@musicshare/shared'; import { showError } from '@/lib/errors'; import { colors, radius, space } from '@/lib/theme'; import { Card, Heading } from './ui'; export function RecentPlays({ plays, preferred, attribution = {}, }: { plays: RecentPlayDTO[]; preferred: StreamingService | null | undefined; attribution?: ProfileDTO['attribution']; }) { const credits = (['lastfm', 'listenbrainz'] as const).filter((s) => attribution[s] && plays.some((p) => p.source === s)); if (plays.length === 0) return null; return ( Recently played {plays.map((p, i) => ( preferred && Linking.openURL(openUrl(p.track, preferred).url).catch((e) => showError(e, "Couldn't open link"))} style={({ pressed }) => [styles.row, i > 0 && styles.divider, pressed && { opacity: 0.6 }]}> {p.track.artworkUrl ? ( ) : ( ♪ )} {p.track.title} {p.track.artist} {timeAgo(p.playedAt)} ))} {credits.map((s) => ( Linking.openURL(attribution[s]!)}> Some plays via {s === 'lastfm' ? 'Last.fm' : 'ListenBrainz'} ))} ); } const styles = StyleSheet.create({ row: { flexDirection: 'row', alignItems: 'center', gap: space.md, paddingVertical: space.sm }, divider: { borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: colors.border }, art: { width: 40, height: 40, borderRadius: radius.sm, backgroundColor: colors.surface2 }, artEmpty: { alignItems: 'center', justifyContent: 'center' }, title: { color: colors.text, fontWeight: '600', fontSize: 14 }, artist: { color: colors.muted, fontSize: 13 }, time: { color: colors.muted, fontSize: 12 }, credit: { color: colors.muted, fontSize: 12, marginTop: space.sm }, });