0x0x230x

Untitled

Jul 9th, 2025
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.95 KB | None | 0 0
  1. import { cn } from '@/utils/utils';
  2. import React, { memo } from 'react';
  3. import { Linking, ScrollView, TouchableOpacity, View } from 'react-native';
  4. import { ChannelCard } from './ChannelCard';
  5. import { PostCard } from './PostCard';
  6. import { ProfileCard } from './ProfileCard';
  7.  
  8. type Post = {
  9. text: string;
  10. author: {
  11. username: string;
  12. displayName: string;
  13. pfp: string;
  14. id: string;
  15. };
  16. platform: string;
  17. url?: string;
  18. photo?: string;
  19. };
  20.  
  21. type Profile = {
  22. id: string | number;
  23. username: string;
  24. displayName?: string;
  25. pfp?: string;
  26. url?: string;
  27. platform: string;
  28. };
  29.  
  30. type Channel = {
  31. name: string;
  32. description?: string;
  33. image_url?: string;
  34. };
  35.  
  36. type ActionParams = {
  37. post?: Post & { url?: string };
  38. profile?: Profile;
  39. profile_url?: string;
  40. channel?: Channel;
  41. channel_url: string;
  42. };
  43.  
  44. interface EmbeddedContentProps {
  45. actionParams?: ActionParams;
  46. platform: string;
  47. withoutLink?: boolean;
  48. withoutZIndex?: boolean;
  49. className?: string;
  50. }
  51.  
  52. export const EmbeddedContent = memo(
  53. ({
  54. actionParams,
  55. platform,
  56. withoutLink = false,
  57. withoutZIndex = false,
  58. className,
  59. }: EmbeddedContentProps) => {
  60. if (
  61. !actionParams?.post &&
  62. !actionParams?.profile &&
  63. !actionParams?.channel
  64. ) {
  65. return null;
  66. }
  67.  
  68. const openLink = (url: string) => {
  69. if (url) Linking.openURL(url);
  70. };
  71.  
  72. return (
  73. <View
  74. className={cn('gap-3 max-h-60 rounded-xl overflow-hidden', className)}
  75. >
  76. <ScrollView nestedScrollEnabled showsVerticalScrollIndicator={false}>
  77. {/* Post */}
  78. {actionParams.post &&
  79. (withoutLink ? (
  80. <PostCard
  81. post={actionParams.post}
  82. withoutZIndex={withoutZIndex}
  83. />
  84. ) : (
  85. <TouchableOpacity
  86. activeOpacity={0.85}
  87. onPress={() => openLink(actionParams.post?.url ?? '')}
  88. >
  89. <PostCard post={actionParams.post} />
  90. </TouchableOpacity>
  91. ))}
  92.  
  93. {/* Profile */}
  94. {actionParams.profile &&
  95. (withoutLink ? (
  96. <ProfileCard profile={actionParams.profile} platform={platform} />
  97. ) : (
  98. <TouchableOpacity
  99. activeOpacity={0.85}
  100. onPress={() => openLink(actionParams.profile_url ?? '')}
  101. >
  102. <ProfileCard
  103. profile={actionParams.profile}
  104. platform={platform}
  105. />
  106. </TouchableOpacity>
  107. ))}
  108.  
  109. {/* Channel */}
  110. {actionParams.channel &&
  111. (withoutLink ? (
  112. <ChannelCard
  113. channel={actionParams.channel}
  114. channelUrl={actionParams.channel_url}
  115. platform={platform}
  116. />
  117. ) : (
  118. <TouchableOpacity
  119. activeOpacity={0.85}
  120. onPress={() => openLink(actionParams.channel_url ?? '')}
  121. >
  122. <ChannelCard
  123. channel={actionParams.channel}
  124. channelUrl={actionParams.channel_url}
  125. platform={platform}
  126. />
  127. </TouchableOpacity>
  128. ))}
  129. </ScrollView>
  130. </View>
  131. );
  132. },
  133. );
  134.  
  135. EmbeddedContent.displayName = 'EmbeddedContent';
  136.  
  137. ------------------------------------------------------------------------------------------------------------------------
  138.  
  139.  
  140. import { Image } from 'expo-image';
  141. import React from 'react';
  142. import { Linking, Text, TouchableOpacity, View } from 'react-native';
  143. import { PlatformIcon } from '../PlatformIcon';
  144.  
  145. interface Profile {
  146. id: string | number;
  147. username: string;
  148. displayName?: string;
  149. pfp?: string;
  150. url?: string;
  151. platform: string;
  152. }
  153.  
  154. interface ProfileCardProps {
  155. profile: Profile;
  156. platform?: string;
  157. className?: string;
  158. }
  159.  
  160. export const ProfileCard = ({
  161. profile,
  162. platform,
  163. className,
  164. }: ProfileCardProps) => {
  165. const fallbackInitial = (
  166. profile.displayName?.[0] || profile.username[0]
  167. ).toUpperCase();
  168.  
  169. const _platform = platform || profile.platform;
  170.  
  171. const profileUrl =
  172. profile.url ||
  173. `https://${_platform === 'x' ? 'x.com' : 'farcaster.xyz'}/${
  174. profile.username
  175. }`;
  176.  
  177. const openProfile = () => Linking.openURL(profileUrl);
  178.  
  179. return (
  180. <TouchableOpacity
  181. onPress={openProfile}
  182. activeOpacity={0.85}
  183. className={`relative flex-row items-start gap-3 p-3 rounded-lg border border-[#2c2d2e] bg-[#131314] overflow-hidden ${
  184. className ?? ''
  185. }`}
  186. >
  187. {/* Gradient border hover effect substitute */}
  188. <View className='absolute inset-0 rounded-lg border border-[#2c2d2e] opacity-0' />
  189.  
  190. {/* Avatar */}
  191. <View className='w-11 h-11 rounded-full border border-[#2c2d2e] bg-[#2c2d2e] items-center justify-center overflow-hidden'>
  192. {profile.pfp ? (
  193. <Image
  194. source={{ uri: profile.pfp }}
  195. className='w-full h-full rounded-full'
  196. contentFit='cover'
  197. priority='high'
  198. />
  199. ) : (
  200. <Text className='text-white text-lg font-semibold'>
  201. {fallbackInitial}
  202. </Text>
  203. )}
  204. </View>
  205.  
  206. {/* Info & platform icon */}
  207. <View className='flex-1 flex-row items-start justify-between min-w-0'>
  208. <View className='flex flex-col max-w-[calc(100%-40px)]'>
  209. <Text numberOfLines={1} className='text-sm font-medium text-primary'>
  210. {profile.displayName || `@${profile.username}`}
  211. </Text>
  212. <Text numberOfLines={1} className='text-xs text-[#454647]'>
  213. @{profile.username}
  214. </Text>
  215. </View>
  216.  
  217. <PlatformIcon platform={_platform} size={16} onPress={openProfile} />
  218. </View>
  219. </TouchableOpacity>
  220. );
  221. };
  222.  
Advertisement
Add Comment
Please, Sign In to add comment