mirror of
https://github.com/KoalaSat/nostros.git
synced 2024-09-29 06:30:47 +00:00
Merge branch 'main' into dependabot/npm_and_yarn/react-native-0.64.3
This commit is contained in:
commit
c29931ab63
@ -1 +0,0 @@
|
|||||||
|
|
29
README.md
29
README.md
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
![nostros_logo](https://user-images.githubusercontent.com/111684255/197588983-2a196d74-0f1e-45e8-be56-0da8c1602835.png)
|
![nostros_logo](https://user-images.githubusercontent.com/111684255/197588983-2a196d74-0f1e-45e8-be56-0da8c1602835.png)
|
||||||
|
|
||||||
Wellcome to the NOSTROS project.
|
Wellcome to the NOSTROS project.
|
||||||
|
|
||||||
# Getting Started
|
# Getting Started
|
||||||
|
|
||||||
## Required Libraries and Frameworks
|
## Required Libraries and Frameworks
|
||||||
|
|
||||||
- Node 16.x
|
- Node 16.x
|
||||||
- JDK 17.0.x
|
- JDK 17.0.x
|
||||||
- (Android) Android Studio SKD
|
- (Android) Android Studio SKD
|
||||||
@ -16,41 +17,61 @@ Wellcome to the NOSTROS project.
|
|||||||
|
|
||||||
- Open a virtual device
|
- Open a virtual device
|
||||||
- Install
|
- Install
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
- Run Metro
|
- Run Metro
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn start
|
yarn start
|
||||||
```
|
```
|
||||||
|
|
||||||
# Some Features to Work On
|
# Some Features to Work On
|
||||||
|
|
||||||
### Bugs
|
### Bugs
|
||||||
|
|
||||||
- [ ] User info missing on first start
|
- [ ] User info missing on first start
|
||||||
- [ ] i18n not loading
|
- [ ] i18n not loading
|
||||||
- [ ] Logging out and in again does not work
|
- [ ] Logging out and in again does not work
|
||||||
- [ ] Clipboard library not working
|
- [ ] Clipboard library not working
|
||||||
|
|
||||||
### Basics
|
### Basics
|
||||||
|
|
||||||
- [ ] Infinite Load
|
- [ ] Infinite Load
|
||||||
- [ ] Go to replied event
|
- [ ] Go to replied event
|
||||||
- [ ] Relays management (add, remove and recomend)
|
- [ ] Relays management (add, remove and recomend)
|
||||||
- [ ] Random Key Generator
|
- [ ] Random Key Generator
|
||||||
|
|
||||||
### Home
|
### Home
|
||||||
|
|
||||||
- [ ] Public Room
|
- [ ] Public Room
|
||||||
- [ ] Other Rooms
|
- [ ] Other Rooms
|
||||||
### Profile
|
|
||||||
- [ ] Verify NIP-05
|
### Profile
|
||||||
|
|
||||||
|
- [ ] Verify NIP-05 https://github.com/nostr-protocol/nips/blob/master/05.md
|
||||||
- [ ] Verify LNURL https://github.com/andrerfneves/lightning-address
|
- [ ] Verify LNURL https://github.com/andrerfneves/lightning-address
|
||||||
|
|
||||||
### Contacts
|
### Contacts
|
||||||
|
|
||||||
- [ ] Direct Messages https://github.com/nostr-protocol/nips/blob/master/04.md
|
- [ ] Direct Messages https://github.com/nostr-protocol/nips/blob/master/04.md
|
||||||
|
|
||||||
### Note
|
### Note
|
||||||
|
- [ ] Autoscroll to reply
|
||||||
- [ ] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
|
- [ ] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
|
||||||
- [ ] Reactions https://github.com/nostr-protocol/nips/blob/master/25.md
|
- [ ] Reactions https://github.com/nostr-protocol/nips/blob/master/25.md
|
||||||
- [ ] Deletion https://github.com/nostr-protocol/nips/blob/master/09.md
|
- [ ] Deletion https://github.com/nostr-protocol/nips/blob/master/09.md
|
||||||
- [ ] Tag Users https://github.com/nostr-protocol/nips/blob/master/10.md
|
- [ ] Tag Users https://github.com/nostr-protocol/nips/blob/master/10.md
|
||||||
|
- [ ] Load entire thread
|
||||||
|
|
||||||
### Send
|
### Send
|
||||||
|
|
||||||
- [ ] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
|
- [ ] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
|
||||||
|
|
||||||
### Config
|
### Config
|
||||||
|
|
||||||
- [ ] Private Key download
|
- [ ] Private Key download
|
||||||
|
|
||||||
# Kudos
|
# Kudos
|
||||||
@ -58,6 +79,6 @@ yarn start
|
|||||||
- Inspired on https://github.com/jb55/nostr-js and https://github.com/fiatjaf/nostr-tools
|
- Inspired on https://github.com/jb55/nostr-js and https://github.com/fiatjaf/nostr-tools
|
||||||
- Discovered thanks to https://lunaticoin.com
|
- Discovered thanks to https://lunaticoin.com
|
||||||
|
|
||||||
------
|
---
|
||||||
|
|
||||||
Made with 🐨 by https://getalby.com/p/koalasat
|
Made with 🐨 by https://getalby.com/p/koalasat
|
||||||
|
@ -16,20 +16,24 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
|||||||
|
|
||||||
export const ConfigPage: React.FC = () => {
|
export const ConfigPage: React.FC = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { setPage, page, database } = useContext(AppContext);
|
const { setPage, database } = useContext(AppContext);
|
||||||
const { setPrivateKey } = useContext(RelayPoolContext);
|
const { setPrivateKey, relayPool, publicKey } = useContext(RelayPoolContext);
|
||||||
const { t } = useTranslation('common');
|
const { t } = useTranslation('common');
|
||||||
const breadcrump = page.split('%');
|
|
||||||
|
|
||||||
const onPressBack: () => void = () => {
|
const onPressBack: () => void = () => {
|
||||||
setPage(breadcrump.slice(0, -1).join('%'));
|
if (publicKey) {
|
||||||
|
setPage(`profile#${publicKey}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPressLogout: () => void = () => {
|
const onPressLogout: () => void = () => {
|
||||||
setPrivateKey('')
|
|
||||||
EncryptedStorage.removeItem('privateKey');
|
|
||||||
if (database) {
|
if (database) {
|
||||||
dropTables(database).then(() => setPage('landing'))
|
dropTables(database).then(() => {
|
||||||
|
setPrivateKey('');
|
||||||
|
relayPool?.unsubscribeAll();
|
||||||
|
EncryptedStorage.removeItem('privateKey');
|
||||||
|
setPage('landing');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,7 +71,9 @@ export const ConfigPage: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
onPress={onPressLogout}
|
onPress={onPressLogout}
|
||||||
status='danger'
|
status='danger'
|
||||||
accessoryLeft={<Icon name='power-off' size={16} color={theme['text-basic-color']} solid />}
|
accessoryLeft={
|
||||||
|
<Icon name='power-off' size={16} color={theme['text-basic-color']} solid />
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{t('configPage.logout')}
|
{t('configPage.logout')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -6,7 +6,12 @@ import { AppContext } from '../../Contexts/AppContext';
|
|||||||
import Icon from 'react-native-vector-icons/FontAwesome5';
|
import Icon from 'react-native-vector-icons/FontAwesome5';
|
||||||
import { Event, EventKind } from '../../lib/nostr/Events';
|
import { Event, EventKind } from '../../lib/nostr/Events';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { addContact, getUsers, insertUserContact, User } from '../../Functions/DatabaseFunctions/Users';
|
import {
|
||||||
|
addContact,
|
||||||
|
getUsers,
|
||||||
|
insertUserContact,
|
||||||
|
User,
|
||||||
|
} from '../../Functions/DatabaseFunctions/Users';
|
||||||
import UserCard from '../UserCard';
|
import UserCard from '../UserCard';
|
||||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
||||||
import Relay from '../../lib/nostr/Relay';
|
import Relay from '../../lib/nostr/Relay';
|
||||||
@ -22,7 +27,7 @@ export const ContactsPage: React.FC = () => {
|
|||||||
const { t } = useTranslation('common');
|
const { t } = useTranslation('common');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (database) {
|
if (database && publicKey) {
|
||||||
getUsers(database, { contacts: true }).then((results) => {
|
getUsers(database, { contacts: true }).then((results) => {
|
||||||
if (results) {
|
if (results) {
|
||||||
setUsers(results);
|
setUsers(results);
|
||||||
@ -37,19 +42,18 @@ export const ContactsPage: React.FC = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
relayPool?.on('event', 'contacts', (relay: Relay, _subId?: string, event?: Event) => {
|
relayPool?.on('event', 'contacts', (relay: Relay, _subId?: string, event?: Event) => {
|
||||||
console.log('RELAYPOOL EVENT =======>', relay.url, event);
|
console.log('RELAYPOOL EVENT =======>', relay.url, event);
|
||||||
if (database && event?.id && event.kind === EventKind.petNames) {
|
if (database && event?.id && event.kind === EventKind.petNames) {
|
||||||
insertUserContact(event, database).finally(() => setLastEventId(event?.id ?? ''));
|
insertUserContact(event, database).finally(() => setLastEventId(event?.id ?? ''));
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
}, []);
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onPressAddContact: () => void = () => {
|
const onPressAddContact: () => void = () => {
|
||||||
if (contactInput && relayPool && database) {
|
if (contactInput && relayPool && database && publicKey) {
|
||||||
addContact(contactInput, database).then(() => {
|
addContact(contactInput, database).then(() => {
|
||||||
populatePets(relayPool, database, publicKey)
|
populatePets(relayPool, database, publicKey);
|
||||||
setShowAddContant(false)
|
setShowAddContant(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -125,4 +129,3 @@ export const ContactsPage: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default ContactsPage;
|
export default ContactsPage;
|
||||||
|
|
||||||
|
@ -31,17 +31,17 @@ export const HomePage: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const subscribeNotes: () => void = () => {
|
const subscribeNotes: () => void = () => {
|
||||||
if (database) {
|
if (database && publicKey) {
|
||||||
getNotes(database, { limit: 1 }).then((notes) => {
|
getNotes(database, { limit: 1 }).then((notes) => {
|
||||||
getUsers(database, { contacts: true }).then((users) => {
|
getUsers(database, { contacts: true }).then((users) => {
|
||||||
setTotalContacts(users.length)
|
setTotalContacts(users.length);
|
||||||
let message: RelayFilters = {
|
let message: RelayFilters = {
|
||||||
kinds: [EventKind.textNote, EventKind.recommendServer],
|
kinds: [EventKind.textNote, EventKind.recommendServer],
|
||||||
authors: [publicKey, ...users.map((user) => user.id)],
|
authors: [publicKey, ...users.map((user) => user.id)],
|
||||||
limit: 20,
|
limit: 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (notes.length > 0) {
|
if (notes.length >= 20) {
|
||||||
message = {
|
message = {
|
||||||
...message,
|
...message,
|
||||||
since: notes[0].created_at,
|
since: notes[0].created_at,
|
||||||
@ -55,7 +55,7 @@ export const HomePage: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadNotes()
|
loadNotes();
|
||||||
}, [lastEventId]);
|
}, [lastEventId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -5,25 +5,21 @@ import Loading from '../Loading';
|
|||||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { tagToUser } from '../../Functions/RelayFunctions/Users';
|
import { tagToUser } from '../../Functions/RelayFunctions/Users';
|
||||||
import Relay, { RelayFilters } from '../../lib/nostr/Relay';
|
import Relay from '../../lib/nostr/Relay';
|
||||||
import { Event, EventKind } from '../../lib/nostr/Events';
|
import { Event, EventKind } from '../../lib/nostr/Events';
|
||||||
import { AppContext } from '../../Contexts/AppContext';
|
import { AppContext } from '../../Contexts/AppContext';
|
||||||
import { getUsers, insertUserContact } from '../../Functions/DatabaseFunctions/Users';
|
import { insertUserContact } from '../../Functions/DatabaseFunctions/Users';
|
||||||
import { getPublickey } from '../../lib/nostr/Bip';
|
|
||||||
import EncryptedStorage from 'react-native-encrypted-storage';
|
import EncryptedStorage from 'react-native-encrypted-storage';
|
||||||
import { SQLiteDatabase } from 'react-native-sqlite-storage';
|
|
||||||
|
|
||||||
export const LandingPage: React.FC = () => {
|
export const LandingPage: React.FC = () => {
|
||||||
const { privateKey, setPrivateKey, publicKey, setPublicKey, relayPool, initRelays } =
|
const { database, setPage } = useContext(AppContext);
|
||||||
useContext(RelayPoolContext);
|
const { privateKey, publicKey, relayPool, setPrivateKey } = useContext(RelayPoolContext);
|
||||||
const { database, setPage, runMigrations, loadingDb } = useContext(AppContext);
|
|
||||||
const { t } = useTranslation('common');
|
const { t } = useTranslation('common');
|
||||||
const [init, setInit] = useState<boolean>(true);
|
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [status, setStatus] = useState<number>(0);
|
const [status, setStatus] = useState<number>(0);
|
||||||
const [totalPets, setTotalPets] = useState<number>();
|
const [totalPets, setTotalPets] = useState<number>();
|
||||||
const [loadedUsers, setLoadedUsers] = useState<number>(0);
|
const [inputValue, setInputValue] = useState<string>('');
|
||||||
const [usersReady, setUsersReady] = useState<boolean>(false);
|
const [loadedUsers, setLoadedUsers] = useState<number>();
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
tab: {
|
tab: {
|
||||||
height: '100%',
|
height: '100%',
|
||||||
@ -45,110 +41,83 @@ export const LandingPage: React.FC = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => { // #1 STEP
|
useEffect(() => {
|
||||||
if (init) {
|
if (relayPool && publicKey) {
|
||||||
EncryptedStorage.getItem('privateKey').then((result) => {
|
setStatus(1);
|
||||||
if (result && result !== '') {
|
initEvents();
|
||||||
setPrivateKey(result);
|
relayPool?.subscribe('main-channel', {
|
||||||
setPublicKey(getPublickey(result));
|
kinds: [EventKind.petNames],
|
||||||
setUsersReady(true);
|
authors: [publicKey],
|
||||||
} if (!loadingDb) {
|
|
||||||
setInit(false);
|
|
||||||
} else {
|
|
||||||
runMigrations();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [init, relayPool, loadingDb]);
|
}, [relayPool, publicKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (usersReady && relayPool && !loadingDb) {
|
if (status > 2) {
|
||||||
initRelays()
|
relayPool?.removeOn('event', 'landing');
|
||||||
setPage('home');
|
setPage('home');
|
||||||
}
|
}
|
||||||
}, [usersReady, relayPool]);
|
}, [status]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (loading && publicKey !== '') {
|
if (loadedUsers) {
|
||||||
initEvents();
|
const timer = setTimeout(() => setStatus(3), 4000);
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}, [loading, publicKey]);
|
}, [loadedUsers]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (loading && loadedUsers) {
|
|
||||||
loadUsers();
|
|
||||||
}
|
|
||||||
}, [loading, totalPets, loadedUsers]);
|
|
||||||
|
|
||||||
const initEvents: () => void = () => {
|
const initEvents: () => void = () => {
|
||||||
relayPool?.on('event', 'landing', (_relay: Relay, _subId?: string, event?: Event) => {
|
relayPool?.on('event', 'landing', (_relay: Relay, _subId?: string, event?: Event) => {
|
||||||
if (database && event) {
|
console.log('LandingPage EVENT =======>', event);
|
||||||
|
if (event && database) {
|
||||||
if (event.kind === EventKind.petNames) {
|
if (event.kind === EventKind.petNames) {
|
||||||
loadPets(event);
|
loadPets(event);
|
||||||
} else {
|
} else if (event.kind === EventKind.meta) {
|
||||||
if (event.kind === EventKind.meta && event.pubkey !== publicKey) {
|
setLoadedUsers((prev) => (prev ? prev + 1 : 1));
|
||||||
setLoadedUsers((prev) => prev + 1)
|
if (loadedUsers && loadedUsers - 1 === totalPets) setStatus(3);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
relayPool?.subscribe('main-channel', {
|
|
||||||
kinds: [EventKind.meta, EventKind.petNames],
|
|
||||||
authors: [publicKey],
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadPets: (event: Event) => void = (event) => {
|
const loadPets: (event: Event) => void = (event) => {
|
||||||
if (database) {
|
if (database) {
|
||||||
setTotalPets(event.tags.length);
|
setTotalPets(event.tags.length);
|
||||||
insertUserContact(event, database).then(() => {
|
if (event.tags.length > 0) {
|
||||||
relayPool?.subscribe('main-channel', {
|
setStatus(2);
|
||||||
kinds: [EventKind.meta],
|
insertUserContact(event, database).then(() => {
|
||||||
authors: event.tags.map((tag) => tagToUser(tag).id),
|
requestUserData(event);
|
||||||
});
|
});
|
||||||
})
|
} else {
|
||||||
setStatus(2);
|
setStatus(3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const requestUsers: (database: SQLiteDatabase) => void = () => {
|
const requestUserData: (event: Event) => void = (event) => {
|
||||||
if (database && status < 3) {
|
if (publicKey) {
|
||||||
setUsersReady(true);
|
const authors: string[] = [publicKey, ...event.tags.map((tag) => tagToUser(tag).id)];
|
||||||
getUsers(database, { exludeIds: [publicKey], contacts: true }).then((users) => {
|
relayPool?.subscribe('main-channel', {
|
||||||
const message: RelayFilters = {
|
kinds: [EventKind.meta],
|
||||||
kinds: [EventKind.textNote, EventKind.recommendServer],
|
authors,
|
||||||
authors: [publicKey, ...users.map((user) => user.id)],
|
|
||||||
limit: 15,
|
|
||||||
};
|
|
||||||
relayPool?.subscribe('main-channel', message);
|
|
||||||
setStatus(3);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadUsers: () => void = () => {
|
|
||||||
if (database) {
|
|
||||||
getUsers(database, { exludeIds: [publicKey], contacts: true }).then((users) => {
|
|
||||||
if (loadedUsers === totalPets) {
|
|
||||||
requestUsers(database)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
setTimeout(() => requestUsers(database), 10000);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPress: () => void = () => {
|
const onPress: () => void = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setPublicKey(getPublickey(privateKey));
|
setPrivateKey(inputValue);
|
||||||
setStatus(1);
|
setStatus(1);
|
||||||
EncryptedStorage.setItem('privateKey', privateKey);
|
EncryptedStorage.setItem('privateKey', inputValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusName: { [status: number]: string } = {
|
const statusName: { [status: number]: string } = {
|
||||||
0: t('landing.connect'),
|
0: t('landing.connect'),
|
||||||
1: t('landing.connecting'),
|
1: t('landing.connecting'),
|
||||||
2: `${t('landing.loadingContacts')} ${loadedUsers}/${totalPets ?? 0}`,
|
2: t('landing.loadingContacts'),
|
||||||
3: t('landing.loadingTimeline'),
|
3: t('landing.ready'),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -159,15 +128,15 @@ export const LandingPage: React.FC = () => {
|
|||||||
<Text style={styles.title} category='h1'>
|
<Text style={styles.title} category='h1'>
|
||||||
NOSTROS
|
NOSTROS
|
||||||
</Text>
|
</Text>
|
||||||
{!init && (
|
{(!privateKey || status !== 0) && (
|
||||||
<>
|
<>
|
||||||
<Input
|
<Input
|
||||||
style={styles.input}
|
style={styles.input}
|
||||||
size='medium'
|
size='medium'
|
||||||
label={t('landing.privateKey')}
|
label={t('landing.privateKey')}
|
||||||
secureTextEntry={true}
|
secureTextEntry={true}
|
||||||
onChangeText={setPrivateKey}
|
onChangeText={setInputValue}
|
||||||
value={privateKey}
|
value={inputValue}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
/>
|
/>
|
||||||
<Button onPress={onPress} disabled={loading}>
|
<Button onPress={onPress} disabled={loading}>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useState } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { Layout } from '@ui-kitten/components';
|
import { Layout } from '@ui-kitten/components';
|
||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
import { AppContext } from '../../Contexts/AppContext';
|
import { AppContext } from '../../Contexts/AppContext';
|
||||||
@ -9,13 +9,10 @@ import SendPage from '../SendPage';
|
|||||||
import ContactsPage from '../ContactsPage';
|
import ContactsPage from '../ContactsPage';
|
||||||
import NotePage from '../NotePage';
|
import NotePage from '../NotePage';
|
||||||
import LandingPage from '../LandingPage';
|
import LandingPage from '../LandingPage';
|
||||||
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
|
|
||||||
import ConfigPage from '../ConfigPage';
|
import ConfigPage from '../ConfigPage';
|
||||||
|
|
||||||
export const MainLayout: React.FC = () => {
|
export const MainLayout: React.FC = () => {
|
||||||
const { page } = useContext(AppContext);
|
const { page } = useContext(AppContext);
|
||||||
const { relayPool } = useContext(RelayPoolContext);
|
|
||||||
const [lastPage, setLastPage] = useState<string>(page)
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
@ -36,28 +33,28 @@ export const MainLayout: React.FC = () => {
|
|||||||
const breadcrump: string[] = page.split('%');
|
const breadcrump: string[] = page.split('%');
|
||||||
const pageToDisplay: string = breadcrump[breadcrump.length - 1].split('#')[0];
|
const pageToDisplay: string = breadcrump[breadcrump.length - 1].split('#')[0];
|
||||||
|
|
||||||
const clearSubscriptions: () => boolean = () => {
|
const view: () => JSX.Element = () => {
|
||||||
if (relayPool && lastPage && lastPage !== page) {
|
if (page === '') {
|
||||||
relayPool.unsubscribeAll()
|
return <Layout style={styles.container} level='4' />;
|
||||||
relayPool.removeOn('event', lastPage)
|
} else if (page === 'landing') {
|
||||||
setLastPage(page)
|
return (
|
||||||
|
<Layout style={styles.container} level='4'>
|
||||||
|
<LandingPage />
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Layout style={styles.container} level='4'>
|
||||||
|
{pagination[pageToDisplay]}
|
||||||
|
</Layout>
|
||||||
|
<NavigationBar />
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return true
|
return <>{view()}</>;
|
||||||
}
|
|
||||||
|
|
||||||
return page === 'landing' ? (
|
|
||||||
<Layout style={styles.container} level='4'>
|
|
||||||
<LandingPage />
|
|
||||||
</Layout>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Layout style={styles.container} level='4'>
|
|
||||||
{clearSubscriptions() && pagination[pageToDisplay]}
|
|
||||||
</Layout>
|
|
||||||
<NavigationBar />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MainLayout;
|
export default MainLayout;
|
||||||
|
@ -13,7 +13,7 @@ export const NavigationBar: React.FC = () => {
|
|||||||
|
|
||||||
const getIndex: () => number = () => {
|
const getIndex: () => number = () => {
|
||||||
if (page.includes('profile#')) {
|
if (page.includes('profile#')) {
|
||||||
return page === `profile#${publicKey}` ? 2 : 1;
|
return publicKey && page === `profile#${publicKey}` ? 2 : 1;
|
||||||
} else if (page.includes('note#')) {
|
} else if (page.includes('note#')) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,7 +76,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({ note }) => {
|
|||||||
relayPool.add(note.content);
|
relayPool.add(note.content);
|
||||||
setRelayPool(relayPool);
|
setRelayPool(relayPool);
|
||||||
storeRelay({ url: note.content }, database);
|
storeRelay({ url: note.content }, database);
|
||||||
populateRelay(relayPool, database, publicKey)
|
populateRelay(relayPool, database, publicKey);
|
||||||
showMessage({
|
showMessage({
|
||||||
message: t('alerts.relayAdded'),
|
message: t('alerts.relayAdded'),
|
||||||
description: note.content,
|
description: note.content,
|
||||||
|
@ -34,7 +34,7 @@ export const NotePage: React.FC = () => {
|
|||||||
getNotes(database, { filters: { id: eventId } }).then((events) => {
|
getNotes(database, { filters: { id: eventId } }).then((events) => {
|
||||||
if (events.length > 0) {
|
if (events.length > 0) {
|
||||||
const event = events[0];
|
const event = events[0];
|
||||||
setNote(event)
|
setNote(event);
|
||||||
getNotes(database, { filters: { reply_event_id: eventId } }).then((notes) => {
|
getNotes(database, { filters: { reply_event_id: eventId } }).then((notes) => {
|
||||||
const rootReplies = getDirectReplies(notes, event);
|
const rootReplies = getDirectReplies(notes, event);
|
||||||
if (rootReplies.length > 0) {
|
if (rootReplies.length > 0) {
|
||||||
@ -62,7 +62,6 @@ export const NotePage: React.FC = () => {
|
|||||||
}, [lastEventId, page]);
|
}, [lastEventId, page]);
|
||||||
|
|
||||||
const onPressBack: () => void = () => {
|
const onPressBack: () => void = () => {
|
||||||
console.log(breadcrump.slice(0, -1).join('%'))
|
|
||||||
setPage(breadcrump.slice(0, -1).join('%'));
|
setPage(breadcrump.slice(0, -1).join('%'));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +82,7 @@ export const NotePage: React.FC = () => {
|
|||||||
} else if (note.id) {
|
} else if (note.id) {
|
||||||
setPage(`${page}%note#${note.id}`);
|
setPage(`${page}%note#${note.id}`);
|
||||||
}
|
}
|
||||||
setReplies([])
|
setReplies([]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,7 +92,7 @@ export const NotePage: React.FC = () => {
|
|||||||
<Layout style={styles.main} level='2'>
|
<Layout style={styles.main} level='2'>
|
||||||
<NoteCard note={note} />
|
<NoteCard note={note} />
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
);
|
||||||
} else if (note) {
|
} else if (note) {
|
||||||
return (
|
return (
|
||||||
<Card onPress={() => onPressNote(note)}>
|
<Card onPress={() => onPressNote(note)}>
|
||||||
|
@ -46,8 +46,8 @@ export const ProfilePage: React.FC = () => {
|
|||||||
const username = user?.name === '' ? user?.id : user?.name;
|
const username = user?.name === '' ? user?.id : user?.name;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setUser(null)
|
setUser(null);
|
||||||
setNotes([])
|
setNotes([]);
|
||||||
relayPool?.on('event', 'profile', (_relay: Relay, _subId?: string, event?: Event) => {
|
relayPool?.on('event', 'profile', (_relay: Relay, _subId?: string, event?: Event) => {
|
||||||
console.log('PROFILE EVENT =======>', event);
|
console.log('PROFILE EVENT =======>', event);
|
||||||
if (database && event?.id && event.pubkey === userId) {
|
if (database && event?.id && event.pubkey === userId) {
|
||||||
@ -56,7 +56,7 @@ export const ProfilePage: React.FC = () => {
|
|||||||
setContactsIds(ids);
|
setContactsIds(ids);
|
||||||
} else if (event.kind === EventKind.meta) {
|
} else if (event.kind === EventKind.meta) {
|
||||||
storeEvent(event, database).finally(() => {
|
storeEvent(event, database).finally(() => {
|
||||||
if (event?.id) setLastEventId(event.id)
|
if (event?.id) setLastEventId(event.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,8 +101,8 @@ export const ProfilePage: React.FC = () => {
|
|||||||
const removeAuthor: () => void = () => {
|
const removeAuthor: () => void = () => {
|
||||||
if (relayPool && database) {
|
if (relayPool && database) {
|
||||||
removeContact(userId, database).then(() => {
|
removeContact(userId, database).then(() => {
|
||||||
populatePets(relayPool, database, publicKey)
|
populatePets(relayPool, database, publicKey);
|
||||||
setIsContact(false)
|
setIsContact(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -110,8 +110,8 @@ export const ProfilePage: React.FC = () => {
|
|||||||
const addAuthor: () => void = () => {
|
const addAuthor: () => void = () => {
|
||||||
if (relayPool && database) {
|
if (relayPool && database) {
|
||||||
addContact(userId, database).then(() => {
|
addContact(userId, database).then(() => {
|
||||||
populatePets(relayPool, database, publicKey)
|
populatePets(relayPool, database, publicKey);
|
||||||
setIsContact(true)
|
setIsContact(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -119,11 +119,11 @@ export const ProfilePage: React.FC = () => {
|
|||||||
const renderOptions: () => JSX.Element = () => {
|
const renderOptions: () => JSX.Element = () => {
|
||||||
if (publicKey === userId) {
|
if (publicKey === userId) {
|
||||||
return (
|
return (
|
||||||
<TopNavigationAction
|
<TopNavigationAction
|
||||||
icon={<Icon name='dna' size={16} color={theme['text-basic-color']} solid />}
|
icon={<Icon name='dna' size={16} color={theme['text-basic-color']} solid />}
|
||||||
onPress={() => setPage('config')}
|
onPress={() => setPage('config')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (user) {
|
if (user) {
|
||||||
if (isContact) {
|
if (isContact) {
|
||||||
|
@ -75,7 +75,7 @@ export const SendPage: React.FC = () => {
|
|||||||
tags,
|
tags,
|
||||||
};
|
};
|
||||||
relayPool?.sendEvent(event);
|
relayPool?.sendEvent(event);
|
||||||
setNoteId(note.id)
|
setNoteId(note.id);
|
||||||
setSending(true);
|
setSending(true);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { SQLiteDatabase } from 'react-native-sqlite-storage';
|
import { SQLiteDatabase } from 'react-native-sqlite-storage';
|
||||||
import { initDatabase } from '../Functions/DatabaseFunctions';
|
import { initDatabase } from '../Functions/DatabaseFunctions';
|
||||||
import { createInitDatabase } from '../Functions/DatabaseFunctions/Migrations';
|
import { createInitDatabase } from '../Functions/DatabaseFunctions/Migrations';
|
||||||
import FlashMessage from 'react-native-flash-message';
|
import FlashMessage from 'react-native-flash-message';
|
||||||
|
import EncryptedStorage from 'react-native-encrypted-storage';
|
||||||
|
|
||||||
export interface AppContextProps {
|
export interface AppContextProps {
|
||||||
page: string;
|
page: string;
|
||||||
setPage: (page: string) => void;
|
setPage: (page: string) => void;
|
||||||
runMigrations: () => void;
|
|
||||||
loadingDb: boolean;
|
loadingDb: boolean;
|
||||||
database: SQLiteDatabase | null;
|
database: SQLiteDatabase | null;
|
||||||
}
|
}
|
||||||
@ -17,9 +17,8 @@ export interface AppContextProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const initialAppContext: AppContextProps = {
|
export const initialAppContext: AppContextProps = {
|
||||||
page: 'landing',
|
page: '',
|
||||||
setPage: () => {},
|
setPage: () => {},
|
||||||
runMigrations: () => {},
|
|
||||||
loadingDb: true,
|
loadingDb: true,
|
||||||
database: null,
|
database: null,
|
||||||
};
|
};
|
||||||
@ -29,13 +28,19 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
|||||||
const [database, setDatabase] = useState<SQLiteDatabase | null>(null);
|
const [database, setDatabase] = useState<SQLiteDatabase | null>(null);
|
||||||
const [loadingDb, setLoadingDb] = useState<boolean>(initialAppContext.loadingDb);
|
const [loadingDb, setLoadingDb] = useState<boolean>(initialAppContext.loadingDb);
|
||||||
|
|
||||||
const runMigrations: () => void = async () => {
|
useEffect(() => {
|
||||||
const db = initDatabase()
|
EncryptedStorage.getItem('privateKey').then((result) => {
|
||||||
setDatabase(db)
|
const db = initDatabase();
|
||||||
createInitDatabase(db).then(() => {
|
setDatabase(db);
|
||||||
setLoadingDb(false);
|
if (!result || result === '') {
|
||||||
|
createInitDatabase(db).then(() => {
|
||||||
|
setLoadingDb(false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setLoadingDb(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppContext.Provider
|
<AppContext.Provider
|
||||||
@ -44,7 +49,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
|
|||||||
setPage,
|
setPage,
|
||||||
loadingDb,
|
loadingDb,
|
||||||
database,
|
database,
|
||||||
runMigrations,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -6,19 +6,18 @@ import { AppContext } from './AppContext';
|
|||||||
import { storeEvent } from '../Functions/DatabaseFunctions/Events';
|
import { storeEvent } from '../Functions/DatabaseFunctions/Events';
|
||||||
import { getRelays, Relay as RelayEntity, storeRelay } from '../Functions/DatabaseFunctions/Relays';
|
import { getRelays, Relay as RelayEntity, storeRelay } from '../Functions/DatabaseFunctions/Relays';
|
||||||
import { showMessage } from 'react-native-flash-message';
|
import { showMessage } from 'react-native-flash-message';
|
||||||
|
import EncryptedStorage from 'react-native-encrypted-storage';
|
||||||
|
import { getPublickey } from '../lib/nostr/Bip';
|
||||||
|
|
||||||
export interface RelayPoolContextProps {
|
export interface RelayPoolContextProps {
|
||||||
relayPool?: RelayPool;
|
relayPool?: RelayPool;
|
||||||
setRelayPool: (relayPool: RelayPool) => void;
|
setRelayPool: (relayPool: RelayPool) => void;
|
||||||
publicKey: string;
|
publicKey?: string;
|
||||||
setPublicKey: (privateKey: string) => void;
|
setPublicKey: (privateKey: string) => void;
|
||||||
privateKey: string;
|
privateKey?: string;
|
||||||
setPrivateKey: (privateKey: string) => void;
|
setPrivateKey: (privateKey: string) => void;
|
||||||
lastEventId?: string;
|
lastEventId?: string;
|
||||||
setLastEventId: (lastEventId: string) => void;
|
setLastEventId: (lastEventId: string) => void;
|
||||||
loadingRelays: boolean;
|
|
||||||
initRelays: () => void;
|
|
||||||
loadRelays: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RelayPoolContextProviderProps {
|
export interface RelayPoolContextProviderProps {
|
||||||
@ -26,56 +25,25 @@ export interface RelayPoolContextProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const initialRelayPoolContext: RelayPoolContextProps = {
|
export const initialRelayPoolContext: RelayPoolContextProps = {
|
||||||
publicKey: '',
|
|
||||||
setPublicKey: () => {},
|
setPublicKey: () => {},
|
||||||
privateKey: '',
|
|
||||||
setPrivateKey: () => {},
|
setPrivateKey: () => {},
|
||||||
setRelayPool: () => {},
|
setRelayPool: () => {},
|
||||||
setLastEventId: () => {},
|
setLastEventId: () => {},
|
||||||
loadingRelays: true,
|
|
||||||
initRelays: () => {},
|
|
||||||
loadRelays: () => {},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RelayPoolContextProvider = ({
|
export const RelayPoolContextProvider = ({
|
||||||
children,
|
children,
|
||||||
}: RelayPoolContextProviderProps): JSX.Element => {
|
}: RelayPoolContextProviderProps): JSX.Element => {
|
||||||
const { database, loadingDb } = useContext(AppContext);
|
const { database, loadingDb, setPage, page } = useContext(AppContext);
|
||||||
|
|
||||||
const [publicKey, setPublicKey] = useState<string>('');
|
const [publicKey, setPublicKey] = useState<string>();
|
||||||
const [privateKey, setPrivateKey] = useState<string>('');
|
const [privateKey, setPrivateKey] = useState<string>();
|
||||||
const [relayPool, setRelayPool] = useState<RelayPool>();
|
const [relayPool, setRelayPool] = useState<RelayPool>();
|
||||||
const [lastEventId, setLastEventId] = useState<string>();
|
const [lastEventId, setLastEventId] = useState<string>();
|
||||||
const [loadingRelays, setLoadingRelays] = useState<boolean>(true);
|
const [lastPage, setLastPage] = useState<string>(page);
|
||||||
|
|
||||||
const initRelays: () => void = () => {
|
const loadRelayPool: () => void = () => {
|
||||||
relayPool?.on(
|
if (database && privateKey) {
|
||||||
'notice',
|
|
||||||
'RelayPoolContextProvider',
|
|
||||||
(relay: Relay, _subId?: string, event?: Event) => {
|
|
||||||
showMessage({
|
|
||||||
message: relay.url,
|
|
||||||
description: event?.content ?? '',
|
|
||||||
type: 'info',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
relayPool?.on(
|
|
||||||
'event',
|
|
||||||
'RelayPoolContextProvider',
|
|
||||||
(relay: Relay, _subId?: string, event?: Event) => {
|
|
||||||
console.log('RELAYPOOL EVENT =======>', relay.url, event);
|
|
||||||
if (database && event?.id && event.kind !== EventKind.petNames) {
|
|
||||||
storeEvent(event, database).finally(() => setLastEventId(event.id));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
setLoadingRelays(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadRelays: () => void = () => {
|
|
||||||
if (database) {
|
|
||||||
getRelays(database).then((relays: RelayEntity[]) => {
|
getRelays(database).then((relays: RelayEntity[]) => {
|
||||||
const initRelayPool = new RelayPool([], privateKey);
|
const initRelayPool = new RelayPool([], privateKey);
|
||||||
if (relays.length > 0) {
|
if (relays.length > 0) {
|
||||||
@ -88,16 +56,65 @@ export const RelayPoolContextProvider = ({
|
|||||||
storeRelay({ url: relayUrl }, database);
|
storeRelay({ url: relayUrl }, database);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initRelayPool?.on(
|
||||||
|
'notice',
|
||||||
|
'RelayPoolContextProvider',
|
||||||
|
(relay: Relay, _subId?: string, event?: Event) => {
|
||||||
|
showMessage({
|
||||||
|
message: relay.url,
|
||||||
|
description: event?.content ?? '',
|
||||||
|
type: 'info',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
initRelayPool?.on(
|
||||||
|
'event',
|
||||||
|
'RelayPoolContextProvider',
|
||||||
|
(relay: Relay, _subId?: string, event?: Event) => {
|
||||||
|
console.log('RELAYPOOL EVENT =======>', relay.url, event);
|
||||||
|
if (database && event?.id && event.kind !== EventKind.petNames) {
|
||||||
|
storeEvent(event, database).finally(() => setLastEventId(event.id));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
setRelayPool(initRelayPool);
|
setRelayPool(initRelayPool);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (privateKey !== '' && !loadingDb && loadingRelays) {
|
if (privateKey) {
|
||||||
loadRelays()
|
setPublicKey(getPublickey(privateKey));
|
||||||
}
|
}
|
||||||
}, [privateKey, loadingDb])
|
}, [privateKey]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (privateKey !== '' && !loadingDb && !relayPool) {
|
||||||
|
loadRelayPool();
|
||||||
|
}
|
||||||
|
}, [privateKey, loadingDb]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (relayPool && lastPage !== page) {
|
||||||
|
relayPool.unsubscribeAll();
|
||||||
|
relayPool.removeOn('event', lastPage);
|
||||||
|
setLastPage(page);
|
||||||
|
}
|
||||||
|
}, [page]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
EncryptedStorage.getItem('privateKey').then((result) => {
|
||||||
|
if (result && result !== '') {
|
||||||
|
loadRelayPool();
|
||||||
|
setPage('home');
|
||||||
|
setPrivateKey(result);
|
||||||
|
} else {
|
||||||
|
setPrivateKey('');
|
||||||
|
setPage('landing');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RelayPoolContext.Provider
|
<RelayPoolContext.Provider
|
||||||
@ -110,9 +127,6 @@ export const RelayPoolContextProvider = ({
|
|||||||
setPrivateKey,
|
setPrivateKey,
|
||||||
lastEventId,
|
lastEventId,
|
||||||
setLastEventId,
|
setLastEventId,
|
||||||
loadingRelays,
|
|
||||||
initRelays,
|
|
||||||
loadRelays,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -40,8 +40,8 @@ export const createInitDatabase: (db: SQLiteDatabase) => Promise<void> = async (
|
|||||||
);
|
);
|
||||||
`,
|
`,
|
||||||
db,
|
db,
|
||||||
).then(() => resolve())
|
).then(() => resolve());
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,8 @@ export const insertNote: (event: Event, db: SQLiteDatabase) => Promise<void> = a
|
|||||||
) => {
|
) => {
|
||||||
return await new Promise<void>((resolve, reject) => {
|
return await new Promise<void>((resolve, reject) => {
|
||||||
if (!verifySignature(event) || !event.id) return reject(new Error('Bad event'));
|
if (!verifySignature(event) || !event.id) return reject(new Error('Bad event'));
|
||||||
if (![EventKind.textNote, EventKind.recommendServer].includes(event.kind)) return reject(new Error('Bad Kind'));
|
if (![EventKind.textNote, EventKind.recommendServer].includes(event.kind))
|
||||||
|
return reject(new Error('Bad Kind'));
|
||||||
|
|
||||||
getNotes(db, { filters: { id: event.id } }).then((notes) => {
|
getNotes(db, { filters: { id: event.id } }).then((notes) => {
|
||||||
if (notes.length === 0 && event.id && event.sig) {
|
if (notes.length === 0 && event.id && event.sig) {
|
||||||
|
@ -49,7 +49,9 @@ export const insertUserMeta: (event: Event, db: SQLiteDatabase) => Promise<void>
|
|||||||
INSERT INTO nostros_users
|
INSERT INTO nostros_users
|
||||||
(id, name, picture, about, main_relay)
|
(id, name, picture, about, main_relay)
|
||||||
VALUES
|
VALUES
|
||||||
('${id}', '${name.split("'").join("''")}', '${picture.split("'").join("''")}', '${about.split("'").join("''")}', '');
|
('${id}', '${name.split("'").join("''")}', '${picture.split("'").join("''")}', '${about
|
||||||
|
.split("'")
|
||||||
|
.join("''")}', '');
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
db.transaction((transaction) => {
|
db.transaction((transaction) => {
|
||||||
|
@ -19,26 +19,24 @@ export const getItems: (resultSet: ResultSet) => object[] = (resultSet) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const simpleExecute: (query: string, db: SQLiteDatabase) => Promise<Transaction> = async (query, db) => {
|
export const simpleExecute: (query: string, db: SQLiteDatabase) => Promise<Transaction> = async (
|
||||||
|
query,
|
||||||
|
db,
|
||||||
|
) => {
|
||||||
return await db.transaction((transaction) => {
|
return await db.transaction((transaction) => {
|
||||||
transaction.executeSql(query, [], () => {}, errorCallback(query));
|
transaction.executeSql(query, [], () => {}, errorCallback(query));
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dropTables: (db: SQLiteDatabase) => Promise<Transaction> = async (db) => {
|
export const dropTables: (db: SQLiteDatabase) => Promise<Transaction> = async (db) => {
|
||||||
const dropQueries = [
|
const dropQueries = [
|
||||||
'DROP TABLE IF EXISTS nostros_notes;',
|
'DROP TABLE IF EXISTS nostros_notes;',
|
||||||
'DROP TABLE IF EXISTS nostros_users;',
|
'DROP TABLE IF EXISTS nostros_users;',
|
||||||
'DROP TABLE IF EXISTS nostros_relays;'
|
'DROP TABLE IF EXISTS nostros_relays;',
|
||||||
]
|
];
|
||||||
return await db.transaction((transaction) => {
|
return await db.transaction((transaction) => {
|
||||||
dropQueries.forEach((query) => {
|
dropQueries.forEach((query) => {
|
||||||
transaction.executeSql(
|
transaction.executeSql(query, [], () => {}, errorCallback(query));
|
||||||
query,
|
});
|
||||||
[],
|
|
||||||
() => {},
|
|
||||||
errorCallback(query),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ export const getReplyEventId: (event: Event) => string | null = (event) => {
|
|||||||
if (!mainTag) {
|
if (!mainTag) {
|
||||||
mainTag = eTags[eTags.length - 1];
|
mainTag = eTags[eTags.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return mainTag ? mainTag[1] : null;
|
return mainTag ? mainTag[1] : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +24,11 @@ export const tagToUser: (tag: string[]) => User = (tag) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const populatePets: (relayPool: RelayPool, database: SQLiteDatabase, publicKey: string) => void = (relayPool, database, publicKey) => {
|
export const populatePets: (
|
||||||
|
relayPool: RelayPool,
|
||||||
|
database: SQLiteDatabase,
|
||||||
|
publicKey: string,
|
||||||
|
) => void = (relayPool, database, publicKey) => {
|
||||||
getUsers(database, { exludeIds: [publicKey], contacts: true }).then((results) => {
|
getUsers(database, { exludeIds: [publicKey], contacts: true }).then((results) => {
|
||||||
if (results) {
|
if (results) {
|
||||||
const event: Event = {
|
const event: Event = {
|
||||||
@ -37,17 +41,21 @@ export const populatePets: (relayPool: RelayPool, database: SQLiteDatabase, publ
|
|||||||
relayPool?.sendEvent(event);
|
relayPool?.sendEvent(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export const populateProfile: (relayPool: RelayPool, database: SQLiteDatabase, publicKey: string) => void = (relayPool, database, publicKey) => {
|
export const populateProfile: (
|
||||||
|
relayPool: RelayPool,
|
||||||
|
database: SQLiteDatabase,
|
||||||
|
publicKey: string,
|
||||||
|
) => void = (relayPool, database, publicKey) => {
|
||||||
getUser(publicKey, database).then((result) => {
|
getUser(publicKey, database).then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
const profile = {
|
const profile = {
|
||||||
name: result.name,
|
name: result.name,
|
||||||
main_relay: result.main_relay,
|
main_relay: result.main_relay,
|
||||||
picture: result.picture,
|
picture: result.picture,
|
||||||
about: result.about
|
about: result.about,
|
||||||
}
|
};
|
||||||
const event: Event = {
|
const event: Event = {
|
||||||
content: JSON.stringify(profile),
|
content: JSON.stringify(profile),
|
||||||
created_at: moment().unix(),
|
created_at: moment().unix(),
|
||||||
@ -58,6 +66,4 @@ export const populateProfile: (relayPool: RelayPool, database: SQLiteDatabase, p
|
|||||||
relayPool?.sendEvent(event);
|
relayPool?.sendEvent(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import { SQLiteDatabase } from "react-native-sqlite-storage"
|
import { SQLiteDatabase } from 'react-native-sqlite-storage';
|
||||||
import RelayPool from "../../lib/nostr/RelayPool/intex"
|
import RelayPool from '../../lib/nostr/RelayPool/intex';
|
||||||
import { populatePets, populateProfile } from "./Users"
|
import { populatePets, populateProfile } from './Users';
|
||||||
|
|
||||||
export const populateRelay: (relayPool: RelayPool, database: SQLiteDatabase, publicKey: string) => void = (relayPool, database, publicKey) => {
|
export const populateRelay: (
|
||||||
populateProfile(relayPool, database, publicKey)
|
relayPool: RelayPool,
|
||||||
populatePets(relayPool, database, publicKey)
|
database: SQLiteDatabase,
|
||||||
}
|
publicKey: string,
|
||||||
|
) => void = (relayPool, database, publicKey) => {
|
||||||
|
populateProfile(relayPool, database, publicKey);
|
||||||
|
populatePets(relayPool, database, publicKey);
|
||||||
|
};
|
||||||
|
@ -110,12 +110,12 @@ class RelayPool {
|
|||||||
relay.sendEvent(signedEvent);
|
relay.sendEvent(signedEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
return signedEvent
|
return signedEvent;
|
||||||
} else {
|
} else {
|
||||||
console.log('Not valid event', event);
|
console.log('Not valid event', event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
public readonly subscribe: (subId: string, filters?: RelayFilters) => void = (subId, filters) => {
|
public readonly subscribe: (subId: string, filters?: RelayFilters) => void = (subId, filters) => {
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
"eslint-plugin-react": "^7.31.10",
|
"eslint-plugin-react": "^7.31.10",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"metro-react-native-babel-preset": "^0.64.0",
|
"metro-react-native-babel-preset": "^0.73.2",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"react-test-renderer": "17.0.1",
|
"react-test-renderer": "17.0.1",
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.8.3"
|
||||||
|
95
yarn.lock
95
yarn.lock
@ -115,7 +115,7 @@
|
|||||||
"@babel/helper-replace-supers" "^7.18.9"
|
"@babel/helper-replace-supers" "^7.18.9"
|
||||||
"@babel/helper-split-export-declaration" "^7.18.6"
|
"@babel/helper-split-export-declaration" "^7.18.6"
|
||||||
|
|
||||||
"@babel/helper-create-regexp-features-plugin@^7.18.6":
|
"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0":
|
||||||
version "7.19.0"
|
version "7.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b"
|
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b"
|
||||||
integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==
|
integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==
|
||||||
@ -216,6 +216,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf"
|
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf"
|
||||||
integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==
|
integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==
|
||||||
|
|
||||||
|
"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9":
|
||||||
|
version "7.18.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
|
||||||
|
integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-annotate-as-pure" "^7.18.6"
|
||||||
|
"@babel/helper-environment-visitor" "^7.18.9"
|
||||||
|
"@babel/helper-wrap-function" "^7.18.9"
|
||||||
|
"@babel/types" "^7.18.9"
|
||||||
|
|
||||||
"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9":
|
"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9":
|
||||||
version "7.19.1"
|
version "7.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78"
|
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78"
|
||||||
@ -263,6 +273,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
|
||||||
integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
|
integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
|
||||||
|
|
||||||
|
"@babel/helper-wrap-function@^7.18.9":
|
||||||
|
version "7.19.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1"
|
||||||
|
integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-function-name" "^7.19.0"
|
||||||
|
"@babel/template" "^7.18.10"
|
||||||
|
"@babel/traverse" "^7.19.0"
|
||||||
|
"@babel/types" "^7.19.0"
|
||||||
|
|
||||||
"@babel/helpers@^7.19.4":
|
"@babel/helpers@^7.19.4":
|
||||||
version "7.19.4"
|
version "7.19.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.4.tgz#42154945f87b8148df7203a25c31ba9a73be46c5"
|
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.4.tgz#42154945f87b8148df7203a25c31ba9a73be46c5"
|
||||||
@ -291,6 +311,16 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.6.tgz#b923430cb94f58a7eae8facbffa9efd19130e7f8"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.6.tgz#b923430cb94f58a7eae8facbffa9efd19130e7f8"
|
||||||
integrity sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==
|
integrity sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==
|
||||||
|
|
||||||
|
"@babel/plugin-proposal-async-generator-functions@^7.0.0":
|
||||||
|
version "7.19.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7"
|
||||||
|
integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-environment-visitor" "^7.18.9"
|
||||||
|
"@babel/helper-plugin-utils" "^7.19.0"
|
||||||
|
"@babel/helper-remap-async-to-generator" "^7.18.9"
|
||||||
|
"@babel/plugin-syntax-async-generators" "^7.8.4"
|
||||||
|
|
||||||
"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0":
|
"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0":
|
||||||
version "7.18.6"
|
version "7.18.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3"
|
||||||
@ -469,6 +499,15 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-plugin-utils" "^7.18.6"
|
"@babel/helper-plugin-utils" "^7.18.6"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-async-to-generator@^7.0.0":
|
||||||
|
version "7.18.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615"
|
||||||
|
integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-module-imports" "^7.18.6"
|
||||||
|
"@babel/helper-plugin-utils" "^7.18.6"
|
||||||
|
"@babel/helper-remap-async-to-generator" "^7.18.6"
|
||||||
|
|
||||||
"@babel/plugin-transform-block-scoped-functions@^7.0.0":
|
"@babel/plugin-transform-block-scoped-functions@^7.0.0":
|
||||||
version "7.18.6"
|
version "7.18.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8"
|
||||||
@ -568,6 +607,14 @@
|
|||||||
"@babel/helper-simple-access" "^7.18.6"
|
"@babel/helper-simple-access" "^7.18.6"
|
||||||
babel-plugin-dynamic-import-node "^2.3.3"
|
babel-plugin-dynamic-import-node "^2.3.3"
|
||||||
|
|
||||||
|
"@babel/plugin-transform-named-capturing-groups-regex@^7.0.0":
|
||||||
|
version "7.19.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888"
|
||||||
|
integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-create-regexp-features-plugin" "^7.19.0"
|
||||||
|
"@babel/helper-plugin-utils" "^7.19.0"
|
||||||
|
|
||||||
"@babel/plugin-transform-object-assign@^7.0.0":
|
"@babel/plugin-transform-object-assign@^7.0.0":
|
||||||
version "7.18.6"
|
version "7.18.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.18.6.tgz#7830b4b6f83e1374a5afb9f6111bcfaea872cdd2"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.18.6.tgz#7830b4b6f83e1374a5afb9f6111bcfaea872cdd2"
|
||||||
@ -5201,7 +5248,7 @@ metro-minify-uglify@0.64.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
uglify-es "^3.1.9"
|
uglify-es "^3.1.9"
|
||||||
|
|
||||||
metro-react-native-babel-preset@0.64.0, metro-react-native-babel-preset@^0.64.0:
|
metro-react-native-babel-preset@0.64.0:
|
||||||
version "0.64.0"
|
version "0.64.0"
|
||||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.64.0.tgz#76861408681dfda3c1d962eb31a8994918c976f8"
|
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.64.0.tgz#76861408681dfda3c1d962eb31a8994918c976f8"
|
||||||
integrity sha512-HcZ0RWQRuJfpPiaHyFQJzcym+/dDIVUPwUAXWoub/C4GkGu+mPjp8vqK6g0FxokCnnI2TK0gZTza2IDfiNNscQ==
|
integrity sha512-HcZ0RWQRuJfpPiaHyFQJzcym+/dDIVUPwUAXWoub/C4GkGu+mPjp8vqK6g0FxokCnnI2TK0gZTza2IDfiNNscQ==
|
||||||
@ -5246,6 +5293,50 @@ metro-react-native-babel-preset@0.64.0, metro-react-native-babel-preset@^0.64.0:
|
|||||||
"@babel/template" "^7.0.0"
|
"@babel/template" "^7.0.0"
|
||||||
react-refresh "^0.4.0"
|
react-refresh "^0.4.0"
|
||||||
|
|
||||||
|
metro-react-native-babel-preset@^0.73.2:
|
||||||
|
version "0.73.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.2.tgz#b80d0bdd3d64a10c14514bd4d73f9cf6277218e9"
|
||||||
|
integrity sha512-Wb7nPaJRHpikZII565oLKylxmiyMFlTA/wSnCkJ7LDo6ICh0jSshfNk9+w5V5xAxSnpsEnvXPaGP5QFk4ZHXrg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/core" "^7.14.0"
|
||||||
|
"@babel/plugin-proposal-async-generator-functions" "^7.0.0"
|
||||||
|
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||||
|
"@babel/plugin-proposal-export-default-from" "^7.0.0"
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0"
|
||||||
|
"@babel/plugin-proposal-object-rest-spread" "^7.0.0"
|
||||||
|
"@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
|
||||||
|
"@babel/plugin-proposal-optional-chaining" "^7.0.0"
|
||||||
|
"@babel/plugin-syntax-dynamic-import" "^7.0.0"
|
||||||
|
"@babel/plugin-syntax-export-default-from" "^7.0.0"
|
||||||
|
"@babel/plugin-syntax-flow" "^7.2.0"
|
||||||
|
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0"
|
||||||
|
"@babel/plugin-syntax-optional-chaining" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-arrow-functions" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-async-to-generator" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-block-scoping" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-classes" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-computed-properties" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-destructuring" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-flow-strip-types" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-function-name" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-literals" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-modules-commonjs" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-parameters" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-react-display-name" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-react-jsx" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-runtime" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-shorthand-properties" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-spread" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-sticky-regex" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-template-literals" "^7.0.0"
|
||||||
|
"@babel/plugin-transform-typescript" "^7.5.0"
|
||||||
|
"@babel/plugin-transform-unicode-regex" "^7.0.0"
|
||||||
|
"@babel/template" "^7.0.0"
|
||||||
|
react-refresh "^0.4.0"
|
||||||
|
|
||||||
metro-react-native-babel-transformer@0.64.0, metro-react-native-babel-transformer@^0.64.0:
|
metro-react-native-babel-transformer@0.64.0, metro-react-native-babel-transformer@^0.64.0:
|
||||||
version "0.64.0"
|
version "0.64.0"
|
||||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.64.0.tgz#eafef756972f20efdc51bd5361d55f8598355623"
|
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.64.0.tgz#eafef756972f20efdc51bd5361d55f8598355623"
|
||||||
|
Loading…
Reference in New Issue
Block a user