@@ -2,9 +2,8 @@ import React, { ReactElement, useState } from 'react';
2
2
import { View , StyleSheet , TouchableOpacity } from 'react-native' ;
3
3
import { StackNavigationProp } from '@react-navigation/stack' ;
4
4
import Clipboard from '@react-native-clipboard/clipboard' ;
5
- import { useTranslation } from 'react-i18next' ;
6
- import { SlashURL } from '@synonymdev/slashtags-sdk' ;
7
5
import { parse } from '@synonymdev/slashtags-url' ;
6
+ import { useTranslation } from 'react-i18next' ;
8
7
9
8
import { closeBottomSheet } from '../../store/actions/ui' ;
10
9
import { handleSlashtagURL } from '../../utils/slashtags' ;
@@ -15,10 +14,12 @@ import {
15
14
useBottomSheetBackPress ,
16
15
useSnapPoints ,
17
16
} from '../../hooks/bottomSheet' ;
18
- import { Text01S , Text02S } from '../../styles/text' ;
17
+ import { Text01S } from '../../styles/text' ;
19
18
import { ClipboardTextIcon , CornersOutIcon } from '../../styles/icons' ;
20
19
import type { RootStackParamList } from '../../navigation/types' ;
21
20
import { useSelectedSlashtag2 } from '../../hooks/slashtags2' ;
21
+ import Button from '../../components/Button' ;
22
+ import SafeAreaInset from '../../components/SafeAreaInset' ;
22
23
23
24
const AddContact = ( {
24
25
navigation,
@@ -27,57 +28,63 @@ const AddContact = ({
27
28
} ) : ReactElement => {
28
29
const { t } = useTranslation ( 'slashtags' ) ;
29
30
const snapPoints = useSnapPoints ( 'small' ) ;
30
- const [ addContactURL , setAddContactURL ] = useState ( '' ) ;
31
- const [ error , setError ] = useState < boolean | string > ( false ) ;
31
+ const [ url , setUrl ] = useState ( '' ) ;
32
+ const [ error , setError ] = useState < undefined | string > ( ) ;
32
33
const { url : myProfileURL } = useSelectedSlashtag2 ( ) ;
33
34
34
35
useBottomSheetBackPress ( 'addContactModal' ) ;
35
36
36
- const updateContactID = ( url : string ) : void => {
37
- setAddContactURL ( url ) ;
38
- setError ( false ) ;
37
+ const handleChangeUrl = ( contactUrl : string ) : void => {
38
+ setUrl ( contactUrl ) ;
39
+ setError ( undefined ) ;
40
+ } ;
39
41
40
- if ( url === '' ) {
42
+ const handleAddContact = ( contactUrl ?: string ) : void => {
43
+ contactUrl = contactUrl ?? url ;
44
+ setError ( undefined ) ;
45
+ if ( ! contactUrl ) {
41
46
return ;
42
47
}
43
48
44
49
try {
45
- if ( parse ( url ) . id === parse ( myProfileURL ) . id ) {
50
+ parse ( contactUrl ) ;
51
+ } catch ( e ) {
52
+ setError ( t ( 'contact_error_key' ) ) ;
53
+ return ;
54
+ }
55
+
56
+ try {
57
+ if ( parse ( contactUrl ) . id === parse ( myProfileURL ) . id ) {
46
58
setError ( t ( 'contact_error_yourself' ) ) ;
47
59
return ;
48
60
}
49
61
} catch ( e ) { }
50
62
51
- if ( ! url . startsWith ( 'slash:' ) ) {
52
- // Handle z32 key without slash: scheme prefix
53
- try {
54
- SlashURL . decode ( url ) ;
55
- handleSlashtagURL ( 'slash:' + url , onError , onContact ) ;
56
- } catch {
57
- onError ( ) ;
58
- }
59
- } else {
60
- handleSlashtagURL ( url , onError , onContact ) ;
61
- }
62
-
63
- function onError ( ) : void {
63
+ const onError = ( ) : void => {
64
64
setError ( t ( 'contact_error_key' ) ) ;
65
- }
65
+ } ;
66
66
67
- function onContact ( ) : void {
68
- setAddContactURL ( '' ) ;
67
+ const onContact = ( ) : void => {
68
+ setUrl ( '' ) ;
69
69
closeBottomSheet ( 'addContactModal' ) ;
70
- }
70
+ } ;
71
+
72
+ handleSlashtagURL ( contactUrl , onError , onContact ) ;
73
+ } ;
74
+
75
+ const updateContactID = async ( contactUrl : string ) : Promise < void > => {
76
+ setUrl ( contactUrl ) ;
77
+ handleAddContact ( contactUrl ) ;
71
78
} ;
72
79
73
- const pasteAddContact = async ( ) : Promise < void > => {
74
- let url = await Clipboard . getString ( ) ;
75
- url = url . trim ( ) ;
76
- updateContactID ( url ) ;
80
+ const handlePaste = async ( ) : Promise < void > => {
81
+ let contactUrl = await Clipboard . getString ( ) ;
82
+ contactUrl = contactUrl . trim ( ) ;
83
+ updateContactID ( contactUrl ) ;
77
84
} ;
78
85
79
- const navigateToScanner = ( ) : void => {
80
- navigation . navigate ( 'Scanner' ) ;
86
+ const handleScanner = ( ) : void => {
87
+ navigation . navigate ( 'Scanner' , { onScan : updateContactID } ) ;
81
88
} ;
82
89
83
90
return (
@@ -97,25 +104,33 @@ const AddContact = ({
97
104
< LabeledInput
98
105
bottomSheet = { true }
99
106
label = { t ( 'contact_add' ) }
100
- value = { addContactURL }
107
+ error = { error }
108
+ value = { url }
101
109
placeholder = { t ( 'contact_key_paste' ) }
102
110
multiline = { true }
103
- onChange = { updateContactID }
104
- testID = "ContactURLInput" >
105
- < TouchableOpacity onPress = { navigateToScanner } >
111
+ onChange = { handleChangeUrl }
112
+ testID = "ContactURLInput"
113
+ color = { error ? 'brand' : undefined } >
114
+ < TouchableOpacity onPress = { handleScanner } >
106
115
< CornersOutIcon width = { 24 } height = { 24 } color = "brand" />
107
116
</ TouchableOpacity >
108
- < TouchableOpacity onPress = { pasteAddContact } >
117
+ < TouchableOpacity onPress = { handlePaste } >
109
118
< ClipboardTextIcon width = { 24 } height = { 24 } color = "brand" />
110
119
</ TouchableOpacity >
111
120
</ LabeledInput >
121
+ </ View >
112
122
113
- { error && (
114
- < View style = { styles . error } testID = "ContactError" >
115
- < Text02S color = "brand" > { error } </ Text02S >
116
- </ View >
117
- ) }
123
+ < View style = { styles . footer } >
124
+ < Button
125
+ size = "large"
126
+ disabled = { ! url }
127
+ style = { styles . button }
128
+ text = { t ( 'contact_add_button' ) }
129
+ onPress = { ( ) : void => handleAddContact ( ) }
130
+ testID = "AddContactButton"
131
+ />
118
132
</ View >
133
+ < SafeAreaInset type = "bottom" minPadding = { 16 } />
119
134
</ View >
120
135
</ BottomSheetWrapper >
121
136
) ;
@@ -130,10 +145,18 @@ const styles = StyleSheet.create({
130
145
} ,
131
146
addContactNote : {
132
147
marginHorizontal : 16 ,
133
- marginBottom : 56 ,
148
+ marginBottom : 16 ,
134
149
} ,
135
- error : {
136
- marginTop : 16 ,
150
+ footer : {
151
+ paddingHorizontal : 16 ,
152
+ alignItems : 'flex-end' ,
153
+ justifyContent : 'flex-end' ,
154
+ flex : 1 ,
155
+ flexDirection : 'row' ,
156
+ } ,
157
+ button : {
158
+ marginBottom : 16 ,
159
+ flex : 1 ,
137
160
} ,
138
161
} ) ;
139
162
0 commit comments