Merge branch 'main' into dependabot/npm_and_yarn/react-native-0.64.3

This commit is contained in:
KoalaSat 2022-10-25 13:07:51 +00:00 committed by GitHub
commit c29931ab63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 366 additions and 252 deletions

View File

@ -1 +0,0 @@

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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(() => {

View File

@ -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}>

View File

@ -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;

View File

@ -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 {

View File

@ -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,

View File

@ -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)}>

View File

@ -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) {

View File

@ -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);
}); });
}; };

View File

@ -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}

View File

@ -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}

View File

@ -40,8 +40,8 @@ export const createInitDatabase: (db: SQLiteDatabase) => Promise<void> = async (
); );
`, `,
db, db,
).then(() => resolve()) ).then(() => resolve());
}) });
}) });
}) });
}; };

View File

@ -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) {

View File

@ -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) => {

View File

@ -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),
);
})
}); });
}; };

View File

@ -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;
}; };

View File

@ -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);
} }
}); });
} };

View File

@ -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);
};

View File

@ -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) => {

View File

@ -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"

View File

@ -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"