be-components 5.1.0 → 5.1.1

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 (64) hide show
  1. package/lib/commonjs/ProfileManager/Components/VouchCard.js +6 -0
  2. package/lib/commonjs/ProfileManager/Components/VouchCard.js.map +1 -1
  3. package/lib/commonjs/SocialComponents/FormattedText.js +130 -0
  4. package/lib/commonjs/SocialComponents/FormattedText.js.map +1 -0
  5. package/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.js +137 -0
  6. package/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.js.map +1 -0
  7. package/lib/commonjs/SocialComponents/FormattedTextInput/index.js +150 -0
  8. package/lib/commonjs/SocialComponents/FormattedTextInput/index.js.map +1 -0
  9. package/lib/commonjs/SocialComponents/api/index.js +60 -4
  10. package/lib/commonjs/SocialComponents/api/index.js.map +1 -1
  11. package/lib/commonjs/SocialComponents/index.js +14 -0
  12. package/lib/commonjs/SocialComponents/index.js.map +1 -1
  13. package/lib/module/ProfileManager/Components/VouchCard.js +7 -1
  14. package/lib/module/ProfileManager/Components/VouchCard.js.map +1 -1
  15. package/lib/module/SocialComponents/FormattedText.js +120 -0
  16. package/lib/module/SocialComponents/FormattedText.js.map +1 -0
  17. package/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.js +129 -0
  18. package/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.js.map +1 -0
  19. package/lib/module/SocialComponents/FormattedTextInput/index.js +141 -0
  20. package/lib/module/SocialComponents/FormattedTextInput/index.js.map +1 -0
  21. package/lib/module/SocialComponents/api/index.js +60 -3
  22. package/lib/module/SocialComponents/api/index.js.map +1 -1
  23. package/lib/module/SocialComponents/index.js +3 -1
  24. package/lib/module/SocialComponents/index.js.map +1 -1
  25. package/lib/typescript/lib/commonjs/ProfileManager/Components/VouchCard.d.ts.map +1 -1
  26. package/lib/typescript/lib/commonjs/SocialComponents/FormattedText.d.ts +9 -0
  27. package/lib/typescript/lib/commonjs/SocialComponents/FormattedText.d.ts.map +1 -0
  28. package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +10 -0
  29. package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -0
  30. package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/index.d.ts +6 -0
  31. package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/index.d.ts.map +1 -0
  32. package/lib/typescript/lib/commonjs/SocialComponents/api/index.d.ts +6 -0
  33. package/lib/typescript/lib/commonjs/SocialComponents/api/index.d.ts.map +1 -1
  34. package/lib/typescript/lib/commonjs/SocialComponents/index.d.ts +6 -0
  35. package/lib/typescript/lib/module/ProfileManager/Components/VouchCard.d.ts.map +1 -1
  36. package/lib/typescript/lib/module/SocialComponents/FormattedText.d.ts +9 -0
  37. package/lib/typescript/lib/module/SocialComponents/FormattedText.d.ts.map +1 -0
  38. package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +12 -0
  39. package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -0
  40. package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/index.d.ts +6 -0
  41. package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/index.d.ts.map +1 -0
  42. package/lib/typescript/lib/module/SocialComponents/api/index.d.ts +6 -0
  43. package/lib/typescript/lib/module/SocialComponents/api/index.d.ts.map +1 -1
  44. package/lib/typescript/lib/module/SocialComponents/index.d.ts +3 -1
  45. package/lib/typescript/lib/module/SocialComponents/index.d.ts.map +1 -1
  46. package/lib/typescript/src/ProfileManager/Components/VouchCard.d.ts.map +1 -1
  47. package/lib/typescript/src/SocialComponents/FormattedText.d.ts +21 -0
  48. package/lib/typescript/src/SocialComponents/FormattedText.d.ts.map +1 -0
  49. package/lib/typescript/src/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +12 -0
  50. package/lib/typescript/src/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -0
  51. package/lib/typescript/src/SocialComponents/FormattedTextInput/index.d.ts +12 -0
  52. package/lib/typescript/src/SocialComponents/FormattedTextInput/index.d.ts.map +1 -0
  53. package/lib/typescript/src/SocialComponents/api/index.d.ts +8 -2
  54. package/lib/typescript/src/SocialComponents/api/index.d.ts.map +1 -1
  55. package/lib/typescript/src/SocialComponents/index.d.ts +3 -1
  56. package/lib/typescript/src/SocialComponents/index.d.ts.map +1 -1
  57. package/package.json +1 -1
  58. package/src/ProfileManager/Components/VouchCard.tsx +3 -2
  59. package/src/SocialComponents/FormattedText.tsx +126 -0
  60. package/src/SocialComponents/FormattedTextInput/components/TagSelector.tsx +105 -0
  61. package/src/SocialComponents/FormattedTextInput/index.tsx +143 -0
  62. package/src/SocialComponents/api/index.ts +48 -4
  63. package/src/SocialComponents/index.tsx +5 -0
  64. package/src/types.d.ts +11 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/SocialComponents/api/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAQxP,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAA;AAEvE,QAAA,MAAM,kBAAkB;;sBASA,OAAO,CAAC,WAAW,EAAE,CAAC;0BAQhB,UAAU,KAAE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;yCAQ5B,MAAM,EAAE;0CAIP,mBAAmB,KAAE,OAAO,CAAC,mBAAmB,CAAC;qCAItD,MAAM,EAAE,KAAE,OAAO,CAAC,UAAU,EAAE,CAAC;sCAS9B,MAAM,EAAE,KAAE,OAAO,CAAC,UAAU,EAAE,CAAC;oCAShC,MAAM,EAAE,KAAE,OAAO,CAAC,YAAY,EAAE,CAAC;oDASlB,MAAM,EAAE,KAAE,OAAO,CAAC,eAAe,EAAE,CAAC;8BAS1D,MAAM,EAAE;wCASE,iBAAiB,KAAE,OAAO,CAAC,iBAAiB,GAAC,SAAS,CAAC;wCAStD,iBAAiB,KAAE,OAAO,CAAC,iBAAiB,GAAC,SAAS,CAAC;iCAS/D,MAAM,KAAE,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;gDAQ1B,MAAM,KAAE,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;kDAS/C,MAAM,KAAE,OAAO,CAAC,SAAS,GAAG;QAAE,cAAc,CAAC,EAAC,kBAAkB,CAAC;QAAC,sBAAsB,CAAC,EAAC,yBAAyB,CAAA;KAAE,CAAC;8CAS1H,MAAM,KAAE,OAAO,CAAC,SAAS,GAAG;QAAE,cAAc,EAAC,kBAAkB,CAAC;QAAC,sBAAsB,EAAC,yBAAyB,CAAA;KAAE,CAAC;8CASrH,MAAM,mBAAkB,MAAM,KAAE,OAAO,CAAC,SAAS,GAAG,yBAAyB,CAAC;CAS9H,CAAA;AAGD,QAAA,MAAM,kBAAkB;0BACC,UAAU;8BAYN,UAAU;;;;kCAYN,MAAM,OAAM,MAAM;+BAWrB,UAAU,EAAE;;;;;;;+BAWZ,UAAU,UAAS,UAAU,EAAE,eAAc,eAAe,EAAE,WAAU,UAAU,EAAE,YAAW,YAAY,EAAE,SAAQ,SAAS,EAAE,WAAU,WAAW,EAAE,KAAE;QAAE,KAAK,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAC,MAAM,CAAC,EAAC,WAAW,CAAC;QAAC,OAAO,CAAC,EAAC,YAAY,CAAC;QAAC,IAAI,CAAC,EAAC,SAAS,CAAA;KAAE;yBAwBzP,MAAM,aAAY,MAAM;CAM/C,CAAA;AAED,QAAA,MAAM,oBAAoB;+BACI,YAAY,KAAE,MAAM;wCAMX,oBAAoB,KAAE,MAAM;uBAO7C,MAAM;2BAMF,MAAM,OAAM,MAAM,UAAS,MAAM;CAG1D,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/SocialComponents/api/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAQrR,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,CAAA;AAE/F,QAAA,MAAM,kBAAkB;;sBASA,OAAO,CAAC,WAAW,EAAE,CAAC;0BAQhB,UAAU,KAAE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;yCAQ5B,MAAM,EAAE;0CAIP,mBAAmB,KAAE,OAAO,CAAC,mBAAmB,CAAC;qCAItD,MAAM,EAAE,KAAE,OAAO,CAAC,UAAU,EAAE,CAAC;uCAS7B,MAAM,KAAE,OAAO,CAAC,iBAAiB,GAAC,SAAS,CAAC;yCAU1C,MAAM,UAAS,MAAM,KAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC;sCAQtD,MAAM,EAAE,KAAE,OAAO,CAAC,UAAU,EAAE,CAAC;oCAShC,MAAM,EAAE,KAAE,OAAO,CAAC,YAAY,EAAE,CAAC;oDASlB,MAAM,EAAE,KAAE,OAAO,CAAC,eAAe,EAAE,CAAC;8BAS1D,MAAM,EAAE;wCASE,iBAAiB,KAAE,OAAO,CAAC,iBAAiB,GAAC,SAAS,CAAC;wCAStD,iBAAiB,KAAE,OAAO,CAAC,iBAAiB,GAAC,SAAS,CAAC;iCAS/D,MAAM,KAAE,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;gDAQ1B,MAAM,KAAE,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;kDAS/C,MAAM,KAAE,OAAO,CAAC,SAAS,GAAG;QAAE,cAAc,CAAC,EAAC,kBAAkB,CAAC;QAAC,sBAAsB,CAAC,EAAC,yBAAyB,CAAA;KAAE,CAAC;8CAS1H,MAAM,KAAE,OAAO,CAAC,SAAS,GAAG;QAAE,cAAc,EAAC,kBAAkB,CAAC;QAAC,sBAAsB,EAAC,yBAAyB,CAAA;KAAE,CAAC;8CASrH,MAAM,mBAAkB,MAAM,KAAE,OAAO,CAAC,SAAS,GAAG,yBAAyB,CAAC;CAS9H,CAAA;AAGD,QAAA,MAAM,kBAAkB;0BACC,UAAU;8BAYN,UAAU;;;;kCAYN,MAAM,OAAM,MAAM;+BAWrB,UAAU,EAAE;;;;;;;+BAWZ,UAAU,UAAS,UAAU,EAAE,eAAc,eAAe,EAAE,WAAU,UAAU,EAAE,YAAW,YAAY,EAAE,SAAQ,SAAS,EAAE,WAAU,WAAW,EAAE,KAAE;QAAE,KAAK,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAC,MAAM,CAAC,EAAC,WAAW,CAAC;QAAC,OAAO,CAAC,EAAC,YAAY,CAAC;QAAC,IAAI,CAAC,EAAC,SAAS,CAAA;KAAE;yBAwBzP,MAAM,aAAY,MAAM;CAM/C,CAAA;AAED,QAAA,MAAM,sBAAsB;gCACG,MAAM,WAAU,MAAM,KAAE,QAAQ,EAAE;gCAkBlC,MAAM,cAAa,MAAM,YAAW,MAAM,mBAAkB,MAAM;CAKhG,CAAA;AAED,QAAA,MAAM,oBAAoB;+BACI,YAAY,KAAE,MAAM;wCAMX,oBAAoB,KAAE,MAAM;uBAO7C,MAAM;2BAMF,MAAM,OAAM,MAAM,UAAS,MAAM;CAG1D,CAAA"}
@@ -6,5 +6,7 @@ import PodcastModule from './PodcastModule';
6
6
  import AudioPlayer from "./AudioPlayer";
7
7
  import { useContacts } from "./Contacts/useContacts";
8
8
  import PostCard from './PostCard';
9
- export { PlayerCard, PlayerList, PlayerProfile, CompanyProfile, PodcastModule, AudioPlayer, useContacts, PostCard };
9
+ import FormattedTextInput from "./FormattedTextInput";
10
+ import { FormattedText } from "./FormattedText";
11
+ export { PlayerCard, PlayerList, FormattedTextInput, FormattedText, PlayerProfile, CompanyProfile, PodcastModule, AudioPlayer, useContacts, PostCard };
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/SocialComponents/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EACH,UAAU,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,EACX,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/SocialComponents/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EACH,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,EACX,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "be-components",
3
- "version": "5.1.0",
3
+ "version": "5.1.1",
4
4
  "description": "Components for BettorEdge Apps",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { TouchableOpacity, Image, Modal, Alert, FlatList, Platform } from 'react-native';
2
+ import { TouchableOpacity, Image, Modal, Alert, FlatList, Platform, useWindowDimensions } from 'react-native';
3
3
  import { Icons } from '../../Components';
4
4
  import Colors from '../../constants/colors';
5
5
  import { ProfileApi, ProfileHelpers } from '../api';
@@ -36,7 +36,7 @@ const VouchCard = ({ player, view_mode, walkthrough, insets, code_details, onVou
36
36
  const [ disclaimer_confirmed, setDisclaimerConfirmed ] = useState(false);
37
37
  const [ id_disclaimer_confirmed, setIDDisclaimerConfirmed ] = useState(false);
38
38
  const [ info_visible, setInfoVisible ] = useState(false);
39
-
39
+ const { height } = useWindowDimensions();
40
40
  const { code_request, promo } = code_details;
41
41
  useEffect(() => {
42
42
  getPlayerFromServer()
@@ -107,6 +107,7 @@ const VouchCard = ({ player, view_mode, walkthrough, insets, code_details, onVou
107
107
  const renderSections = (data:{item:string, index:number}) => {
108
108
  switch(data.item){
109
109
  case 'header':
110
+ if(height < 830){ return <></> }
110
111
  return (
111
112
  <View style={{ padding:20 }}>
112
113
  <Text size={30} theme='h1'>Help us identify you</Text>
@@ -0,0 +1,126 @@
1
+ import React from 'react';
2
+ import { Button, Text, View } from "../Components/Themed";
3
+ import type { TagProps } from '../types';
4
+
5
+ type FormattedTextProps = {
6
+ text: string,
7
+ tags:TagProps[],
8
+ onSelectTag: (tag:SelectedTagProps) => void
9
+ }
10
+
11
+ type SelectedTagProps = {
12
+ tag_character: string,
13
+ tag_type: 'player',
14
+ full_tag: string,
15
+ tag_target: string
16
+ }
17
+
18
+ export const FormattedText = ({ text, tags, onSelectTag }:FormattedTextProps) => {
19
+
20
+ const components = formatText(text, tags, onSelectTag);
21
+ let unique_lines = [ ...new Set(components.map(c => c.line)) ];
22
+
23
+ return (
24
+ <View transparent>
25
+ {unique_lines.map(l => {
26
+ let render_components = components.filter(c => c.line == l)
27
+ return (
28
+ <View transparent type='row' style={{ flexWrap:'wrap' }}>
29
+ {render_components.map(c => c.component)}
30
+ </View>
31
+ )
32
+ })}
33
+ </View>
34
+ )
35
+ }
36
+
37
+ export const splitTextByArray = (text:string, separators:string[]) => {
38
+ const regex = new RegExp(separators.join('|'), 'g');
39
+ return text.split(regex);
40
+ }
41
+
42
+ const getTagFromString = (tag:string):SelectedTagProps | undefined => {
43
+ let tag_character = tag.charAt(0);
44
+ let tag_target = tag.split(tag_character)[1]
45
+ if(!tag_target){ return undefined }
46
+ let full_tag = tag
47
+ let tag_type:'player' = 'player'
48
+ switch(tag_character){
49
+ case '@': tag_type = 'player'; break;
50
+ default: break
51
+ }
52
+ return {
53
+ tag_character,
54
+ tag_target,
55
+ full_tag,
56
+ tag_type
57
+ }
58
+
59
+ }
60
+
61
+ export const formatText = (text:string, included_tags:TagProps[], onSelectTag:(tag:SelectedTagProps) => void):{ line:number, component:any }[] => {
62
+ let raw_text = text.replace(/\\n/g, " {ln} ")
63
+ let parsed_text:string[] = JSON.parse(raw_text as string).split(' ');
64
+ //First - lets grab the line breaks
65
+ let line_breaks:number[] = []
66
+ parsed_text.map((t,i) => {
67
+ let breaks = t.split('{ln}');
68
+ if(breaks.length > 1){
69
+ line_breaks.push(i);
70
+ }
71
+ })
72
+
73
+ let components:{line:number, component:any}[] = []
74
+ let lines:{ [key:number]: string } = {}
75
+ let tags:{ [key:number]: string[] } = {}
76
+
77
+ //Second - Lets generate the lines and grab tags out of the lines
78
+ let curr_line = 0
79
+ parsed_text.map((t,i) => {
80
+ let line_break = line_breaks.find(b => b == i)
81
+ if(line_break){ curr_line += 1; return }
82
+ let curr_string = lines[curr_line] ?? ''
83
+ curr_string += `${t} `
84
+ lines[curr_line] = curr_string
85
+ let tag = t.split('@');
86
+ if(tag.length == 2){
87
+ let curr_tags = tags[curr_line] ?? []
88
+ tags[curr_line] = curr_tags.concat(t)
89
+ }
90
+ });
91
+
92
+ Object.values(lines).map((l,i) => {
93
+ let line_tags = tags[i] ?? [];
94
+ let split_line = splitTextByArray(l, line_tags);
95
+ split_line.map((sl, index) => {
96
+ components.push({
97
+ line: i,
98
+ component: <Text>{sl}</Text>
99
+ })
100
+ let tag = line_tags[index]
101
+ if(tag){
102
+ //Check if it is valid!
103
+ const included_tag = included_tags.find(t => t.tag == tag);
104
+ console.log(included_tag)
105
+ components.push({
106
+ line: i,
107
+ component: (
108
+ <Button
109
+ style={{ padding:0 }}
110
+ type='text'
111
+ transparent
112
+ title={tag}
113
+ onPress={() => {
114
+ if(!onSelectTag){ return }
115
+ let selected_tag = getTagFromString(tag)
116
+ if(!selected_tag){ return }
117
+ onSelectTag(selected_tag)
118
+ }}
119
+ />
120
+ )
121
+ })
122
+ }
123
+ })
124
+ })
125
+ return components
126
+ }
@@ -0,0 +1,105 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { Button, Text, View } from "../../../Components/Themed";
3
+ import type { PublicPlayerProps, TagProps } from '../../../types';
4
+ import { SocialComponentApi } from '../../api';
5
+ import { FlatList, Image } from 'react-native';
6
+
7
+ type TagSelectorProps = {
8
+ type: 'player',
9
+ visible:boolean,
10
+ working_tag:TagProps,
11
+ onCancel: () => void,
12
+ onSelectTag:(tag:TagProps) => void
13
+ }
14
+
15
+ const TagSelector = ({ type, visible, working_tag, onSelectTag, onCancel } : TagSelectorProps) => {
16
+ const [ player_tag, setPlayerTag ] = useState<{
17
+ loading:boolean,
18
+ players:PublicPlayerProps[],
19
+ offset:number
20
+ }>({
21
+ loading: false, players:[], offset:0
22
+ });
23
+
24
+
25
+ useEffect(() => {
26
+ if(!visible){ return }
27
+ startUpSelector(type, working_tag)
28
+ },[visible, working_tag]);
29
+
30
+ const startUpSelector = async(type:'player', working_tag:TagProps) => {
31
+ switch(type){
32
+ case 'player':
33
+ return searchPlayers(working_tag, 0);
34
+ default: return //Not handled
35
+ }
36
+ }
37
+
38
+ const searchPlayers = async(tag:TagProps, page:number) => {
39
+ setPlayerTag({ ...player_tag, loading: true });
40
+ const plys = await SocialComponentApi.searchPlayersByValue(tag.tag, page);
41
+ setPlayerTag({
42
+ ...player_tag,
43
+ loading: false,
44
+ players: plys,
45
+ offset: page
46
+ })
47
+ }
48
+
49
+ const handleSelectPlayer = (player:PublicPlayerProps) => {
50
+ if(!working_tag){ return }
51
+ onSelectTag({
52
+ ...working_tag,
53
+ tag: player.username,
54
+ player,
55
+ valid: true
56
+ })
57
+ }
58
+
59
+ const renderPlayers = (data:{ item:PublicPlayerProps, index:number }) => {
60
+ return (
61
+ <Button float style={{ margin:4, padding:0, maxWidth:120 }} onPress={() => handleSelectPlayer(data.item)}>
62
+ <Image
63
+ source={{ uri: data.item.profile_pic }}
64
+ style={{ height:80, width:120, borderTopRightRadius:8, borderTopLeftRadius:8 }}
65
+ resizeMode='cover'
66
+ />
67
+ <View transparent style={{ padding:5 }}>
68
+ <Text theme='h2' textAlign='center'>@{data.item.username}</Text>
69
+ </View>
70
+ </Button>
71
+ )
72
+ }
73
+
74
+ if(!visible){ return <></> }
75
+
76
+ return (
77
+ <View style={{ position:'absolute', bottom:5, left:0, right:0 }}>
78
+ {type == 'player' ?
79
+ <View float>
80
+ <View type='header' style={{ flexDirection:'row', alignItems:'center', padding:10 }}>
81
+ <View transparent style={{ flex:1 }}>
82
+ <Text theme='h2'>Tag A Player!</Text>
83
+ </View>
84
+ <Button
85
+ title='X'
86
+ float
87
+ onPress={() => onCancel()}
88
+ />
89
+ </View>
90
+ <View style={{ padding:5 }}>
91
+ <FlatList
92
+ data={player_tag.players}
93
+ key={'player_selector_list_format'}
94
+ horizontal
95
+ keyExtractor={(item) => item.player_id.toString()}
96
+ renderItem={renderPlayers}
97
+ />
98
+ </View>
99
+ </View>
100
+ :<></>}
101
+ </View>
102
+ )
103
+ }
104
+
105
+ export default TagSelector
@@ -0,0 +1,143 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { TextInput, View } from "../../Components/Themed"
3
+ import { Platform, type NativeSyntheticEvent, type TextInputSelectionChangeEventData } from 'react-native';
4
+ import type { TagProps } from '../../types';
5
+ import { SocialComponentApi, SocialComponentHelpers } from '../api';
6
+ import TagSelector from './components/TagSelector';
7
+
8
+ type FormattedTextInputProps = {
9
+ onChangeText?: (data:{ text:string, formatted_text:any }) => void,
10
+ onTagsUpdate:(tags:TagProps[]) => void
11
+ }
12
+
13
+ const FormattedTextInput = ({ onChangeText }:FormattedTextInputProps) => {
14
+ const [ input_state, setInputState ] = useState<{
15
+ height:number
16
+ }>({
17
+ height: 50
18
+ });
19
+ const [ data, setData ] = useState<{
20
+ text: string,
21
+ formatted_text:string
22
+ }>(
23
+ {
24
+ text: '',
25
+ formatted_text: JSON.stringify('')
26
+ }
27
+ );
28
+ const [ location, setLocation ] = useState({
29
+ start:0,
30
+ end:0
31
+ });
32
+ const [ tag_selector, setTagSelector ] = useState<{
33
+ visible:boolean,
34
+ type:'player',
35
+ working_tag?:TagProps
36
+ }>({ visible: false, type: 'player' })
37
+
38
+
39
+ const { text } = data;
40
+ const { height } = input_state;
41
+ const tags = useMemo(() => SocialComponentHelpers.extractTagsFromText(text, location.start), [location.start])
42
+ const active_tag = tags.find(t => t.active);
43
+
44
+ const [ valid_tags, setValidTags ] = useState<TagProps[]>([]);
45
+ const [ action_loading, setActionLoading ] = useState(false);
46
+ const [ working_tag, setWorkingTag ] = useState<any>();
47
+
48
+ useEffect(() => {
49
+ SocialComponentApi.setEnvironment();
50
+ },[])
51
+
52
+ useEffect(() => {
53
+ if(active_tag){ return setWorkingTag(active_tag) }
54
+ if(working_tag){
55
+ validateTag(working_tag)
56
+ searchPlayer(working_tag);
57
+ setWorkingTag(undefined)
58
+ return
59
+ }
60
+ },[active_tag]);
61
+
62
+
63
+ const validateTag = async(tag:TagProps) => {
64
+ console.log(tag)
65
+ }
66
+
67
+ const searchPlayer = async(tag:TagProps) => {
68
+ setActionLoading(true);
69
+ const player = await SocialComponentApi.searchPlayerByUsername(tag.tag);
70
+ if(player){
71
+ setValidTags(valid_tags.concat({ ...tag, player }));
72
+ return setActionLoading(false);
73
+ }
74
+ setTagSelector({
75
+ visible:true,
76
+ working_tag:tag,
77
+ type:'player'
78
+ })
79
+ return setActionLoading(false);
80
+ }
81
+
82
+
83
+ const handleSelectionChange = (ev:NativeSyntheticEvent<TextInputSelectionChangeEventData | any>) => {
84
+ if(ev.nativeEvent.selection.start == location.start){ return }
85
+ setLocation({
86
+ start: ev.nativeEvent.selection.start,
87
+ end: ev.nativeEvent.selection.end
88
+ });
89
+ }
90
+
91
+ const handleUpdateTag = async(tag:TagProps) => {
92
+ const new_text = SocialComponentHelpers.replaceText(text, tag.start, tag.end, `@${tag.tag}`);
93
+ setValidTags(valid_tags.concat({ ...tag }));
94
+ setData({
95
+ ...data,
96
+ text: new_text
97
+ });
98
+ setTagSelector({ visible: false, type: 'player' })
99
+
100
+ }
101
+
102
+ const handleChange = (ev:any) => {
103
+ let text:string = JSON.stringify(ev.text)
104
+ setData({
105
+ ...data,
106
+ text: ev.text,
107
+ formatted_text:text
108
+ });
109
+ if(onChangeText){ onChangeText({ text: ev.text, formatted_text: text }) }
110
+ }
111
+
112
+ return (
113
+ <View>
114
+ <View transparent>
115
+ {tag_selector.visible && tag_selector.working_tag ?
116
+ <TagSelector
117
+ working_tag={tag_selector.working_tag}
118
+ type={tag_selector.type}
119
+ visible={tag_selector.visible}
120
+ onCancel={() => setTagSelector({ visible: false, type: 'player' })}
121
+ onSelectTag={(tag) => handleUpdateTag(tag)}
122
+ />
123
+ :<></>}
124
+ </View>
125
+ <View transparent>
126
+ <TextInput
127
+ value={text}
128
+ editable={!action_loading}
129
+ multiline
130
+ style={{ flexGrow:1, height: Platform.OS == 'web' ? height : undefined }}
131
+ onContentSizeChange={(e) => {
132
+ if(Platform.OS != 'web'){ return }
133
+ setInputState({ ...input_state, height: e.nativeEvent.contentSize.height })
134
+ }}
135
+ onSelectionChange={handleSelectionChange}
136
+ onChange={(ev) => handleChange(ev.nativeEvent)}
137
+ />
138
+ </View>
139
+ </View>
140
+ )
141
+ }
142
+
143
+ export default FormattedTextInput
@@ -1,14 +1,14 @@
1
1
  import axios from "axios";
2
2
  import { APIOverrides } from "../../ApiOverrides";
3
- import type { AthleteProps, EventProps, LeagueProps, MatchProps, OrderProps, PlayerFollowerProps, PlayerPodcastEpisodeProps, PlayerPodcastProps, PodcastEpisodesProps, PodcastProps, PostReactionProps, TeamProps, TournamentProps } from "../../types";
3
+ import type { AthleteProps, EventProps, LeagueProps, MatchProps, OrderProps, PlayerFollowerProps, PlayerPodcastEpisodeProps, PlayerPodcastProps, PodcastEpisodesProps, PodcastProps, PostReactionProps, PublicPlayerProps, TagProps, TeamProps, TournamentProps } from "../../types";
4
4
  import Colors from "../../constants/colors";
5
5
  import moment from "moment-mini";
6
6
 
7
7
  let SOCIAL_SVC_API = '';
8
8
  let EVENT_SVC_API = '';
9
9
  let MK_SVC_API = '';
10
- //let AUTH_SVC_API = '';
11
- export { SocialComponentApi, SocialOrderHelpers, SocialPodcastHelpers }
10
+ let AUTH_SVC_API = '';
11
+ export { SocialComponentApi, SocialOrderHelpers, SocialPodcastHelpers, SocialComponentHelpers }
12
12
 
13
13
  const SocialComponentApi = {
14
14
  setEnvironment: () => {
@@ -16,7 +16,7 @@ const SocialComponentApi = {
16
16
  SOCIAL_SVC_API = endpoints['SOCIAL_SVC_API'] as string;
17
17
  EVENT_SVC_API = endpoints['EVENT_SVC_API'] as string;
18
18
  MK_SVC_API = endpoints['MK_SVC_API'] as string;
19
- //AUTH_SVC_API = endpoints['AUTH_SVC_API'] as string;
19
+ AUTH_SVC_API = endpoints['AUTH_SVC_API'] as string;
20
20
 
21
21
  },
22
22
  getLeagues: async():Promise<LeagueProps[]> => {
@@ -52,6 +52,24 @@ const SocialComponentApi = {
52
52
  return []
53
53
  }
54
54
  },
55
+ searchPlayerByUsername: async(username:string):Promise<PublicPlayerProps|undefined> => {
56
+ try {
57
+ const resp = await axios.post(`${AUTH_SVC_API}/v1/players/player/search/username`, { username })
58
+ return resp.data.player
59
+ } catch (e) {
60
+ console.log('there was an error')
61
+ console.log(e)
62
+ return undefined
63
+ }
64
+ },
65
+ searchPlayersByValue: async(search_value:string, offset:number):Promise<PublicPlayerProps[]> => {
66
+ try {
67
+ const resp = await axios.post(`${AUTH_SVC_API}/v1/players/player/search/value`, { search_value, offset })
68
+ return resp.data.players
69
+ } catch (e) {
70
+ return []
71
+ }
72
+ },
55
73
  getMatchesByMatchIds: async(match_ids:string[]):Promise<MatchProps[]> => {
56
74
  if(match_ids.length == 0){ return [] }
57
75
  try {
@@ -232,6 +250,32 @@ const SocialOrderHelpers = {
232
250
  }
233
251
  }
234
252
 
253
+ const SocialComponentHelpers = {
254
+ extractTagsFromText: (text:string, cursor?:number):TagProps[] => {
255
+ let tags:TagProps[] = []
256
+ let split_text = text.split(' ');
257
+ if(split_text.length == 0){ return [] }
258
+ let location = 0
259
+ split_text.map(t => {
260
+ let text_length = t.length + 1
261
+ location += text_length
262
+ if(t[0] == '@'){
263
+ let tag = t.split('@')[1]
264
+ let start = location - text_length
265
+ let end = location - 1
266
+ const active = cursor && cursor >= start && cursor <= end ? true :false
267
+ tags.push({ indicator:'@', type:'player', tag: tag ?? '', start, end, active})
268
+ }
269
+ })
270
+ return tags
271
+ },
272
+ replaceText :(originalText:string, startIndex:number, endIndex:number, replacementText:string) => {
273
+ const before = originalText.substring(0, startIndex);
274
+ const after = originalText.substring(endIndex);
275
+ return before + replacementText + after;
276
+ }
277
+ }
278
+
235
279
  const SocialPodcastHelpers = {
236
280
  getPodcastImage: (podcast:PodcastProps):string => {
237
281
  let image_source = podcast.image_override?.url
@@ -6,9 +6,14 @@ import PodcastModule from './PodcastModule';
6
6
  import AudioPlayer from "./AudioPlayer";
7
7
  import { useContacts } from "./Contacts/useContacts";
8
8
  import PostCard from './PostCard';
9
+ import FormattedTextInput from "./FormattedTextInput";
10
+ import { FormattedText } from "./FormattedText";
11
+
9
12
  export {
10
13
  PlayerCard,
11
14
  PlayerList,
15
+ FormattedTextInput,
16
+ FormattedText,
12
17
  PlayerProfile,
13
18
  CompanyProfile,
14
19
  PodcastModule,
package/src/types.d.ts CHANGED
@@ -500,7 +500,17 @@ export interface PlayerFollowerStatsProps {
500
500
  team_member_count:number
501
501
  }
502
502
 
503
-
503
+ export interface TagProps {
504
+ type: 'player' | string,
505
+ tag_type_id?:string,
506
+ player?:PublicPlayerProps,
507
+ indicator: string,
508
+ tag: string,
509
+ start: number,
510
+ end: number,
511
+ active?:boolean,
512
+ valid?:boolean
513
+ }
504
514
 
505
515
  export interface CampaignProps {
506
516
  campaign_id:string,