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.
- package/lib/commonjs/ProfileManager/Components/VouchCard.js +6 -0
- package/lib/commonjs/ProfileManager/Components/VouchCard.js.map +1 -1
- package/lib/commonjs/SocialComponents/FormattedText.js +130 -0
- package/lib/commonjs/SocialComponents/FormattedText.js.map +1 -0
- package/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.js +137 -0
- package/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.js.map +1 -0
- package/lib/commonjs/SocialComponents/FormattedTextInput/index.js +150 -0
- package/lib/commonjs/SocialComponents/FormattedTextInput/index.js.map +1 -0
- package/lib/commonjs/SocialComponents/api/index.js +60 -4
- package/lib/commonjs/SocialComponents/api/index.js.map +1 -1
- package/lib/commonjs/SocialComponents/index.js +14 -0
- package/lib/commonjs/SocialComponents/index.js.map +1 -1
- package/lib/module/ProfileManager/Components/VouchCard.js +7 -1
- package/lib/module/ProfileManager/Components/VouchCard.js.map +1 -1
- package/lib/module/SocialComponents/FormattedText.js +120 -0
- package/lib/module/SocialComponents/FormattedText.js.map +1 -0
- package/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.js +129 -0
- package/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.js.map +1 -0
- package/lib/module/SocialComponents/FormattedTextInput/index.js +141 -0
- package/lib/module/SocialComponents/FormattedTextInput/index.js.map +1 -0
- package/lib/module/SocialComponents/api/index.js +60 -3
- package/lib/module/SocialComponents/api/index.js.map +1 -1
- package/lib/module/SocialComponents/index.js +3 -1
- package/lib/module/SocialComponents/index.js.map +1 -1
- package/lib/typescript/lib/commonjs/ProfileManager/Components/VouchCard.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/SocialComponents/FormattedText.d.ts +9 -0
- package/lib/typescript/lib/commonjs/SocialComponents/FormattedText.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +10 -0
- package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/index.d.ts +6 -0
- package/lib/typescript/lib/commonjs/SocialComponents/FormattedTextInput/index.d.ts.map +1 -0
- package/lib/typescript/lib/commonjs/SocialComponents/api/index.d.ts +6 -0
- package/lib/typescript/lib/commonjs/SocialComponents/api/index.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/SocialComponents/index.d.ts +6 -0
- package/lib/typescript/lib/module/ProfileManager/Components/VouchCard.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/FormattedText.d.ts +9 -0
- package/lib/typescript/lib/module/SocialComponents/FormattedText.d.ts.map +1 -0
- package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +12 -0
- package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -0
- package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/index.d.ts +6 -0
- package/lib/typescript/lib/module/SocialComponents/FormattedTextInput/index.d.ts.map +1 -0
- package/lib/typescript/lib/module/SocialComponents/api/index.d.ts +6 -0
- package/lib/typescript/lib/module/SocialComponents/api/index.d.ts.map +1 -1
- package/lib/typescript/lib/module/SocialComponents/index.d.ts +3 -1
- package/lib/typescript/lib/module/SocialComponents/index.d.ts.map +1 -1
- package/lib/typescript/src/ProfileManager/Components/VouchCard.d.ts.map +1 -1
- package/lib/typescript/src/SocialComponents/FormattedText.d.ts +21 -0
- package/lib/typescript/src/SocialComponents/FormattedText.d.ts.map +1 -0
- package/lib/typescript/src/SocialComponents/FormattedTextInput/components/TagSelector.d.ts +12 -0
- package/lib/typescript/src/SocialComponents/FormattedTextInput/components/TagSelector.d.ts.map +1 -0
- package/lib/typescript/src/SocialComponents/FormattedTextInput/index.d.ts +12 -0
- package/lib/typescript/src/SocialComponents/FormattedTextInput/index.d.ts.map +1 -0
- package/lib/typescript/src/SocialComponents/api/index.d.ts +8 -2
- package/lib/typescript/src/SocialComponents/api/index.d.ts.map +1 -1
- package/lib/typescript/src/SocialComponents/index.d.ts +3 -1
- package/lib/typescript/src/SocialComponents/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ProfileManager/Components/VouchCard.tsx +3 -2
- package/src/SocialComponents/FormattedText.tsx +126 -0
- package/src/SocialComponents/FormattedTextInput/components/TagSelector.tsx +105 -0
- package/src/SocialComponents/FormattedTextInput/index.tsx +143 -0
- package/src/SocialComponents/api/index.ts +48 -4
- package/src/SocialComponents/index.tsx +5 -0
- 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;
|
|
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
|
-
|
|
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,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
|
-
|
|
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
|
-
|
|
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,
|