be-components 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/lib/commonjs/Components/Icons.js +144 -0
  2. package/lib/commonjs/Components/Icons.js.map +1 -1
  3. package/lib/commonjs/MarketComponents/components/TeamEventMarket/api/index.js +1 -1
  4. package/lib/commonjs/MarketComponents/components/TeamEventMarket/api/index.js.map +1 -1
  5. package/lib/commonjs/SocialComponents/PlayerCard.js +7 -6
  6. package/lib/commonjs/SocialComponents/PlayerCard.js.map +1 -1
  7. package/lib/commonjs/SocialComponents/PlayerList.js +1 -0
  8. package/lib/commonjs/SocialComponents/PlayerList.js.map +1 -1
  9. package/lib/commonjs/SocialComponents/PlayerProfile/api/index.js +149 -0
  10. package/lib/commonjs/SocialComponents/PlayerProfile/api/index.js.map +1 -0
  11. package/lib/commonjs/SocialComponents/PlayerProfile/components/PlayerFollowersList.js +138 -0
  12. package/lib/commonjs/SocialComponents/PlayerProfile/components/PlayerFollowersList.js.map +1 -0
  13. package/lib/commonjs/SocialComponents/PlayerProfile/components/PostsList.js +94 -0
  14. package/lib/commonjs/SocialComponents/PlayerProfile/components/PostsList.js.map +1 -0
  15. package/lib/commonjs/SocialComponents/PlayerProfile/index.js +501 -0
  16. package/lib/commonjs/SocialComponents/PlayerProfile/index.js.map +1 -0
  17. package/lib/commonjs/SocialComponents/PostCard/components/DraftTextEntities.js +36 -0
  18. package/lib/commonjs/SocialComponents/PostCard/components/DraftTextEntities.js.map +1 -0
  19. package/lib/commonjs/SocialComponents/PostCard/components/DraftTextViewer.js +59 -0
  20. package/lib/commonjs/SocialComponents/PostCard/components/DraftTextViewer.js.map +1 -0
  21. package/lib/commonjs/SocialComponents/PostCard/components/EntityHelpers.js +52 -0
  22. package/lib/commonjs/SocialComponents/PostCard/components/EntityHelpers.js.map +1 -0
  23. package/lib/commonjs/SocialComponents/PostCard/components/PostHeader.js +47 -0
  24. package/lib/commonjs/SocialComponents/PostCard/components/PostHeader.js.map +1 -0
  25. package/lib/commonjs/SocialComponents/PostCard/components/PostReactionBar.js +113 -0
  26. package/lib/commonjs/SocialComponents/PostCard/components/PostReactionBar.js.map +1 -0
  27. package/lib/commonjs/SocialComponents/PostCard/index.js +124 -0
  28. package/lib/commonjs/SocialComponents/PostCard/index.js.map +1 -0
  29. package/lib/commonjs/SocialComponents/SocialOrderCard.js +115 -0
  30. package/lib/commonjs/SocialComponents/SocialOrderCard.js.map +1 -0
  31. package/lib/commonjs/SocialComponents/SocialOrdersList.js +96 -0
  32. package/lib/commonjs/SocialComponents/SocialOrdersList.js.map +1 -0
  33. package/lib/commonjs/SocialComponents/api/index.js +204 -1
  34. package/lib/commonjs/SocialComponents/api/index.js.map +1 -1
  35. package/lib/commonjs/SocialComponents/index.js +7 -0
  36. package/lib/commonjs/SocialComponents/index.js.map +1 -1
  37. package/lib/module/Components/Icons.js +144 -0
  38. package/lib/module/Components/Icons.js.map +1 -1
  39. package/lib/module/MarketComponents/components/TeamEventMarket/api/index.js +1 -1
  40. package/lib/module/MarketComponents/components/TeamEventMarket/api/index.js.map +1 -1
  41. package/lib/module/SocialComponents/PlayerCard.js +7 -6
  42. package/lib/module/SocialComponents/PlayerCard.js.map +1 -1
  43. package/lib/module/SocialComponents/PlayerList.js +1 -0
  44. package/lib/module/SocialComponents/PlayerList.js.map +1 -1
  45. package/lib/module/SocialComponents/PlayerProfile/api/index.js +143 -0
  46. package/lib/module/SocialComponents/PlayerProfile/api/index.js.map +1 -0
  47. package/lib/module/SocialComponents/PlayerProfile/components/PlayerFollowersList.js +129 -0
  48. package/lib/module/SocialComponents/PlayerProfile/components/PlayerFollowersList.js.map +1 -0
  49. package/lib/module/SocialComponents/PlayerProfile/components/PostsList.js +86 -0
  50. package/lib/module/SocialComponents/PlayerProfile/components/PostsList.js.map +1 -0
  51. package/lib/module/SocialComponents/PlayerProfile/index.js +493 -0
  52. package/lib/module/SocialComponents/PlayerProfile/index.js.map +1 -0
  53. package/lib/module/SocialComponents/PostCard/components/DraftTextEntities.js +27 -0
  54. package/lib/module/SocialComponents/PostCard/components/DraftTextEntities.js.map +1 -0
  55. package/lib/module/SocialComponents/PostCard/components/DraftTextViewer.js +51 -0
  56. package/lib/module/SocialComponents/PostCard/components/DraftTextViewer.js.map +1 -0
  57. package/lib/module/SocialComponents/PostCard/components/EntityHelpers.js +41 -0
  58. package/lib/module/SocialComponents/PostCard/components/EntityHelpers.js.map +1 -0
  59. package/lib/module/SocialComponents/PostCard/components/PostHeader.js +40 -0
  60. package/lib/module/SocialComponents/PostCard/components/PostHeader.js.map +1 -0
  61. package/lib/module/SocialComponents/PostCard/components/PostReactionBar.js +104 -0
  62. package/lib/module/SocialComponents/PostCard/components/PostReactionBar.js.map +1 -0
  63. package/lib/module/SocialComponents/PostCard/index.js +115 -0
  64. package/lib/module/SocialComponents/PostCard/index.js.map +1 -0
  65. package/lib/module/SocialComponents/SocialOrderCard.js +108 -0
  66. package/lib/module/SocialComponents/SocialOrderCard.js.map +1 -0
  67. package/lib/module/SocialComponents/SocialOrdersList.js +87 -0
  68. package/lib/module/SocialComponents/SocialOrdersList.js.map +1 -0
  69. package/lib/module/SocialComponents/api/index.js +204 -1
  70. package/lib/module/SocialComponents/api/index.js.map +1 -1
  71. package/lib/module/SocialComponents/index.js +2 -1
  72. package/lib/module/SocialComponents/index.js.map +1 -1
  73. package/lib/typescript/src/Components/Icons.d.ts +5 -0
  74. package/lib/typescript/src/Components/Icons.d.ts.map +1 -1
  75. package/lib/typescript/src/SocialComponents/PlayerCard.d.ts +2 -1
  76. package/lib/typescript/src/SocialComponents/PlayerCard.d.ts.map +1 -1
  77. package/lib/typescript/src/SocialComponents/PlayerList.d.ts.map +1 -1
  78. package/lib/typescript/src/SocialComponents/PlayerProfile/api/index.d.ts +19 -0
  79. package/lib/typescript/src/SocialComponents/PlayerProfile/api/index.d.ts.map +1 -0
  80. package/lib/typescript/src/SocialComponents/PlayerProfile/components/PlayerFollowersList.d.ts +13 -0
  81. package/lib/typescript/src/SocialComponents/PlayerProfile/components/PlayerFollowersList.d.ts.map +1 -0
  82. package/lib/typescript/src/SocialComponents/PlayerProfile/components/PostsList.d.ts +9 -0
  83. package/lib/typescript/src/SocialComponents/PlayerProfile/components/PostsList.d.ts.map +1 -0
  84. package/lib/typescript/src/SocialComponents/PlayerProfile/index.d.ts +9 -0
  85. package/lib/typescript/src/SocialComponents/PlayerProfile/index.d.ts.map +1 -0
  86. package/lib/typescript/src/SocialComponents/PostCard/components/DraftTextEntities.d.ts +4 -0
  87. package/lib/typescript/src/SocialComponents/PostCard/components/DraftTextEntities.d.ts.map +1 -0
  88. package/lib/typescript/src/SocialComponents/PostCard/components/DraftTextViewer.d.ts +12 -0
  89. package/lib/typescript/src/SocialComponents/PostCard/components/DraftTextViewer.d.ts.map +1 -0
  90. package/lib/typescript/src/SocialComponents/PostCard/components/EntityHelpers.d.ts +12 -0
  91. package/lib/typescript/src/SocialComponents/PostCard/components/EntityHelpers.d.ts.map +1 -0
  92. package/lib/typescript/src/SocialComponents/PostCard/components/PostHeader.d.ts +9 -0
  93. package/lib/typescript/src/SocialComponents/PostCard/components/PostHeader.d.ts.map +1 -0
  94. package/lib/typescript/src/SocialComponents/PostCard/components/PostReactionBar.d.ts +11 -0
  95. package/lib/typescript/src/SocialComponents/PostCard/components/PostReactionBar.d.ts.map +1 -0
  96. package/lib/typescript/src/SocialComponents/PostCard/index.d.ts +11 -0
  97. package/lib/typescript/src/SocialComponents/PostCard/index.d.ts.map +1 -0
  98. package/lib/typescript/src/SocialComponents/SocialOrderCard.d.ts +13 -0
  99. package/lib/typescript/src/SocialComponents/SocialOrderCard.d.ts.map +1 -0
  100. package/lib/typescript/src/SocialComponents/SocialOrdersList.d.ts +9 -0
  101. package/lib/typescript/src/SocialComponents/SocialOrdersList.d.ts.map +1 -0
  102. package/lib/typescript/src/SocialComponents/api/index.d.ts +26 -2
  103. package/lib/typescript/src/SocialComponents/api/index.d.ts.map +1 -1
  104. package/lib/typescript/src/SocialComponents/index.d.ts +2 -1
  105. package/lib/typescript/src/SocialComponents/index.d.ts.map +1 -1
  106. package/package.json +5 -1
  107. package/src/Components/Icons.tsx +76 -0
  108. package/src/MarketComponents/components/TeamEventMarket/api/index.ts +1 -1
  109. package/src/SocialComponents/PlayerCard.tsx +6 -5
  110. package/src/SocialComponents/PlayerList.tsx +2 -1
  111. package/src/SocialComponents/PlayerProfile/api/index.ts +138 -0
  112. package/src/SocialComponents/PlayerProfile/components/PlayerFollowersList.tsx +111 -0
  113. package/src/SocialComponents/PlayerProfile/components/PostsList.tsx +92 -0
  114. package/src/SocialComponents/PlayerProfile/index.tsx +380 -0
  115. package/src/SocialComponents/PostCard/components/DraftTextEntities.tsx +25 -0
  116. package/src/SocialComponents/PostCard/components/DraftTextViewer.tsx +61 -0
  117. package/src/SocialComponents/PostCard/components/EntityHelpers.tsx +44 -0
  118. package/src/SocialComponents/PostCard/components/PostHeader.tsx +29 -0
  119. package/src/SocialComponents/PostCard/components/PostReactionBar.tsx +75 -0
  120. package/src/SocialComponents/PostCard/index.tsx +105 -0
  121. package/src/SocialComponents/SocialOrderCard.tsx +75 -0
  122. package/src/SocialComponents/SocialOrdersList.tsx +93 -0
  123. package/src/SocialComponents/api/index.ts +119 -4
  124. package/src/SocialComponents/index.tsx +3 -2
  125. package/src/types.d.ts +245 -0
@@ -0,0 +1,380 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { View, ActivityIndicator, Image, ScrollView, FlatList, TouchableOpacity, Linking } from 'react-native';
3
+ import type { OrderProps, PlayerFollowerProps, PlayerFollowerStatsProps, PlayerLinkProps, PublicPlayerProps } from '../../types';
4
+ import { SocialProfileApi } from './api';
5
+ import Colors from '../../constants/colors';
6
+ import { view_styles } from '../../constants/styles';
7
+ import { Button, Icons, Spring, Text } from '../../Components';
8
+ import PlayerCard from '../PlayerCard';
9
+ import PlayerFollowersList from './components/PlayerFollowersList';
10
+ import PostsList from './components/PostsList';
11
+ import SocialOrdersList from '../SocialOrdersList';
12
+
13
+ type PlayerProfileProps = {
14
+ viewing_player_id:string,
15
+ player_id?:string,
16
+ height?:number
17
+ }
18
+
19
+ const PlayerProfile = ({ viewing_player_id, player_id, height }:PlayerProfileProps) => {
20
+ const [ module_size, setModuleSize ] = useState({ height:755, width:330 });
21
+ const [ show_following, setShowFollowing ] = useState<{
22
+ visible:boolean,
23
+ status: 'following'|'followers'
24
+ }>({
25
+ visible: false,
26
+ status: 'following'
27
+ })
28
+ const [ my_data, setMyData ] = useState<{
29
+ me_loading:boolean,
30
+ player_follower?:PlayerFollowerProps
31
+ }>({
32
+ me_loading:false
33
+ });
34
+ const { player_follower } = my_data;
35
+
36
+ const [ activity_data, setActivityData ] = useState<{
37
+ activity_loading:boolean,
38
+ orders:OrderProps[],
39
+ activity_offset:number
40
+ }>({
41
+ activity_loading: false,
42
+ orders:[],
43
+ activity_offset: 0
44
+ });
45
+ const { orders } = activity_data;
46
+
47
+ const [ follow_data, setFollowData ] = useState<{
48
+ follow_loading:boolean,
49
+ player_followers:PlayerFollowerProps[],
50
+ players_following:PlayerFollowerProps[]
51
+ }>({
52
+ follow_loading: false,
53
+ player_followers: [],
54
+ players_following: []
55
+ });
56
+ const { follow_loading, player_followers, players_following } = follow_data;
57
+ const top_3_followers = player_followers.slice(0, 4);
58
+ const top_3_following = players_following.slice(0,4);
59
+ const [ profile_data, setData ] = useState<{
60
+ loading:boolean,
61
+ player?:PublicPlayerProps,
62
+ player_links:PlayerLinkProps[],
63
+ active_toggle:string,
64
+ player_follower_stats?:PlayerFollowerStatsProps
65
+ }>({
66
+ loading:false,
67
+ player_links:[],
68
+ active_toggle:'Posts'
69
+ });
70
+ const { player, active_toggle, player_links, player_follower_stats } = profile_data;
71
+
72
+ useEffect(() => {
73
+ SocialProfileApi.setEnvironment()
74
+ getDataFromServer()
75
+ getFollowDataFromServer();
76
+ },[]);
77
+
78
+ useEffect(() => {
79
+ if(!player_id){ return }
80
+ getMyDataFromServer(player_id)
81
+ },[player_id])
82
+
83
+ useEffect(() => {
84
+ switch(active_toggle){
85
+ case 'Activity':
86
+ getOrderData(0);
87
+ return
88
+ default: return
89
+ }
90
+ },[active_toggle])
91
+
92
+ const getOrderData = async(offset:number) => {
93
+ setActivityData({ ...activity_data, activity_loading: true });
94
+ const os = await SocialProfileApi.getOrdersByPlayerId(viewing_player_id, offset)
95
+ setActivityData({
96
+ ...activity_data,
97
+ activity_loading: false,
98
+ orders: os,
99
+ activity_offset: offset
100
+ })
101
+ }
102
+
103
+ const getDataFromServer = async() => {
104
+ setData({ ...profile_data, loading:true });
105
+ const p = await SocialProfileApi.getPlayerById(viewing_player_id)
106
+ const pl = await SocialProfileApi.getPlayerLinksByPlayerId(viewing_player_id);
107
+ const pfs = await SocialProfileApi.getFollowerStats(viewing_player_id);
108
+ setData({
109
+ ...profile_data,
110
+ loading:false,
111
+ player:p,
112
+ player_links:pl,
113
+ player_follower_stats: pfs
114
+ })
115
+ }
116
+
117
+ const getFollowDataFromServer = async() => {
118
+ setFollowData({ ...follow_data, follow_loading: true });
119
+ const followers = await SocialProfileApi.getPlayerFollowersByPlayerId(viewing_player_id, 'followers', 0);
120
+ const following = await SocialProfileApi.getPlayerFollowersByPlayerId(viewing_player_id, 'following', 0);
121
+
122
+ setFollowData({
123
+ ...follow_data,
124
+ follow_loading: false,
125
+ player_followers: followers,
126
+ players_following: following
127
+ })
128
+ }
129
+
130
+ const getMyDataFromServer = async(player_id:string) => {
131
+ setMyData({ ...my_data, me_loading:true });
132
+ const pf = await SocialProfileApi.getFollowerStatus(player_id, viewing_player_id);
133
+ setMyData({
134
+ ...my_data,
135
+ me_loading: false,
136
+ player_follower: pf
137
+ })
138
+ }
139
+
140
+ const renderToggles = (data:{ item:string, index:number }) => {
141
+ const active = data.item == active_toggle ? true : false
142
+ return (
143
+ <TouchableOpacity style={{ width: (module_size.width - 65) / 2, padding:15, borderRadius:22, backgroundColor:active?Colors.brand.midnight:'transparent' }}
144
+ onPress={() => setData({ ...profile_data, active_toggle: data.item })}>
145
+ <Text textAlign='center' weight='bold' size={14} color={active ?Colors.shades.white:Colors.brand.midnight}>{data.item}</Text>
146
+ </TouchableOpacity>
147
+ )
148
+ }
149
+ const renderFollowers = (data: { item:PlayerFollowerProps, index:number }) => {
150
+ if(!data.item.playerDetails){ return <></> }
151
+ return (
152
+ <View style={{ padding:4 }}>
153
+ <PlayerCard
154
+ player={data.item.playerDetails}
155
+ width={120}
156
+ border
157
+ alignment='vertical'
158
+ onSelectPlayer={() => console.log(data.item)}
159
+ onFollowingUpdate={(pf) => console.log(pf)}
160
+ />
161
+ </View>
162
+ )
163
+ }
164
+
165
+
166
+ const renderLinks = (data: { item:PlayerLinkProps, index:number }) => {
167
+ return (
168
+ <TouchableOpacity style={{ marginLeft:5, marginRight:5 }} onPress={() => Linking.openURL(data.item.link_full)}>
169
+ {data.item.link_type == 'twitter' ?
170
+ <Icons.TwitterIcon
171
+ size={30}
172
+ />
173
+ :data.item.link_type == 'custom' ?
174
+ <Icons.LinkIcon
175
+ color={Colors.brand.midnight}
176
+ size={30}
177
+ />
178
+ :data.item.link_type == 'linked_in' ?
179
+ <Icons.LinkedInIcon
180
+ size={30}
181
+ />
182
+ :<></>}
183
+ </TouchableOpacity>
184
+ )
185
+ }
186
+
187
+ if(!player){
188
+ return (
189
+ <ActivityIndicator
190
+ size='large'
191
+ style={{ padding:20, alignSelf:'center' }}
192
+ color={Colors.brand.midnight}
193
+ />
194
+ )
195
+ }
196
+
197
+ return (
198
+ <View style={{ flex:1 }} onLayout={(ev) => {
199
+ const { height, width } = ev.nativeEvent.layout
200
+ setModuleSize({ width, height });
201
+ }}>
202
+ <View style={{ position:'absolute', top:0, left:0, right:0 }} nativeID='profile_image'>
203
+ <Image
204
+ source={{ uri: player.profile_pic && player.profile_pic != '' ? player.profile_pic : 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
205
+ style={{ width: module_size.width, height: module_size.width, borderBottomRightRadius:50, borderBottomLeftRadius:50 }}
206
+ resizeMode='cover'
207
+ />
208
+ </View>
209
+ <ScrollView style={{ flex:1 }}>
210
+ <View style={{ ...view_styles.section, marginTop:module_size.width - 200 }}>
211
+ <View style={{ ...view_styles.section_header, borderBottomWidth:0 }}>
212
+ <View style={{ flex:1 }}>
213
+ <Text theme='header'>{player.first_name} {player.last_name}</Text>
214
+ <Text style={{ marginTop:4 }} theme='body_2'>@{player.username}</Text>
215
+ </View>
216
+ <Button
217
+ title={player_follower?.status == 'following' ? 'UNFOLLOW' : 'FOLLOW'}
218
+ backgroundColor={player_follower?.status == 'following' ? Colors.shades.white : Colors.brand.electric}
219
+ title_color={player_follower?.status == 'following' ? Colors.brand.electric : Colors.shades.white}
220
+ borderWidth={player_follower?.status == 'following' ? 1 : 0}
221
+ borderColor={player_follower?.status == 'following' ? Colors.brand.electric: 'transparent'}
222
+ onPress={() => console.log('FOLLOW')}
223
+ />
224
+ </View>
225
+
226
+ <View style={{ ...view_styles.section_body, padding:0 }}>
227
+ <View style={{ ...view_styles.body_row, padding:10, borderTopWidth:1, borderColor:Colors.shades.shade600 }}>
228
+ <Text theme='header_2' style={{flex:1}}>Engage With @{player.username}</Text>
229
+ <Icons.ChatIcon size={24} color={Colors.brand.midnight} />
230
+ </View>
231
+ <View style={{ padding:10, backgroundColor:Colors.shades.shade100 }}>
232
+ <Text theme='body'>{player.bio && player.bio != '' ? player.bio : `${player.username} has not set a bio.`}</Text>
233
+ </View>
234
+ </View>
235
+ {player_links.length > 0 ?
236
+ <View style={{ ...view_styles.section_footer }}>
237
+ <View style={{ flex:1 }}>
238
+ <Text theme='header_2'>Checkout my socials</Text>
239
+ </View>
240
+ <View style={{ alignSelf:'flex-end' }}>
241
+ <FlatList
242
+ data={player_links}
243
+ renderItem={renderLinks}
244
+ keyExtractor={(item) => item.player_link_id.toString()}
245
+ horizontal
246
+ />
247
+ </View>
248
+ </View>
249
+ :<></>}
250
+ </View>
251
+ <View style={{ ...view_styles.section }}>
252
+ <View style={{ ...view_styles.section_header }}>
253
+ <View style={{ flex:1 }}>
254
+ <Text theme='header'>Followers</Text>
255
+ <Text style={{ marginTop:3 }} theme='body_2'>Who is follwoing @{player.username}</Text>
256
+ </View>
257
+ <View style={{ padding:10 }}>
258
+ <Text theme='header_2'>{player_follower_stats?.follower_count ?? 0}</Text>
259
+ </View>
260
+ <Button
261
+ title='View All'
262
+ backgroundColor={Colors.brand.midnight}
263
+ title_color={Colors.shades.white}
264
+ onPress={() => setShowFollowing({ visible:true, status: 'followers' })}
265
+ />
266
+ </View>
267
+ <View style={view_styles.section_body}>
268
+ <View style={{ ...view_styles.body_row }}>
269
+ {follow_loading ?
270
+ <ActivityIndicator size={'large'} color={Colors.brand.midnight} />
271
+ :<></>}
272
+ <View style={{ flex:1 }}>
273
+ <FlatList
274
+ key='top_followers'
275
+ horizontal
276
+ showsHorizontalScrollIndicator={false}
277
+ data={top_3_followers}
278
+ renderItem={renderFollowers}
279
+ keyExtractor={(item) => item.player_follower_id.toString()}
280
+ />
281
+ </View>
282
+ </View>
283
+ </View>
284
+ </View>
285
+ <View style={{ ...view_styles.section }}>
286
+ <View style={{ ...view_styles.section_header }}>
287
+ <View style={{ flex:1 }}>
288
+ <Text theme='header'>Following</Text>
289
+ <Text style={{ marginTop:3 }} theme='body_2'>Who is @{player.username} following</Text>
290
+ </View>
291
+ <View style={{ padding:10 }}>
292
+ <Text theme='header_2'>{player_follower_stats?.following_count ?? 0}</Text>
293
+ </View>
294
+ <Button
295
+ title='View All'
296
+ backgroundColor={Colors.brand.midnight}
297
+ title_color={Colors.shades.white}
298
+ onPress={() => setShowFollowing({ visible:true, status: 'following' })}
299
+ />
300
+ </View>
301
+ <View style={view_styles.section_body}>
302
+ <View style={{ ...view_styles.body_row }}>
303
+ {follow_loading ?
304
+ <ActivityIndicator size={'large'} color={Colors.brand.midnight} />
305
+ :<></>}
306
+ <View style={{ flex:1 }}>
307
+ <FlatList
308
+ key='top_following'
309
+ showsHorizontalScrollIndicator={false}
310
+ horizontal
311
+ data={top_3_following}
312
+ renderItem={renderFollowers}
313
+ keyExtractor={(item) => item.player_follower_id.toString()}
314
+ />
315
+ </View>
316
+ </View>
317
+ </View>
318
+ </View>
319
+ <View style={{ ...view_styles.section }}>
320
+ <View style={{ ...view_styles.section_header }}>
321
+ <View style={{ flex:1 }}>
322
+ <Text theme='header'>Activity</Text>
323
+ <Text style={{ marginTop:3 }} theme='body_2'>Use the toggles below to see recent activity from @{player.username}</Text>
324
+ </View>
325
+ </View>
326
+ <View style={{ ...view_styles.section_body, padding:0 }}>
327
+ <View style={{ ...view_styles.body_row, margin:10, marginLeft:20, marginRight:20, borderRadius:22, padding:1, backgroundColor:Colors.shades.shade100 }}>
328
+ <FlatList
329
+ key={'toggles'}
330
+ horizontal
331
+ showsHorizontalScrollIndicator={false}
332
+ data={['Posts','Activity']}
333
+ renderItem={renderToggles}
334
+ keyExtractor={(item) => item}
335
+
336
+ />
337
+ </View>
338
+ {active_toggle == 'Posts' ?
339
+ <PostsList
340
+ viewing_player={player}
341
+ player_id={player_id}
342
+ />
343
+ :active_toggle == 'Activity' ?
344
+ <SocialOrdersList
345
+ orders={orders}
346
+ direction='vertical'
347
+ />
348
+ :<></>}
349
+
350
+ </View>
351
+ </View>
352
+ </ScrollView>
353
+ {show_following.visible ?
354
+ <View style={{ position:'absolute', top:0, left:0, right:0, bottom:0, backgroundColor:Colors.shades.black_faded }}>
355
+ <Spring
356
+ to={0}
357
+ from={500}
358
+ slide='vertical'
359
+ >
360
+ <PlayerFollowersList
361
+ height={height}
362
+ viewing_player={player}
363
+ player_id={player_id}
364
+ status={show_following.status}
365
+ total={show_following.status == 'followers' ? player_follower_stats?.follower_count : player_follower_stats?.following_count}
366
+ onClose={() => setShowFollowing({ ...show_following, visible:false })}
367
+ />
368
+ </Spring>
369
+ </View>
370
+ :<></>}
371
+ </View>
372
+ )
373
+ }
374
+
375
+ export default PlayerProfile
376
+
377
+
378
+ /*
379
+ <Text theme='body'>Joined in {moment(player.create_datetime).format('MMM YYYY')}</Text>
380
+ */
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { TouchableOpacity } from 'react-native';
3
+ import { Text } from '../../../Components';
4
+ import Colors from '../../../constants/colors';
5
+
6
+ export const rti_playerEntity = (props:any) => {
7
+ const entity = props.contentState.getEntity(props.entityKey).getData();
8
+ console.log(entity)
9
+ return (
10
+ <TouchableOpacity onPress={() => console.log('Go to profile')}>
11
+ <Text size={14} color={Colors.brand.electric} weight='semibold'>{props.children}</Text>
12
+ </TouchableOpacity>
13
+ )
14
+ }
15
+
16
+
17
+ export const rti_tagEntity = (props:any) => {
18
+ const entity = props.contentState.getEntity(props.entityKey).getData();
19
+ console.log(entity)
20
+ return (
21
+ <TouchableOpacity onPress={() => console.log('olah!')}>
22
+ <Text size={14} color={Colors.brand.electric} weight='semibold'>{props.children}</Text>
23
+ </TouchableOpacity>
24
+ )
25
+ }
@@ -0,0 +1,61 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { View } from 'react-native';
3
+ import { Editor, EditorState, convertFromRaw, CompositeDecorator } from 'draft-js';
4
+ import 'draft-js/dist/Draft.css';
5
+ import type { RawDraftJSProps } from '../../../types';
6
+ import { rti_playerEntity, rti_tagEntity } from './DraftTextEntities';
7
+ import { rti_findPlayerEntities, rti_findTagEntities, createDraftJSFromText } from './EntityHelpers';
8
+
9
+ type DraftTextViewerProps = {
10
+ post_id:string,
11
+ text_fallback: string,
12
+ formatted_body?: RawDraftJSProps,
13
+ view_type: 'memo'|'comment'|'message'
14
+ }
15
+
16
+ function DraftTextViewer({ post_id, formatted_body, text_fallback }:DraftTextViewerProps) {
17
+ const [ failed, setFailed ] = useState(false)
18
+ const [editorState, setEditorState] = useState(
19
+ () => EditorState.createEmpty(),
20
+ );
21
+
22
+ const decorator = new CompositeDecorator([
23
+ {
24
+ strategy: rti_findPlayerEntities,
25
+ component: rti_playerEntity,
26
+ props: { test: 'hey!' }
27
+ },
28
+ {
29
+ strategy: rti_findTagEntities,
30
+ component: rti_tagEntity,
31
+ props: { test: 'hey!' }
32
+ }
33
+ ]);
34
+
35
+
36
+ useEffect(() => {
37
+ if(formatted_body){
38
+ let readContent = convertFromRaw(formatted_body as any)
39
+ setEditorState(EditorState.createWithContent(readContent, decorator))
40
+ setFailed(false)
41
+ } else {
42
+ if(!text_fallback){ setFailed(true) }
43
+ else { setEditorState(EditorState.createWithContent(createDraftJSFromText(text_fallback))); setFailed(false) }
44
+ }
45
+ },[post_id, formatted_body, text_fallback])
46
+
47
+
48
+ if(failed){ return (<></>) }
49
+ return (
50
+ <View>
51
+ <Editor
52
+ readOnly
53
+ editorState={editorState}
54
+ onChange={setEditorState} />
55
+ </View>
56
+
57
+ )
58
+ }
59
+
60
+ export default DraftTextViewer
61
+
@@ -0,0 +1,44 @@
1
+ import { ContentState } from "draft-js";
2
+ import isUrl from "is-url";
3
+
4
+ export const rti_findPlayerEntities = (contentBlock:any, callback:any, contentState:any) => {
5
+ contentBlock.findEntityRanges(
6
+ (character:any) => {
7
+ const entityKey = character.getEntity();
8
+ return (
9
+ entityKey !== null &&
10
+ contentState.getEntity(entityKey).getType() === 'PLAYER'
11
+ );
12
+ },
13
+ callback
14
+ );
15
+ }
16
+
17
+
18
+ export const rti_findTagEntities = (contentBlock:any, callback:any, contentState:any) => {
19
+ contentBlock.findEntityRanges(
20
+ (character:any) => {
21
+ const entityKey = character.getEntity();
22
+ return (
23
+ entityKey !== null &&
24
+ contentState.getEntity(entityKey).getType() === 'TAG'
25
+ );
26
+ },
27
+ callback
28
+ );
29
+ }
30
+
31
+
32
+
33
+ type ValidatedURLType = { url:string, error:boolean, message?:string }
34
+ export const validateUrl = (url:string):ValidatedURLType => {
35
+ if(isUrl(url)){ return { url, error:false } }
36
+ let newURL = `https://${url}`
37
+ if(!isUrl(newURL)){ return { url, error:true, message: 'URL is not valid' } }
38
+ return { url:newURL, error:false }
39
+ }
40
+
41
+ export const createDraftJSFromText = (text:string) => {
42
+ if(text === '' || text === ' '){ return ContentState.createFromText('') }
43
+ return ContentState.createFromText(text)
44
+ }
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { Image, View } from 'react-native';
3
+ import { view_styles } from '../../../constants/styles';
4
+ import type { PostProps, PublicPlayerProps } from '../../../types';
5
+ import { Text } from '../../../Components';
6
+ import moment from 'moment-mini';
7
+
8
+ type PostHeaderProps = {
9
+ player: PublicPlayerProps,
10
+ post:PostProps
11
+ }
12
+
13
+ const PostHeader = ({ player, post }:PostHeaderProps) => {
14
+ return (
15
+ <View style={{ ...view_styles.section_header, padding:5 }}>
16
+ <Image
17
+ source={{ uri: player.profile_pic && player.profile_pic != '' ? player.profile_pic : 'https://res.cloudinary.com/hoabts6mc/image/upload/v1722453927/default_man_n96ofq.webp' }}
18
+ style={{ height:32, width:32, borderRadius:100 }}
19
+ resizeMode='cover'
20
+ />
21
+ <View style={{ flex:1, marginLeft:10 }}>
22
+ <Text theme='header_2'>{player.first_name} {player.last_name}</Text>
23
+ <Text style={{ marginTop:3 }} theme='body_2'>@{player.username} • {moment(post.create_datetime).fromNow()}</Text>
24
+ </View>
25
+ </View>
26
+ )
27
+ }
28
+
29
+ export default PostHeader
@@ -0,0 +1,75 @@
1
+ import React, { useState } from 'react';
2
+ import { FlatList, View, TouchableOpacity } from "react-native"
3
+ import type { PostReactionProps, PostReactionStatsProps } from '../../../types';
4
+ import { Button, Text } from '../../../Components';
5
+ import Colors from '../../../constants/colors';
6
+ import { view_styles } from '../../../constants/styles';
7
+
8
+ type PostReactionBarProps = {
9
+ post_reaction_stats: PostReactionStatsProps[],
10
+ my_post_reactions: PostReactionProps[],
11
+ featured?:boolean,
12
+ onReactionSelect: (reaction:string) => void
13
+ }
14
+
15
+ const available_reactions = [
16
+ { reaction: 'like', label: '❤️' },
17
+ { reaction: 'celebrate', label: '🎉' },
18
+ { reaction: 'fire', label: '🔥' },
19
+ { reaction: 'clap', label: '👏' },
20
+ { reaction: 'trophy', label: '🏆' },
21
+ { reaction: 'strong', label: '💪' },
22
+ { reaction: 'money', label: '💰' },
23
+ { reaction: 'eyes', label: '👀' },
24
+ ]
25
+
26
+ const PostReactionBar = ({ post_reaction_stats, my_post_reactions, onReactionSelect }:PostReactionBarProps) => {
27
+ const [ more_selected, setMoreSelected ] = useState(false);
28
+ const handleReaction = async(reaction:string) => {
29
+ if(!onReactionSelect){ return }
30
+ onReactionSelect(reaction)
31
+ setMoreSelected(false)
32
+ }
33
+
34
+ const renderAvailableReactions = (data: {item:any, index:number}) => {
35
+ const reacted = post_reaction_stats.length > 0 && !more_selected
36
+ const reaction_stat = post_reaction_stats.find(p => p.reaction === data.item.reaction)
37
+ const my_reaction = my_post_reactions.find(pr => pr.reaction === data.item.reaction)
38
+ const selected = my_reaction?.status === 'visible' ? true : false
39
+ return (
40
+ <TouchableOpacity style={
41
+ reacted ?
42
+ { ...view_styles.float, marginBottom:5, marginLeft:data.index===0?0:-5, paddingRight:10, paddingLeft:5, flexDirection:'row', alignItems:'center', padding:2, borderRadius:100, backgroundColor:selected?Colors.highlights.highlight200:Colors.shades.white }
43
+ :
44
+ {}} onPress={() => handleReaction(data.item.reaction)}>
45
+
46
+ <Text style={{fontSize:12, padding:6}}>{data.item.label}</Text>
47
+ {reaction_stat && !more_selected && post_reaction_stats.length < 5 ?
48
+ <Text size={12} color={selected ? Colors.shades.white : Colors.brand.midnight} weight='regular' style={{ padding:3 }}>{reaction_stat.reaction_count}</Text>
49
+ :<></>}
50
+ </TouchableOpacity>
51
+ )
52
+ }
53
+
54
+ let visible_reactions = available_reactions
55
+ if(post_reaction_stats.length > 0 && !more_selected){
56
+ visible_reactions = visible_reactions.filter(r => post_reaction_stats.find(pr => pr.reaction === r.reaction))
57
+ }
58
+ return (
59
+ <View style={{ flexDirection:'row', alignItems:'center' }}>
60
+ <FlatList key='reactions' data={visible_reactions} renderItem={renderAvailableReactions} keyExtractor={(item) => item.reaction} horizontal/>
61
+ {post_reaction_stats.length > 0 && !more_selected ?
62
+ <Button
63
+ title='MORE'
64
+ title_color={Colors.brand.electric}
65
+ title_size={10}
66
+ style={{ marginLeft:4 }}
67
+ padding={0}
68
+ onPress={() => setMoreSelected(true)}
69
+ />
70
+ :<></>}
71
+ </View>
72
+ )
73
+ }
74
+
75
+ export default PostReactionBar