Your music, beautifully tracked. All yours. (coming soon) teal.fm
teal-fm atproto

add actor play view

+34 -31
+1 -1
apps/amethyst/app/(tabs)/_layout.tsx
··· 24 return ( 25 <Tabs 26 screenOptions={{ 27 - title: "Tab One", 28 tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint, 29 // Disable the static render of the header on web 30 // to prevent a hydration error in
··· 24 return ( 25 <Tabs 26 screenOptions={{ 27 + title: "Home", 28 tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint, 29 // Disable the static render of the header on web 30 // to prevent a hydration error in
+10 -27
apps/amethyst/app/(tabs)/index.tsx
··· 1 import * as React from "react"; 2 - import { ActivityIndicator, View } from "react-native"; 3 import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; 4 import { CardHeader, CardTitle } from "../../components/ui/card"; 5 import { Text } from "@/components/ui/text"; 6 import { useStore } from "@/stores/mainStore"; 7 import AuthOptions from "../auth/options"; 8 9 - import { Response } from "@atproto/api/src/client/types/app/bsky/actor/getProfile"; 10 import { Stack } from "expo-router"; 11 import ActorPlaysView from "@/components/play/actorPlaysView"; 12 ··· 14 "https://i.pinimg.com/originals/ef/a2/8d/efa28d18a04e7fa40ed49eeb0ab660db.jpg"; 15 16 export default function Screen() { 17 - const [profile, setProfile] = React.useState<Response | null>(null); 18 const j = useStore((state) => state.status); 19 // @me 20 const agent = useStore((state) => state.pdsAgent); 21 - const isReady = useStore((state) => state.isAgentReady); 22 - React.useEffect(() => { 23 - if (agent) { 24 - agent 25 - .getProfile({ actor: agent.did ?? "teal.fm" }) 26 - .then((profile) => { 27 - console.log(profile); 28 - return setProfile(profile); 29 - }) 30 - .catch((e) => { 31 - console.log(e); 32 - }); 33 - } else { 34 - console.log("No agent"); 35 - } 36 - }, [isReady, agent]); 37 38 if (j !== "loggedIn") { 39 return <AuthOptions />; ··· 49 } 50 51 return ( 52 - <View className="flex-1 justify-start items-start gap-5 p-6 bg-background"> 53 <Stack.Screen 54 options={{ 55 title: "Home", ··· 60 <CardHeader className="items-start pb-0"> 61 <Avatar alt="Rick Sanchez's Avatar" className="w-24 h-24"> 62 <AvatarImage 63 - source={{ uri: profile?.data.avatar ?? GITHUB_AVATAR_URI }} 64 /> 65 <AvatarFallback> 66 <Text> 67 - {profile?.data.displayName?.substring(0, 1) ?? " Richard"} 68 </Text> 69 </AvatarFallback> 70 </Avatar> 71 <View className="px-3" /> 72 <CardTitle className="text-center"> 73 - {profile?.data.displayName ?? " Richard"} 74 </CardTitle> 75 {profile 76 - ? profile.data?.description?.split("\n").map((str, i) => ( 77 <Text className="text-start self-start place-self-start" key={i}> 78 {str} 79 </Text> 80 )) || "A very mysterious person" 81 : "Loading..."} 82 </CardHeader> 83 - <View className="max-w-xl w-full gap-2 pl-6"> 84 <Text className="text-left text-3xl font-serif">Your Stamps</Text> 85 - <ActorPlaysView repo={profile.data.did} /> 86 </View> 87 - </View> 88 ); 89 }
··· 1 import * as React from "react"; 2 + import { ActivityIndicator, ScrollView, View } from "react-native"; 3 import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; 4 import { CardHeader, CardTitle } from "../../components/ui/card"; 5 import { Text } from "@/components/ui/text"; 6 import { useStore } from "@/stores/mainStore"; 7 import AuthOptions from "../auth/options"; 8 9 import { Stack } from "expo-router"; 10 import ActorPlaysView from "@/components/play/actorPlaysView"; 11 ··· 13 "https://i.pinimg.com/originals/ef/a2/8d/efa28d18a04e7fa40ed49eeb0ab660db.jpg"; 14 15 export default function Screen() { 16 const j = useStore((state) => state.status); 17 // @me 18 const agent = useStore((state) => state.pdsAgent); 19 + const profile = useStore((state) => state.profiles[agent?.did ?? ""]); 20 21 if (j !== "loggedIn") { 22 return <AuthOptions />; ··· 32 } 33 34 return ( 35 + <ScrollView className="flex-1 justify-start items-start gap-5 p-6 bg-background"> 36 <Stack.Screen 37 options={{ 38 title: "Home", ··· 43 <CardHeader className="items-start pb-0"> 44 <Avatar alt="Rick Sanchez's Avatar" className="w-24 h-24"> 45 <AvatarImage 46 + source={{ uri: profile.bsky?.avatar ?? GITHUB_AVATAR_URI }} 47 /> 48 <AvatarFallback> 49 <Text> 50 + {profile.bsky?.displayName?.substring(0, 1) ?? " Richard"} 51 </Text> 52 </AvatarFallback> 53 </Avatar> 54 <View className="px-3" /> 55 <CardTitle className="text-center"> 56 + {profile.bsky?.displayName ?? " Richard"} 57 </CardTitle> 58 {profile 59 + ? profile.bsky?.description?.split("\n").map((str, i) => ( 60 <Text className="text-start self-start place-self-start" key={i}> 61 {str} 62 </Text> 63 )) || "A very mysterious person" 64 : "Loading..."} 65 </CardHeader> 66 + <View className="max-w-xl w-full gap-2 pl-6 pt-6"> 67 <Text className="text-left text-3xl font-serif">Your Stamps</Text> 68 + <ActorPlaysView repo={agent?.did} /> 69 </View> 70 + </ScrollView> 71 ); 72 }
+3 -3
apps/amethyst/components/play/actorPlaysView.tsx
··· 1 import { useStore } from "@/stores/mainStore"; 2 import { Record as Play } from "@teal/lexicons/src/types/fm/teal/alpha/feed/play"; 3 import { useEffect, useState } from "react"; 4 - import { View, Text, ScrollView } from "react-native"; 5 import PlayView from "./playView"; 6 interface ActorPlaysViewProps { 7 - repo: string; 8 } 9 interface PlayWrapper { 10 cid: string; ··· 39 return ( 40 <ScrollView className="w-full *:gap-4"> 41 {play.map((p) => ( 42 - <PlayView play={p.value} /> 43 ))} 44 </ScrollView> 45 );
··· 1 import { useStore } from "@/stores/mainStore"; 2 import { Record as Play } from "@teal/lexicons/src/types/fm/teal/alpha/feed/play"; 3 import { useEffect, useState } from "react"; 4 + import { Text, ScrollView } from "react-native"; 5 import PlayView from "./playView"; 6 interface ActorPlaysViewProps { 7 + repo: string | undefined; 8 } 9 interface PlayWrapper { 10 cid: string; ··· 39 return ( 40 <ScrollView className="w-full *:gap-4"> 41 {play.map((p) => ( 42 + <PlayView key={p.uri} play={p.value} /> 43 ))} 44 </ScrollView> 45 );
+20
apps/amethyst/global.css
··· 62 .var-font-soft { 63 font-variation-settings: "SOFT" 100; 64 }
··· 62 .var-font-soft { 63 font-variation-settings: "SOFT" 100; 64 } 65 + 66 + @supports not selector(::-webkit-scrollbar) { 67 + scrollbar-color: rgba(0, 0, 0, 0.8) transparent; 68 + scrollbar-width: thin; 69 + } 70 + 71 + ::-webkit-scrollbar { 72 + width: 7px; 73 + } 74 + ::-webkit-scrollbar-track { 75 + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 76 + } 77 + ::-webkit-scrollbar-thumb { 78 + background-color: darkslategray; 79 + outline: 1px solid slategrey; 80 + border-radius: 99px; 81 + } 82 + ::webkit-scrollbar-thumb:hover { 83 + background-color: slategray; 84 + }