Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.

Commit 47b36d0

Browse files
author
KoalaSat
authored
Custom relays (#91)
2 parents 57d26ca + e721b9e commit 47b36d0

7 files changed

Lines changed: 117 additions & 13 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Local setup: https://github.com/KoalaSat/nostros/blob/main/SETUP.md
5757
### Note
5858

5959
- [x] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
60-
- [ ] Reactions https://github.com/nostr-protocol/nips/blob/master/25.md
60+
- [x] Reactions https://github.com/nostr-protocol/nips/blob/master/25.md
6161
- [ ] Deletion https://github.com/nostr-protocol/nips/blob/master/09.md
6262
- [x] Load entire thread
6363

android/app/src/main/java/com/nostros/modules/RelayPoolModule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ public void connect(String pubKey, Callback callback) {
6767
userPubKey = pubKey;
6868
relays = database.getRelays(context);
6969
if (relays.isEmpty()) {
70-
add("wss://relay.damus.io");
70+
add("wss://damus.io");
71+
add("wss://brb.io");
7172
add("wss://nostr-relay.wlvs.space");
7273
}
7374
for (Relay relay : relays) {
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
export const defaultRelays = [
2-
'wss://nostr-relay.wlvs.space',
2+
'wss://brb.io',
3+
'wss://damus.io',
34
'wss://nostr-pub.wellorder.net',
45
'wss://nostr-relay.wlvs.space',
56
'wss://nostr.onsats.org',
67
'wss://nostr-pub.semisol.dev',
7-
'wss://relay.damus.io',
88
'wss://nostr.openchain.fr',
99
'wss://relay.nostr.info',
1010
'wss://nostr.oxtr.dev',
1111
'wss://nostr.ono.re',
1212
'wss://relay.grunch.dev',
13-
'wss://brb.io',
14-
'wss://damus.io',
1513
]
14+
15+
export const REGEX_SOCKET_LINK =
16+
/((wss):\/\/)?([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/i

frontend/Locales/en.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@
3232
"createProfile": "Go to configuration"
3333
},
3434
"relaysPage": {
35-
"title": "Relays"
35+
"title": "Relays",
36+
"addRelay": {
37+
"placeholder": "Relay URL",
38+
"invalidFormat": "Invalid Format",
39+
"add": "Add relay"
40+
}
3641
},
3742
"loader": {
3843
"searchingProfile": "Searching your profile",

frontend/Locales/es.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@
3232
"createProfile": "Ir a configuración"
3333
},
3434
"relaysPage": {
35-
"title": "Relays"
35+
"title": "Relays",
36+
"addRelay": {
37+
"placeholder": "URL del relay",
38+
"invalidFormat": "Format no válido",
39+
"add": "Agregar relay"
40+
}
3641
},
3742
"notePage": {
3843
"reply": "Responder"

frontend/Locales/ru.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@
3232
"createProfile": "Перейти в настройки"
3333
},
3434
"relaysPage": {
35-
"title": "Все реле"
35+
"title": "Все реле",
36+
"addRelay": {
37+
"placeholder": "URL del relay",
38+
"invalidFormat": "Format no válido",
39+
"add": "Agregar relay"
40+
}
3641
},
3742
"notePage": {
3843
"reply": "Ответить"

frontend/Pages/RelaysPage/index.tsx

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
import { Button, Layout, TopNavigation, useTheme, Text } from '@ui-kitten/components'
1+
import {
2+
Button,
3+
Layout,
4+
TopNavigation,
5+
useTheme,
6+
Text,
7+
Modal,
8+
Card,
9+
Input,
10+
} from '@ui-kitten/components'
211
import React, { useContext, useEffect, useState } from 'react'
3-
import { RefreshControl, ScrollView, StyleSheet } from 'react-native'
12+
import { RefreshControl, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'
413
import { AppContext } from '../../Contexts/AppContext'
514
import Icon from 'react-native-vector-icons/FontAwesome5'
615
import { useTranslation } from 'react-i18next'
716
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
817
import { getRelays, Relay } from '../../Functions/DatabaseFunctions/Relays'
9-
import { defaultRelays } from '../../Constants/RelayConstants'
18+
import { defaultRelays, REGEX_SOCKET_LINK } from '../../Constants/RelayConstants'
1019
import { showMessage } from 'react-native-flash-message'
1120

1221
export const RelaysPage: React.FC = () => {
@@ -16,6 +25,9 @@ export const RelaysPage: React.FC = () => {
1625
const { t } = useTranslation('common')
1726
const [relays, setRelays] = useState<Relay[]>([])
1827
const [loading, setLoading] = useState<boolean>(false)
28+
const [showAddRelay, setShowAddRelay] = useState<boolean>(false)
29+
const [addRelayInput, setAddRelayInput] = useState<string>('')
30+
const [showInvalidInput, setShowInvalidInput] = useState<boolean>(false)
1931

2032
const loadRelays: () => void = () => {
2133
if (database) {
@@ -70,6 +82,17 @@ export const RelaysPage: React.FC = () => {
7082
}
7183
}
7284

85+
const onPressAddRelay: () => void = () => {
86+
if ((addRelayInput.match(REGEX_SOCKET_LINK) ?? []).length > 0) {
87+
addRelayItem(addRelayInput)
88+
setAddRelayInput('')
89+
setShowAddRelay(false)
90+
setShowInvalidInput(false)
91+
} else {
92+
setShowInvalidInput(true)
93+
}
94+
}
95+
7396
const relayActions: (relay: Relay) => JSX.Element = (relay) => {
7497
return relays?.find((item) => item.url === relay.url) ? (
7598
<Button
@@ -83,7 +106,7 @@ export const RelaysPage: React.FC = () => {
83106
status='success'
84107
disabled={loading}
85108
onPress={() => addRelayItem(relay.url)}
86-
accessoryLeft={<Icon name='plus' size={16} color={theme['text-basic-color']} solid />}
109+
accessoryLeft={<Icon name='power-off' size={16} color={theme['text-basic-color']} solid />}
87110
/>
88111
)
89112
}
@@ -135,6 +158,23 @@ export const RelaysPage: React.FC = () => {
135158
text: {
136159
color: theme['text-basic-color'],
137160
},
161+
modal: {
162+
paddingLeft: 32,
163+
paddingRight: 32,
164+
width: '100%',
165+
},
166+
backdrop: {
167+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
168+
},
169+
button: {
170+
marginTop: 31,
171+
},
172+
modalContainer: {
173+
marginTop: 30,
174+
marginBottom: 30,
175+
paddingLeft: 12,
176+
paddingRight: 12,
177+
},
138178
})
139179

140180
return (
@@ -156,7 +196,54 @@ export const RelaysPage: React.FC = () => {
156196
)}
157197
</ScrollView>
158198
</Layout>
199+
<Modal
200+
style={styles.modal}
201+
visible={showAddRelay}
202+
backdropStyle={styles.backdrop}
203+
onBackdropPress={() => setShowAddRelay(false)}
204+
>
205+
<Card disabled={true}>
206+
<Layout style={styles.modalContainer}>
207+
<Layout>
208+
<Input
209+
placeholder={t('relaysPage.addRelay.placeholder')}
210+
value={addRelayInput}
211+
onChangeText={setAddRelayInput}
212+
size='large'
213+
/>
214+
</Layout>
215+
{showInvalidInput && (
216+
<Layout style={styles.button}>
217+
<Text status='danger'>{t('relaysPage.addRelay.invalidFormat')}</Text>
218+
</Layout>
219+
)}
220+
<Layout style={styles.button}>
221+
<Button onPress={onPressAddRelay}>
222+
{<Text>{t('relaysPage.addRelay.add')}</Text>}
223+
</Button>
224+
</Layout>
225+
</Layout>
226+
</Card>
227+
</Modal>
159228
</Layout>
229+
<TouchableOpacity
230+
style={{
231+
borderWidth: 1,
232+
borderColor: 'rgba(0,0,0,0.2)',
233+
alignItems: 'center',
234+
justifyContent: 'center',
235+
width: 65,
236+
position: 'absolute',
237+
bottom: 20,
238+
right: 20,
239+
height: 65,
240+
backgroundColor: theme['color-warning-500'],
241+
borderRadius: 100,
242+
}}
243+
onPress={() => setShowAddRelay(true)}
244+
>
245+
<Icon name='plus' size={30} color={theme['text-basic-color']} solid />
246+
</TouchableOpacity>
160247
</>
161248
)
162249
}

0 commit comments

Comments
 (0)