mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-29 06:30:47 +00:00
NIP-65 Publish relay list
This commit is contained in:
parent
fd711c0c35
commit
b6532b83e1
3
.github/workflows/notify.yml
vendored
3
.github/workflows/notify.yml
vendored
@ -29,5 +29,4 @@ jobs:
|
|||||||
~/go/bin/noscl relay add "wss://nostr.ono.re"
|
~/go/bin/noscl relay add "wss://nostr.ono.re"
|
||||||
~/go/bin/noscl relay add "wss://relay.grunch.dev"
|
~/go/bin/noscl relay add "wss://relay.grunch.dev"
|
||||||
~/go/bin/noscl relay add "wss://nostr.developer.li"
|
~/go/bin/noscl relay add "wss://nostr.developer.li"
|
||||||
~/go/bin/noscl publish '${{ github.event.release.body }}'
|
~/go/bin/noscl publish "${{ github.event.release.body }}"
|
||||||
~/go/bin/noscl publish ${{ github.event.release.body }}
|
|
||||||
|
@ -71,7 +71,9 @@ public class Event {
|
|||||||
} else if (kind.equals("43")) {
|
} else if (kind.equals("43")) {
|
||||||
hideGroupMessage(database);
|
hideGroupMessage(database);
|
||||||
} else if (kind.equals("44")) {
|
} else if (kind.equals("44")) {
|
||||||
blockUser(database);
|
muteUser(database);
|
||||||
|
} else if (kind.equals("1002")) {
|
||||||
|
saveRelays(database);
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -209,13 +211,14 @@ public class Event {
|
|||||||
database.replace("nostros_notes", null, values);
|
database.replace("nostros_notes", null, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void blockUser(SQLiteDatabase database) throws JSONException {
|
protected void muteUser(SQLiteDatabase database) throws JSONException {
|
||||||
JSONArray pTags = filterTags("p");
|
JSONArray pTags = filterTags("p");
|
||||||
String groupId = pTags.getJSONArray(0).getString(1);
|
String groupId = pTags.getJSONArray(0).getString(1);
|
||||||
String query = "SELECT id FROM nostros_users WHERE id = ?";
|
String query = "SELECT id FROM nostros_users WHERE id = ?";
|
||||||
@SuppressLint("Recycle") Cursor cursor = database.rawQuery(query, new String[] {groupId});
|
@SuppressLint("Recycle") Cursor cursor = database.rawQuery(query, new String[] {groupId});
|
||||||
|
|
||||||
if (cursor.getCount() == 0) {
|
if (cursor.getCount() == 0) {
|
||||||
|
} else {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put("muted_groups", 1);
|
values.put("muted_groups", 1);
|
||||||
String whereClause = "id = ?";
|
String whereClause = "id = ?";
|
||||||
@ -409,7 +412,7 @@ public class Event {
|
|||||||
values.put("valid_nip05", validateNip05(nip05) ? 1 : 0);
|
values.put("valid_nip05", validateNip05(nip05) ? 1 : 0);
|
||||||
values.put("blocked", 0);
|
values.put("blocked", 0);
|
||||||
database.insert("nostros_users", null, values);
|
database.insert("nostros_users", null, values);
|
||||||
} else if (cursor.moveToFirst() && (cursor.isNull(0) || created_at > cursor.getInt(0))) {
|
} else if (cursor.moveToFirst() && created_at > cursor.getInt(0)) {
|
||||||
if (cursor.getInt(1) == 0 || !cursor.getString(2).equals(nip05)) {
|
if (cursor.getInt(1) == 0 || !cursor.getString(2).equals(nip05)) {
|
||||||
values.put("valid_nip05", validateNip05(nip05) ? 1 : 0);
|
values.put("valid_nip05", validateNip05(nip05) ? 1 : 0);
|
||||||
}
|
}
|
||||||
@ -422,23 +425,71 @@ public class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void savePets(SQLiteDatabase database) throws JSONException {
|
protected void savePets(SQLiteDatabase database) throws JSONException {
|
||||||
|
String queryLast = "SELECT pet_at FROM nostros_users ORDER BY pet_at DESC LIMIT 1";
|
||||||
|
Cursor cursorLast = database.rawQuery(queryLast, new String[] {});
|
||||||
|
if (cursorLast.moveToFirst() && created_at > cursorLast.getInt(0)) {
|
||||||
|
ContentValues valuesIntial = new ContentValues();
|
||||||
|
valuesIntial.put("contact", 0);
|
||||||
|
String whereClauseInitial = "id = ?";
|
||||||
|
database.update("nostros_users", valuesIntial, whereClauseInitial, new String[]{});
|
||||||
|
|
||||||
|
for (int i = 0; i < tags.length(); ++i) {
|
||||||
|
JSONArray tag = tags.getJSONArray(i);
|
||||||
|
String petId = tag.getString(1);
|
||||||
|
String name = "";
|
||||||
|
if (tag.length() >= 4) {
|
||||||
|
name = tag.getString(3);
|
||||||
|
}
|
||||||
|
String query = "SELECT * FROM nostros_users WHERE id = ?";
|
||||||
|
Cursor cursor = database.rawQuery(query, new String[] {petId});
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("pet_at", created_at);
|
||||||
|
values.put("contact", 1);
|
||||||
|
values.put("name", name);
|
||||||
|
values.put("blocked", 0);
|
||||||
|
|
||||||
|
if (cursor.getCount() == 0) {
|
||||||
|
values.put("id", petId);
|
||||||
|
database.insert("nostros_users", null, values);
|
||||||
|
} else {
|
||||||
|
String whereClause = "id = ?";
|
||||||
|
String[] whereArgs = new String[] {
|
||||||
|
petId
|
||||||
|
};
|
||||||
|
database.update("nostros_users", values, whereClause, whereArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void saveRelays(SQLiteDatabase database) throws JSONException {
|
||||||
for (int i = 0; i < tags.length(); ++i) {
|
for (int i = 0; i < tags.length(); ++i) {
|
||||||
JSONArray tag = tags.getJSONArray(i);
|
JSONArray tag = tags.getJSONArray(i);
|
||||||
String petId = tag.getString(1);
|
String url = tag.getString(1);
|
||||||
String name = "";
|
String mode = "";
|
||||||
if (tag.length() >= 4) {
|
if (tag.length() > 1) {
|
||||||
name = tag.getString(3);
|
mode = tag.getString(2);
|
||||||
}
|
}
|
||||||
String query = "SELECT * FROM nostros_users WHERE id = ?";
|
|
||||||
Cursor cursor = database.rawQuery(query, new String[] {petId});
|
String query = "SELECT updated_at FROM nostros_relays WHERE url = ?";
|
||||||
|
Cursor cursor = database.rawQuery(query, new String[] {url});
|
||||||
|
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("url", url);
|
||||||
|
values.put("mode", mode);
|
||||||
|
|
||||||
if (cursor.getCount() == 0) {
|
if (cursor.getCount() == 0) {
|
||||||
ContentValues values = new ContentValues();
|
values.put("active", 0);
|
||||||
values.put("id", petId);
|
values.put("global_feed", 0);
|
||||||
values.put("name", name);
|
values.put("manual", 1);
|
||||||
values.put("contact", true);
|
database.insert("nostros_relays", null, values);
|
||||||
values.put("blocked", 0);
|
} else if (cursor.moveToFirst() && created_at > cursor.getInt(0)) {
|
||||||
values.put("pet_at", created_at);
|
values.put("updated_at", created_at);
|
||||||
database.insert("nostros_users", null, values);
|
String whereClause = "url = ?";
|
||||||
|
String[] whereArgs = new String[] {
|
||||||
|
url
|
||||||
|
};
|
||||||
|
database.update("nostros_relays", values, whereClause, whereArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +173,10 @@ public class DatabaseModule {
|
|||||||
database.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN read INT DEFAULT 0;");
|
database.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN read INT DEFAULT 0;");
|
||||||
database.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN user_mentioned INT DEFAULT 0;");
|
database.execSQL("ALTER TABLE nostros_group_messages ADD COLUMN user_mentioned INT DEFAULT 0;");
|
||||||
} catch (SQLException e) { }
|
} catch (SQLException e) { }
|
||||||
|
try {
|
||||||
|
database.execSQL("ALTER TABLE updated_at ADD COLUMN mode INT DEFAULT 0;");
|
||||||
|
database.execSQL("ALTER TABLE nostros_relays ADD COLUMN mode TEXT;");
|
||||||
|
} catch (SQLException e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveEvent(JSONObject data, String userPubKey, String relayUrl) throws JSONException {
|
public void saveEvent(JSONObject data, String userPubKey, String relayUrl) throws JSONException {
|
||||||
|
@ -27,6 +27,12 @@ export const MenuItems: React.FC = () => {
|
|||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
|
|
||||||
|
const [activerelays, setActiveRelays] = React.useState<number>(0)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
setActiveRelays(relays.filter((relay) => relay.active).length)
|
||||||
|
}, [relays])
|
||||||
|
|
||||||
const onPressLogout: () => void = () => {
|
const onPressLogout: () => void = () => {
|
||||||
logout()
|
logout()
|
||||||
}
|
}
|
||||||
@ -110,12 +116,12 @@ export const MenuItems: React.FC = () => {
|
|||||||
onPress={() => onPressItem('relays', 0)}
|
onPress={() => onPressItem('relays', 0)}
|
||||||
onTouchEnd={() => setDrawerItemIndex(-1)}
|
onTouchEnd={() => setDrawerItemIndex(-1)}
|
||||||
right={() =>
|
right={() =>
|
||||||
relays.length < 1 ? (
|
activerelays < 1 ? (
|
||||||
<Text style={{ color: theme.colors.error }}>{t('menuItems.notConnected')}</Text>
|
<Text style={{ color: theme.colors.error }}>{t('menuItems.notConnected')}</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text style={{ color: theme.colors.inversePrimary }}>
|
<Text style={{ color: '#7ADC70' }}>
|
||||||
{t('menuItems.connectedRelays', {
|
{t('menuItems.connectedRelays', {
|
||||||
number: relays.filter((relay) => relay.active).length,
|
number: activerelays,
|
||||||
})}
|
})}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { StyleSheet, View, ListRenderItem, Switch, FlatList } from 'react-native'
|
import { StyleSheet, View, ListRenderItem, Switch, FlatList } from 'react-native'
|
||||||
import { IconButton, List, Snackbar, Text, useTheme } from 'react-native-paper'
|
import { Button, IconButton, List, Snackbar, Text, useTheme } from 'react-native-paper'
|
||||||
import { AppContext } from '../../Contexts/AppContext'
|
import { AppContext } from '../../Contexts/AppContext'
|
||||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
||||||
import { UserContext } from '../../Contexts/UserContext'
|
import { UserContext } from '../../Contexts/UserContext'
|
||||||
@ -10,6 +10,7 @@ import {
|
|||||||
getUser,
|
getUser,
|
||||||
updateUserBlock,
|
updateUserBlock,
|
||||||
updateUserContact,
|
updateUserContact,
|
||||||
|
updateUserMutesGroups,
|
||||||
User,
|
User,
|
||||||
} from '../../Functions/DatabaseFunctions/Users'
|
} from '../../Functions/DatabaseFunctions/Users'
|
||||||
import { populatePets, username } from '../../Functions/RelayFunctions/Users'
|
import { populatePets, username } from '../../Functions/RelayFunctions/Users'
|
||||||
@ -22,6 +23,8 @@ import { relayToColor } from '../../Functions/NativeFunctions'
|
|||||||
import { Relay } from '../../Functions/DatabaseFunctions/Relays'
|
import { Relay } from '../../Functions/DatabaseFunctions/Relays'
|
||||||
import ProfileShare from '../ProfileShare'
|
import ProfileShare from '../ProfileShare'
|
||||||
import { ScrollView } from 'react-native-gesture-handler'
|
import { ScrollView } from 'react-native-gesture-handler'
|
||||||
|
import { Kind } from 'nostr-tools'
|
||||||
|
import { getUnixTime } from 'date-fns'
|
||||||
|
|
||||||
interface ProfileActionsProps {
|
interface ProfileActionsProps {
|
||||||
user: User
|
user: User
|
||||||
@ -40,10 +43,12 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
|
|||||||
const { relayPool, updateRelayItem } = React.useContext(RelayPoolContext)
|
const { relayPool, updateRelayItem } = React.useContext(RelayPoolContext)
|
||||||
const [isContact, setIsContact] = React.useState<boolean>()
|
const [isContact, setIsContact] = React.useState<boolean>()
|
||||||
const [isBlocked, setIsBlocked] = React.useState<boolean>()
|
const [isBlocked, setIsBlocked] = React.useState<boolean>()
|
||||||
|
const [isMuted, setIsMuted] = React.useState<boolean>()
|
||||||
const [showNotification, setShowNotification] = React.useState<undefined | string>()
|
const [showNotification, setShowNotification] = React.useState<undefined | string>()
|
||||||
const [showNotificationRelay, setShowNotificationRelay] = React.useState<undefined | string>()
|
const [showNotificationRelay, setShowNotificationRelay] = React.useState<undefined | string>()
|
||||||
const bottomSheetRelaysRef = React.useRef<RBSheet>(null)
|
const bottomSheetRelaysRef = React.useRef<RBSheet>(null)
|
||||||
const bottomSheetShareRef = React.useRef<RBSheet>(null)
|
const bottomSheetShareRef = React.useRef<RBSheet>(null)
|
||||||
|
const bottomSheetMuteRef = React.useRef<RBSheet>(null)
|
||||||
const [userRelays, setUserRelays] = React.useState<NoteRelay[]>([])
|
const [userRelays, setUserRelays] = React.useState<NoteRelay[]>([])
|
||||||
const [openLn, setOpenLn] = React.useState<boolean>(false)
|
const [openLn, setOpenLn] = React.useState<boolean>(false)
|
||||||
|
|
||||||
@ -52,6 +57,27 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
|
|||||||
loadRelays()
|
loadRelays()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const muteUser: () => void = () => {
|
||||||
|
if (publicKey && relayPool && database && user.id) {
|
||||||
|
relayPool
|
||||||
|
?.sendEvent({
|
||||||
|
content: '',
|
||||||
|
created_at: getUnixTime(new Date()),
|
||||||
|
kind: Kind.ChannelMuteUser,
|
||||||
|
pubkey: publicKey,
|
||||||
|
tags: [['p', user.id]],
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
if (database) {
|
||||||
|
updateUserMutesGroups(database, user.id, true).then(() => {
|
||||||
|
setIsMuted(true)
|
||||||
|
bottomSheetMuteRef.current?.close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const loadRelays: () => void = () => {
|
const loadRelays: () => void = () => {
|
||||||
if (database) {
|
if (database) {
|
||||||
getUserRelays(database, user.id).then((results) => {
|
getUserRelays(database, user.id).then((results) => {
|
||||||
@ -69,6 +95,7 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
|
|||||||
setUser(result)
|
setUser(result)
|
||||||
setIsContact(result.contact)
|
setIsContact(result.contact)
|
||||||
setIsBlocked(result.blocked !== undefined && result.blocked > 0)
|
setIsBlocked(result.blocked !== undefined && result.blocked > 0)
|
||||||
|
setIsMuted(result.muted_groups !== undefined && result.muted_groups > 0)
|
||||||
} else if (user.id === publicKey) {
|
} else if (user.id === publicKey) {
|
||||||
setUser({
|
setUser({
|
||||||
id: publicKey,
|
id: publicKey,
|
||||||
@ -203,12 +230,13 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
|
|||||||
<View style={styles.mainLayout}>
|
<View style={styles.mainLayout}>
|
||||||
<View style={styles.actionButton}>
|
<View style={styles.actionButton}>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={user?.blocked && user?.blocked > 0 ? 'account-cancel' : 'account-cancel-outline'}
|
icon='account-cancel-outline'
|
||||||
|
iconColor={isBlocked ? theme.colors.error : theme.colors.onSecondaryContainer}
|
||||||
size={28}
|
size={28}
|
||||||
onPress={onChangeBlockUser}
|
onPress={onChangeBlockUser}
|
||||||
/>
|
/>
|
||||||
<Text>
|
<Text style={isBlocked ? { color: theme.colors.error } : {}}>
|
||||||
{t(user?.blocked && user?.blocked > 0 ? 'profileCard.unblock' : 'profileCard.block')}
|
{t(isBlocked ? 'profileCard.blocked' : 'profileCard.block')}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.actionButton}>
|
<View style={styles.actionButton}>
|
||||||
@ -228,6 +256,20 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
|
|||||||
<Text>{t('profileCard.relaysTitle')}</Text>
|
<Text>{t('profileCard.relaysTitle')}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
<View style={styles.mainLayout}>
|
||||||
|
<View style={styles.actionButton}>
|
||||||
|
<IconButton
|
||||||
|
icon={isMuted ? 'volume-off' : 'volume-high'}
|
||||||
|
iconColor={isMuted ? theme.colors.error : theme.colors.onSecondaryContainer}
|
||||||
|
size={28}
|
||||||
|
onPress={() => !isMuted && bottomSheetMuteRef.current?.open()}
|
||||||
|
disabled={user.id === publicKey}
|
||||||
|
/>
|
||||||
|
<Text style={isMuted ? { color: theme.colors.error } : {}}>
|
||||||
|
{t(isMuted ? 'profileCard.muted' : 'profileCard.mute')}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
<RBSheet ref={bottomSheetRelaysRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
<RBSheet ref={bottomSheetRelaysRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
||||||
<View>
|
<View>
|
||||||
<Text variant='titleLarge'>{t('profileCard.relaysTitle')}</Text>
|
<Text variant='titleLarge'>{t('profileCard.relaysTitle')}</Text>
|
||||||
@ -265,6 +307,30 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
|
|||||||
<RBSheet ref={bottomSheetShareRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
<RBSheet ref={bottomSheetShareRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
||||||
<ProfileShare user={user} />
|
<ProfileShare user={user} />
|
||||||
</RBSheet>
|
</RBSheet>
|
||||||
|
<RBSheet ref={bottomSheetMuteRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
|
||||||
|
<View style={styles.muteContainer}>
|
||||||
|
<Text variant='titleLarge'>
|
||||||
|
{t('profileCard.muteUser', { username: username(user) })}
|
||||||
|
</Text>
|
||||||
|
<View style={[styles.warning, { backgroundColor: '#683D00' }]}>
|
||||||
|
<Text variant='titleSmall' style={[styles.warningTitle, { color: '#FFDCBB' }]}>
|
||||||
|
{t('profileCard.muteWarningTitle')}
|
||||||
|
</Text>
|
||||||
|
<Text style={{ color: '#FFDCBB' }}>{t('profileCard.muteWarning')}</Text>
|
||||||
|
</View>
|
||||||
|
<Button style={styles.buttonSpacer} mode='contained' onPress={muteUser}>
|
||||||
|
{t('profileCard.muteForever', { username: username(user) })}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
mode='outlined'
|
||||||
|
onPress={() => {
|
||||||
|
bottomSheetMuteRef.current?.close()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('profileCard.cancel')}
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</RBSheet>
|
||||||
<LnPayment setOpen={setOpenLn} open={openLn} user={user} />
|
<LnPayment setOpen={setOpenLn} open={openLn} user={user} />
|
||||||
{showNotification && (
|
{showNotification && (
|
||||||
<Snackbar
|
<Snackbar
|
||||||
@ -307,6 +373,22 @@ const styles = StyleSheet.create({
|
|||||||
paddingLeft: 16,
|
paddingLeft: 16,
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
|
warning: {
|
||||||
|
borderRadius: 4,
|
||||||
|
padding: 16,
|
||||||
|
marginTop: 16,
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
warningTitle: {
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
buttonSpacer: {
|
||||||
|
marginTop: 16,
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
muteContainer: {
|
||||||
|
paddingRight: 16,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default ProfileActions
|
export default ProfileActions
|
||||||
|
@ -6,6 +6,8 @@ import debounce from 'lodash.debounce'
|
|||||||
import { getActiveRelays, getRelays, Relay } from '../Functions/DatabaseFunctions/Relays'
|
import { getActiveRelays, getRelays, Relay } from '../Functions/DatabaseFunctions/Relays'
|
||||||
import { UserContext } from './UserContext'
|
import { UserContext } from './UserContext'
|
||||||
import { randomInt } from '../Functions/NativeFunctions'
|
import { randomInt } from '../Functions/NativeFunctions'
|
||||||
|
import { getUnixTime } from 'date-fns'
|
||||||
|
import { Event } from '../../lib/nostr/Events'
|
||||||
|
|
||||||
export interface RelayPoolContextProps {
|
export interface RelayPoolContextProps {
|
||||||
relayPoolReady: boolean
|
relayPoolReady: boolean
|
||||||
@ -54,6 +56,19 @@ export const RelayPoolContextProvider = ({
|
|||||||
const [relays, setRelays] = React.useState<Relay[]>([])
|
const [relays, setRelays] = React.useState<Relay[]>([])
|
||||||
const [displayRelayDrawer, setDisplayrelayDrawer] = React.useState<string>()
|
const [displayRelayDrawer, setDisplayrelayDrawer] = React.useState<string>()
|
||||||
|
|
||||||
|
const sendRelays: (relayList: Relay[]) => void = (relayList) => {
|
||||||
|
if (publicKey && relayList.length > 0) {
|
||||||
|
const event: Event = {
|
||||||
|
content: '',
|
||||||
|
created_at: getUnixTime(new Date()),
|
||||||
|
kind: 1002,
|
||||||
|
pubkey: publicKey,
|
||||||
|
tags: relayList.map((relay) => ['r', relay.url, relay.mode ?? '']),
|
||||||
|
}
|
||||||
|
relayPool?.sendEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const changeEventIdHandler: (event: WebsocketEvent) => void = (event) => {
|
const changeEventIdHandler: (event: WebsocketEvent) => void = (event) => {
|
||||||
setLastEventId(event.eventId)
|
setLastEventId(event.eventId)
|
||||||
}
|
}
|
||||||
@ -92,15 +107,15 @@ export const RelayPoolContextProvider = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadRelays: () => Promise<void> = async () => {
|
const loadRelays: () => Promise<Relay[]> = async () => {
|
||||||
return await new Promise<void>((resolve, _reject) => {
|
return await new Promise<Relay[]>((resolve, _reject) => {
|
||||||
if (database) {
|
if (database) {
|
||||||
getRelays(database).then((results) => {
|
getRelays(database).then((results) => {
|
||||||
setRelays(results)
|
setRelays(results)
|
||||||
resolve()
|
resolve(results)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
resolve()
|
resolve([])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -118,7 +133,7 @@ export const RelayPoolContextProvider = ({
|
|||||||
return await new Promise((resolve, _reject) => {
|
return await new Promise((resolve, _reject) => {
|
||||||
if (relayPool && database && publicKey) {
|
if (relayPool && database && publicKey) {
|
||||||
relayPool.update(relay.url, relay.active ?? 1, relay.global_feed ?? 1, () => {
|
relayPool.update(relay.url, relay.active ?? 1, relay.global_feed ?? 1, () => {
|
||||||
loadRelays().then(resolve)
|
loadRelays().then(() => resolve())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -129,7 +144,10 @@ export const RelayPoolContextProvider = ({
|
|||||||
return await new Promise((resolve, _reject) => {
|
return await new Promise((resolve, _reject) => {
|
||||||
if (relayPool && database && publicKey) {
|
if (relayPool && database && publicKey) {
|
||||||
relayPool.add(relay.url, () => {
|
relayPool.add(relay.url, () => {
|
||||||
loadRelays().then(resolve)
|
loadRelays().then((results) => {
|
||||||
|
sendRelays(results)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -140,7 +158,10 @@ export const RelayPoolContextProvider = ({
|
|||||||
return await new Promise((resolve, _reject) => {
|
return await new Promise((resolve, _reject) => {
|
||||||
if (relayPool && database && publicKey) {
|
if (relayPool && database && publicKey) {
|
||||||
relayPool.remove(relay.url, () => {
|
relayPool.remove(relay.url, () => {
|
||||||
loadRelays().then(resolve)
|
loadRelays().then((results) => {
|
||||||
|
sendRelays(results)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -37,9 +37,9 @@ export const updateConversationRead: (
|
|||||||
return db.execute(userQuery, [1, conversationId])
|
return db.execute(userQuery, [1, conversationId])
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateAllRead: (db: QuickSQLiteConnection) => Promise<QueryResult | null> = async (
|
export const updateAllDirectMessagesRead: (
|
||||||
db,
|
db: QuickSQLiteConnection,
|
||||||
) => {
|
) => Promise<QueryResult | null> = async (db) => {
|
||||||
const userQuery = `UPDATE nostros_direct_messages SET read = ?`
|
const userQuery = `UPDATE nostros_direct_messages SET read = ?`
|
||||||
return db.execute(userQuery, [1])
|
return db.execute(userQuery, [1])
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,13 @@ export const deleteGroup: (
|
|||||||
return db.execute(userQuery, [groupId])
|
return db.execute(userQuery, [groupId])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const updateAllDirectMessagesRead: (
|
||||||
|
db: QuickSQLiteConnection,
|
||||||
|
) => Promise<QueryResult | null> = async (db) => {
|
||||||
|
const userQuery = `UPDATE nostros_group_messages SET read = ?`
|
||||||
|
return db.execute(userQuery, [1])
|
||||||
|
}
|
||||||
|
|
||||||
export const activateGroup: (
|
export const activateGroup: (
|
||||||
db: QuickSQLiteConnection,
|
db: QuickSQLiteConnection,
|
||||||
groupId: string,
|
groupId: string,
|
||||||
|
@ -10,6 +10,7 @@ export interface Relay {
|
|||||||
global_feed?: number
|
global_feed?: number
|
||||||
resilient?: number
|
resilient?: number
|
||||||
manual?: number
|
manual?: number
|
||||||
|
mode?: 'read' | 'write' | ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RelayInfo {
|
export interface RelayInfo {
|
||||||
|
@ -14,6 +14,7 @@ export interface User {
|
|||||||
created_at?: number
|
created_at?: number
|
||||||
valid_nip05?: boolean
|
valid_nip05?: boolean
|
||||||
blocked?: number
|
blocked?: number
|
||||||
|
muted_groups?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const databaseToEntity: (object: object) => User = (object) => {
|
const databaseToEntity: (object: object) => User = (object) => {
|
||||||
@ -42,6 +43,17 @@ export const updateUserBlock: (
|
|||||||
return db.execute(userQuery, [blocked ? 1 : 0, userId])
|
return db.execute(userQuery, [blocked ? 1 : 0, userId])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const updateUserMutesGroups: (
|
||||||
|
db: QuickSQLiteConnection,
|
||||||
|
userId: string,
|
||||||
|
muted: boolean,
|
||||||
|
) => Promise<QueryResult | null> = async (db, userId, muted) => {
|
||||||
|
const userQuery = `UPDATE nostros_users SET muted_groups = ? WHERE id = ?`
|
||||||
|
|
||||||
|
await addUser(userId, db)
|
||||||
|
return db.execute(userQuery, [muted ? 1 : 0, userId])
|
||||||
|
}
|
||||||
|
|
||||||
export const getUser: (pubkey: string, db: QuickSQLiteConnection) => Promise<User | null> = async (
|
export const getUser: (pubkey: string, db: QuickSQLiteConnection) => Promise<User | null> = async (
|
||||||
pubkey,
|
pubkey,
|
||||||
db,
|
db,
|
||||||
|
@ -370,7 +370,10 @@
|
|||||||
"share": "Teilen",
|
"share": "Teilen",
|
||||||
"unblock": "Erlauben",
|
"unblock": "Erlauben",
|
||||||
"unfollow": "Abo entfernen",
|
"unfollow": "Abo entfernen",
|
||||||
"relaysTitle": "Relays"
|
"relaysTitle": "Relays",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"mute": "Mute",
|
||||||
|
"muted": "Muted"
|
||||||
},
|
},
|
||||||
"conversationsFeed": {
|
"conversationsFeed": {
|
||||||
"openMessage": "Unterhaltung beginnen",
|
"openMessage": "Unterhaltung beginnen",
|
||||||
|
@ -313,7 +313,8 @@
|
|||||||
},
|
},
|
||||||
"groupPage": {
|
"groupPage": {
|
||||||
"typeMessage": "Type message",
|
"typeMessage": "Type message",
|
||||||
"replyText": "Message"
|
"replyText": "Message",
|
||||||
|
"admin": "ADMIN"
|
||||||
},
|
},
|
||||||
"groupHeaderIcon": {
|
"groupHeaderIcon": {
|
||||||
"delete": "Leave group",
|
"delete": "Leave group",
|
||||||
@ -368,7 +369,15 @@
|
|||||||
"block": "Block",
|
"block": "Block",
|
||||||
"unblock": "Unblock",
|
"unblock": "Unblock",
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"relaysTitle": "Relays"
|
"relaysTitle": "Relays",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"mute": "Mute",
|
||||||
|
"muted": "Muted",
|
||||||
|
"muteUser": "Mute {{username}} on chats",
|
||||||
|
"muteWarningTitle": "Important",
|
||||||
|
"muteWarning": "This action will hide the messages of this user on all chats and cannot be undone.",
|
||||||
|
"muteForever": "Mute {{username}} forever",
|
||||||
|
"cancel": "Cancel"
|
||||||
},
|
},
|
||||||
"conversationsFeed": {
|
"conversationsFeed": {
|
||||||
"openMessage": "Start conversation",
|
"openMessage": "Start conversation",
|
||||||
|
@ -352,7 +352,10 @@
|
|||||||
"share": "Share",
|
"share": "Share",
|
||||||
"unblock": "Desbloquear",
|
"unblock": "Desbloquear",
|
||||||
"unfollow": "Siguiendo",
|
"unfollow": "Siguiendo",
|
||||||
"relaysTitle": "Relays"
|
"relaysTitle": "Relays",
|
||||||
|
"blocked": "Bloqueado",
|
||||||
|
"mute": "Silenciar",
|
||||||
|
"muted": "Silenciado"
|
||||||
},
|
},
|
||||||
"conversationsFeed": {
|
"conversationsFeed": {
|
||||||
"openMessage": "Comenzar conversación",
|
"openMessage": "Comenzar conversación",
|
||||||
|
@ -336,7 +336,10 @@
|
|||||||
"block": "Bloquer",
|
"block": "Bloquer",
|
||||||
"unblock": "Débloquer",
|
"unblock": "Débloquer",
|
||||||
"unfollow": "Abonné",
|
"unfollow": "Abonné",
|
||||||
"relaysTitle": "Relays"
|
"relaysTitle": "Relays",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"mute": "Mute",
|
||||||
|
"muted": "Muted"
|
||||||
},
|
},
|
||||||
"conversationsFeed": {
|
"conversationsFeed": {
|
||||||
"openMessage": "Commencer la conversation",
|
"openMessage": "Commencer la conversation",
|
||||||
|
@ -344,7 +344,10 @@
|
|||||||
"unblock": "Desbloquear",
|
"unblock": "Desbloquear",
|
||||||
"unfollow": "Following",
|
"unfollow": "Following",
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"relaysTitle": "Relays"
|
"relaysTitle": "Relays",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"mute": "Mute",
|
||||||
|
"muted": "Muted"
|
||||||
},
|
},
|
||||||
"conversationsFeed": {
|
"conversationsFeed": {
|
||||||
"openMessage": "Start conversation",
|
"openMessage": "Start conversation",
|
||||||
|
@ -350,7 +350,10 @@
|
|||||||
"share": "分享",
|
"share": "分享",
|
||||||
"copyNip05": "复制 NIP-05",
|
"copyNip05": "复制 NIP-05",
|
||||||
"copyNPub": "复制公钥",
|
"copyNPub": "复制公钥",
|
||||||
"relaysTitle": "中继"
|
"relaysTitle": "中继",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"mute": "Mute",
|
||||||
|
"muted": "Muted"
|
||||||
},
|
},
|
||||||
"conversationsFeed": {
|
"conversationsFeed": {
|
||||||
"openMessage": "发送私信",
|
"openMessage": "发送私信",
|
||||||
|
@ -18,7 +18,7 @@ import ConfigPage from '../ConfigPage'
|
|||||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
||||||
import { AppContext } from '../../Contexts/AppContext'
|
import { AppContext } from '../../Contexts/AppContext'
|
||||||
import RelayCard from '../../Components/RelayCard'
|
import RelayCard from '../../Components/RelayCard'
|
||||||
import { updateAllRead } from '../../Functions/DatabaseFunctions/DirectMessages'
|
import { updateAllDirectMessagesRead } from '../../Functions/DatabaseFunctions/DirectMessages'
|
||||||
import { getUnixTime } from 'date-fns'
|
import { getUnixTime } from 'date-fns'
|
||||||
import ContactsPage from '../ContactsPage'
|
import ContactsPage from '../ContactsPage'
|
||||||
import GroupPage from '../GroupPage'
|
import GroupPage from '../GroupPage'
|
||||||
@ -60,8 +60,13 @@ export const HomeNavigator: React.FC = () => {
|
|||||||
bottomSheetRef.current?.open()
|
bottomSheetRef.current?.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onPressCheckAll: () => void = () => {
|
const onMesssagesPressCheckAll: () => void = () => {
|
||||||
if (database) updateAllRead(database)
|
if (database) updateAllDirectMessagesRead(database)
|
||||||
|
setRefreshBottomBarAt(getUnixTime(new Date()))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onGroupsPressCheckAll: () => void = () => {
|
||||||
|
if (database) updateAllDirectMessagesRead(database)
|
||||||
setRefreshBottomBarAt(getUnixTime(new Date()))
|
setRefreshBottomBarAt(getUnixTime(new Date()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +124,18 @@ export const HomeNavigator: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{['Landing'].includes(route.name) && historyKey?.includes('messages-') && (
|
{['Landing'].includes(route.name) && historyKey?.includes('messages-') && (
|
||||||
<Appbar.Action icon='check-all' isLeading onPress={() => onPressCheckAll()} />
|
<Appbar.Action
|
||||||
|
icon='check-all'
|
||||||
|
isLeading
|
||||||
|
onPress={() => onMesssagesPressCheckAll()}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{['Landing'].includes(route.name) && historyKey?.includes('groups-') && (
|
||||||
|
<Appbar.Action
|
||||||
|
icon='check-all'
|
||||||
|
isLeading
|
||||||
|
onPress={() => onGroupsPressCheckAll()}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{['Group'].includes(route.name) && (
|
{['Group'].includes(route.name) && (
|
||||||
<GroupHeaderIcon groupId={route.params?.groupId} />
|
<GroupHeaderIcon groupId={route.params?.groupId} />
|
||||||
|
@ -32,7 +32,9 @@ import { handleInfinityScroll } from '../../Functions/NativeFunctions'
|
|||||||
import NostrosAvatar from '../../Components/NostrosAvatar'
|
import NostrosAvatar from '../../Components/NostrosAvatar'
|
||||||
import UploadImage from '../../Components/UploadImage'
|
import UploadImage from '../../Components/UploadImage'
|
||||||
import {
|
import {
|
||||||
|
getGroup,
|
||||||
getGroupMessages,
|
getGroupMessages,
|
||||||
|
Group,
|
||||||
GroupMessage,
|
GroupMessage,
|
||||||
updateGroupRead,
|
updateGroupRead,
|
||||||
} from '../../Functions/DatabaseFunctions/Groups'
|
} from '../../Functions/DatabaseFunctions/Groups'
|
||||||
@ -53,6 +55,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
|||||||
const { relayPool, lastEventId } = useContext(RelayPoolContext)
|
const { relayPool, lastEventId } = useContext(RelayPoolContext)
|
||||||
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
|
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
|
||||||
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
||||||
|
const [group, setGroup] = useState<Group>()
|
||||||
const [groupMessages, setGroupMessages] = useState<GroupMessage[]>([])
|
const [groupMessages, setGroupMessages] = useState<GroupMessage[]>([])
|
||||||
const [sendingMessages, setSendingMessages] = useState<GroupMessage[]>([])
|
const [sendingMessages, setSendingMessages] = useState<GroupMessage[]>([])
|
||||||
const [reply, setReply] = useState<GroupMessage>()
|
const [reply, setReply] = useState<GroupMessage>()
|
||||||
@ -82,6 +85,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
|||||||
|
|
||||||
const loadGroupMessages: (subscribe: boolean) => void = (subscribe) => {
|
const loadGroupMessages: (subscribe: boolean) => void = (subscribe) => {
|
||||||
if (database && publicKey && route.params.groupId) {
|
if (database && publicKey && route.params.groupId) {
|
||||||
|
getGroup(database, route.params.groupId).then(setGroup)
|
||||||
updateGroupRead(database, route.params.groupId)
|
updateGroupRead(database, route.params.groupId)
|
||||||
getGroupMessages(database, route.params.groupId, {
|
getGroupMessages(database, route.params.groupId, {
|
||||||
order: 'DESC',
|
order: 'DESC',
|
||||||
@ -294,6 +298,11 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.cardContentDate}>
|
<View style={styles.cardContentDate}>
|
||||||
|
{item.pubkey === group?.pubkey && (
|
||||||
|
<View style={[styles.warning, { backgroundColor: '#683D00' }]}>
|
||||||
|
<Text style={{ color: '#FFDCBB' }}>{t('groupPage.admin')}</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
{message?.pending && (
|
{message?.pending && (
|
||||||
<View style={styles.cardContentPending}>
|
<View style={styles.cardContentPending}>
|
||||||
<MaterialCommunityIcons
|
<MaterialCommunityIcons
|
||||||
@ -589,6 +598,12 @@ const styles = StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
paddingLeft: 16,
|
paddingLeft: 16,
|
||||||
},
|
},
|
||||||
|
warning: {
|
||||||
|
borderRadius: 4,
|
||||||
|
paddingLeft: 5,
|
||||||
|
paddingRight: 5,
|
||||||
|
marginRight: 5,
|
||||||
|
},
|
||||||
input: {
|
input: {
|
||||||
flexDirection: 'column-reverse',
|
flexDirection: 'column-reverse',
|
||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
|
@ -96,11 +96,10 @@ export const GroupsFeed: React.FC = () => {
|
|||||||
results.forEach((group) => {
|
results.forEach((group) => {
|
||||||
if (group.id) {
|
if (group.id) {
|
||||||
getGroupMessagesMentionsCount(database, group.id).then((count) => {
|
getGroupMessagesMentionsCount(database, group.id).then((count) => {
|
||||||
if (count > 0)
|
setNewMentions((prev) => {
|
||||||
setNewMentions((prev) => {
|
if (group.id) prev[group.id] = count
|
||||||
if (group.id) prev[group.id] = count
|
return prev
|
||||||
return prev
|
})
|
||||||
})
|
|
||||||
})
|
})
|
||||||
getGroupMessagesCount(database, group.id).then((count) => {
|
getGroupMessagesCount(database, group.id).then((count) => {
|
||||||
setNewMessage((prev) => {
|
setNewMessage((prev) => {
|
||||||
|
@ -58,7 +58,7 @@ export const ProfileLoadPage: React.FC = () => {
|
|||||||
if (publicKey && relayPoolReady) {
|
if (publicKey && relayPoolReady) {
|
||||||
relayPool?.subscribe('profile-load-meta', [
|
relayPool?.subscribe('profile-load-meta', [
|
||||||
{
|
{
|
||||||
kinds: [Kind.Contacts, Kind.Metadata],
|
kinds: [Kind.Contacts, Kind.Metadata, Kind.ChannelCreation, Kind.ChannelMetadata, 1002],
|
||||||
authors: [publicKey],
|
authors: [publicKey],
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
@ -2,7 +2,7 @@ import React, { useContext, useState } from 'react'
|
|||||||
import { FlatList, ListRenderItem, ScrollView, StyleSheet, View } from 'react-native'
|
import { FlatList, ListRenderItem, ScrollView, StyleSheet, View } from 'react-native'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
|
||||||
import { getRelays, Relay } from '../../Functions/DatabaseFunctions/Relays'
|
import { Relay } from '../../Functions/DatabaseFunctions/Relays'
|
||||||
import { REGEX_SOCKET_LINK } from '../../Constants/Relay'
|
import { REGEX_SOCKET_LINK } from '../../Constants/Relay'
|
||||||
import {
|
import {
|
||||||
List,
|
List,
|
||||||
@ -20,48 +20,38 @@ import RBSheet from 'react-native-raw-bottom-sheet'
|
|||||||
import { relayToColor } from '../../Functions/NativeFunctions'
|
import { relayToColor } from '../../Functions/NativeFunctions'
|
||||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||||
import { useFocusEffect } from '@react-navigation/native'
|
import { useFocusEffect } from '@react-navigation/native'
|
||||||
import { AppContext } from '../../Contexts/AppContext'
|
import { UserContext } from '../../Contexts/UserContext'
|
||||||
|
|
||||||
export const defaultRelays = [
|
|
||||||
'wss://brb.io',
|
|
||||||
'wss://damus.io',
|
|
||||||
'wss://nostr-pub.wellorder.net',
|
|
||||||
'wss://nostr.swiss-enigma.ch',
|
|
||||||
'wss://nostr.onsats.org',
|
|
||||||
'wss://nostr-pub.semisol.dev',
|
|
||||||
'wss://nostr.openchain.fr',
|
|
||||||
'wss://relay.nostr.info',
|
|
||||||
'wss://nostr.oxtr.dev',
|
|
||||||
'wss://nostr.ono.re',
|
|
||||||
'wss://relay.grunch.dev',
|
|
||||||
'wss://nostr.developer.li',
|
|
||||||
]
|
|
||||||
|
|
||||||
export const RelaysPage: React.FC = () => {
|
export const RelaysPage: React.FC = () => {
|
||||||
const defaultRelayInput = React.useMemo(() => 'wss://', [])
|
const defaultRelayInput = React.useMemo(() => 'wss://', [])
|
||||||
const { updateRelayItem, addRelayItem, relayPool, setDisplayrelayDrawer } =
|
const { updateRelayItem, addRelayItem, relayPool, setDisplayrelayDrawer, relays } =
|
||||||
useContext(RelayPoolContext)
|
useContext(RelayPoolContext)
|
||||||
const { database } = useContext(AppContext)
|
const { publicKey } = useContext(UserContext)
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const bottomSheetAddRef = React.useRef<RBSheet>(null)
|
const bottomSheetAddRef = React.useRef<RBSheet>(null)
|
||||||
const bottomSheetResilenseRef = React.useRef<RBSheet>(null)
|
const bottomSheetResilenseRef = React.useRef<RBSheet>(null)
|
||||||
const [relays, setRelays] = React.useState<Relay[]>([])
|
|
||||||
const [addRelayInput, setAddRelayInput] = useState<string>(defaultRelayInput)
|
const [addRelayInput, setAddRelayInput] = useState<string>(defaultRelayInput)
|
||||||
const [showNotification, setShowNotification] = useState<string>()
|
const [showNotification, setShowNotification] = useState<string>()
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
React.useCallback(() => {
|
React.useCallback(() => {
|
||||||
relayPool?.unsubscribeAll()
|
relayPool?.unsubscribeAll()
|
||||||
updateRelays()
|
if (publicKey) {
|
||||||
|
relayPool?.subscribe('relays', [
|
||||||
|
{
|
||||||
|
kinds: [1002],
|
||||||
|
authors: [publicKey],
|
||||||
|
limit: 1,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
return () => {}
|
return () => relayPool?.unsubscribe(['relays'])
|
||||||
}, []),
|
}, []),
|
||||||
)
|
)
|
||||||
|
|
||||||
const updateRelays: () => void = () => {
|
React.useEffect(() => {}, [relays])
|
||||||
if (database) getRelays(database).then(setRelays)
|
|
||||||
}
|
|
||||||
|
|
||||||
const addRelay: (url: string) => void = (url) => {
|
const addRelay: (url: string) => void = (url) => {
|
||||||
if (!relayList.find((relay) => relay.url === url)) {
|
if (!relayList.find((relay) => relay.url === url)) {
|
||||||
@ -70,7 +60,6 @@ export const RelaysPage: React.FC = () => {
|
|||||||
active: 1,
|
active: 1,
|
||||||
global_feed: 1,
|
global_feed: 1,
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
updateRelays()
|
|
||||||
setShowNotification('add')
|
setShowNotification('add')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -79,7 +68,6 @@ export const RelaysPage: React.FC = () => {
|
|||||||
const activeRelay: (relay: Relay) => void = (relay) => {
|
const activeRelay: (relay: Relay) => void = (relay) => {
|
||||||
relay.active = 1
|
relay.active = 1
|
||||||
updateRelayItem(relay).then(() => {
|
updateRelayItem(relay).then(() => {
|
||||||
updateRelays()
|
|
||||||
setShowNotification('active')
|
setShowNotification('active')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -88,7 +76,6 @@ export const RelaysPage: React.FC = () => {
|
|||||||
relay.active = 0
|
relay.active = 0
|
||||||
relay.global_feed = 0
|
relay.global_feed = 0
|
||||||
updateRelayItem(relay).then(() => {
|
updateRelayItem(relay).then(() => {
|
||||||
updateRelays()
|
|
||||||
setShowNotification('desactive')
|
setShowNotification('desactive')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -97,7 +84,6 @@ export const RelaysPage: React.FC = () => {
|
|||||||
relay.active = 1
|
relay.active = 1
|
||||||
relay.global_feed = 1
|
relay.global_feed = 1
|
||||||
updateRelayItem(relay).then(() => {
|
updateRelayItem(relay).then(() => {
|
||||||
updateRelays()
|
|
||||||
setShowNotification('globalFeedActive')
|
setShowNotification('globalFeedActive')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -105,7 +91,6 @@ export const RelaysPage: React.FC = () => {
|
|||||||
const desactiveGlobalFeedRelay: (relay: Relay) => void = (relay) => {
|
const desactiveGlobalFeedRelay: (relay: Relay) => void = (relay) => {
|
||||||
relay.global_feed = 0
|
relay.global_feed = 0
|
||||||
updateRelayItem(relay).then(() => {
|
updateRelayItem(relay).then(() => {
|
||||||
updateRelays()
|
|
||||||
setShowNotification('globalFeedActiveUnactive')
|
setShowNotification('globalFeedActiveUnactive')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -145,8 +130,6 @@ export const RelaysPage: React.FC = () => {
|
|||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const myRelays = relayList.filter((relay) => !defaultRelays.includes(relay.url))
|
|
||||||
|
|
||||||
const renderItem: ListRenderItem<Relay> = ({ item, index }) => {
|
const renderItem: ListRenderItem<Relay> = ({ item, index }) => {
|
||||||
return (
|
return (
|
||||||
<List.Item
|
<List.Item
|
||||||
@ -200,7 +183,7 @@ export const RelaysPage: React.FC = () => {
|
|||||||
right={() => (
|
right={() => (
|
||||||
<>
|
<>
|
||||||
{type === 'centralized' && (
|
{type === 'centralized' && (
|
||||||
<Text style={[styles.smallRelay, { color: theme.colors.errorContainer }]}>
|
<Text style={[styles.smallRelay, { color: theme.colors.error }]}>
|
||||||
{relayPool?.resilientAssignation.centralizedRelays[item] &&
|
{relayPool?.resilientAssignation.centralizedRelays[item] &&
|
||||||
t('relaysPage.centralized')}
|
t('relaysPage.centralized')}
|
||||||
</Text>
|
</Text>
|
||||||
@ -258,33 +241,9 @@ export const RelaysPage: React.FC = () => {
|
|||||||
data={Object.keys(relayPool?.resilientAssignation.smallRelays ?? {})}
|
data={Object.keys(relayPool?.resilientAssignation.smallRelays ?? {})}
|
||||||
renderItem={(data) => renderResilienceItem(data.item, data.index, 'small')}
|
renderItem={(data) => renderResilienceItem(data.item, data.index, 'small')}
|
||||||
/>
|
/>
|
||||||
{myRelays.length > 0 && (
|
|
||||||
<>
|
|
||||||
<View style={styles.titleWrapper}>
|
|
||||||
<Text style={styles.title} variant='titleMedium'>
|
|
||||||
{t('relaysPage.myList')}
|
|
||||||
</Text>
|
|
||||||
<Divider />
|
|
||||||
</View>
|
|
||||||
<List.Item
|
|
||||||
title={t('relaysPage.relayName')}
|
|
||||||
right={() => (
|
|
||||||
<>
|
|
||||||
<Text style={styles.listHeader}>{t('relaysPage.globalFeed')}</Text>
|
|
||||||
<Text style={styles.listHeader}>{t('relaysPage.active')}</Text>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FlatList
|
|
||||||
showsVerticalScrollIndicator={false}
|
|
||||||
data={myRelays}
|
|
||||||
renderItem={renderItem}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<View style={styles.titleWrapper}>
|
<View style={styles.titleWrapper}>
|
||||||
<Text style={styles.title} variant='titleMedium'>
|
<Text style={styles.title} variant='titleMedium'>
|
||||||
{t('relaysPage.recommended')}
|
{t('relaysPage.myList')}
|
||||||
</Text>
|
</Text>
|
||||||
<Divider />
|
<Divider />
|
||||||
</View>
|
</View>
|
||||||
@ -297,17 +256,7 @@ export const RelaysPage: React.FC = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<FlatList
|
<FlatList showsVerticalScrollIndicator={false} data={relays} renderItem={renderItem} />
|
||||||
showsVerticalScrollIndicator={false}
|
|
||||||
data={defaultRelays.map(
|
|
||||||
(url) =>
|
|
||||||
relays.find((relay) => relay.url === url && relay.active && relay.active > 0) ?? {
|
|
||||||
url,
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
renderItem={renderItem}
|
|
||||||
style={styles.list}
|
|
||||||
/>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<AnimatedFAB
|
<AnimatedFAB
|
||||||
style={styles.fab}
|
style={styles.fab}
|
||||||
|
Loading…
Reference in New Issue
Block a user