diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b13789..e69de29 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1 +0,0 @@
-
diff --git a/README.md b/README.md
index cf99d37..fbcc77f 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,12 @@
![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
## Required Libraries and Frameworks
+
- Node 16.x
- JDK 17.0.x
- (Android) Android Studio SKD
@@ -16,41 +17,60 @@ Wellcome to the NOSTROS project.
- Open a virtual device
- Install
+
```
yarn install
```
+
- Run Metro
+
```
yarn start
```
# Some Features to Work On
+
### Bugs
+
- [ ] User info missing on first start
- [ ] i18n not loading
- [ ] Logging out and in again does not work
- [ ] Clipboard library not working
+
### Basics
+
- [ ] Infinite Load
- [ ] Go to replied event
- [ ] Relays management (add, remove and recomend)
- [ ] Random Key Generator
+
### Home
+
- [ ] Public Room
- [ ] Other Rooms
-### Profile
+
+### Profile
+
- [ ] Verify NIP-05
- [ ] Verify LNURL https://github.com/andrerfneves/lightning-address
+
### Contacts
+
- [ ] Direct Messages https://github.com/nostr-protocol/nips/blob/master/04.md
+
### Note
+
- [ ] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
- [ ] Reactions https://github.com/nostr-protocol/nips/blob/master/25.md
- [ ] Deletion https://github.com/nostr-protocol/nips/blob/master/09.md
- [ ] Tag Users https://github.com/nostr-protocol/nips/blob/master/10.md
+
### Send
+
- [ ] Mentions https://github.com/nostr-protocol/nips/blob/master/08.md
+
### Config
+
- [ ] Private Key download
# Kudos
@@ -58,6 +78,6 @@ yarn start
- Inspired on https://github.com/jb55/nostr-js and https://github.com/fiatjaf/nostr-tools
- Discovered thanks to https://lunaticoin.com
-------
+---
Made with 🐨 by https://getalby.com/p/koalasat
diff --git a/frontend/Components/ConfigPage/index.tsx b/frontend/Components/ConfigPage/index.tsx
index aef7ec8..1115641 100644
--- a/frontend/Components/ConfigPage/index.tsx
+++ b/frontend/Components/ConfigPage/index.tsx
@@ -17,7 +17,7 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
export const ConfigPage: React.FC = () => {
const theme = useTheme();
const { setPage, page, database } = useContext(AppContext);
- const { setPrivateKey } = useContext(RelayPoolContext);
+ const { setPrivateKey, relayPool } = useContext(RelayPoolContext);
const { t } = useTranslation('common');
const breadcrump = page.split('%');
@@ -26,10 +26,13 @@ export const ConfigPage: React.FC = () => {
};
const onPressLogout: () => void = () => {
- setPrivateKey('')
- EncryptedStorage.removeItem('privateKey');
if (database) {
- dropTables(database).then(() => setPage('landing'))
+ dropTables(database).then(() => {
+ setPrivateKey('');
+ relayPool?.unsubscribeAll();
+ EncryptedStorage.removeItem('privateKey');
+ setPage('landing');
+ });
}
};
@@ -67,7 +70,9 @@ export const ConfigPage: React.FC = () => {
}
+ accessoryLeft={
+
+ }
>
{t('configPage.logout')}
diff --git a/frontend/Components/ContactsPage/index.tsx b/frontend/Components/ContactsPage/index.tsx
index 2bfce8b..15bcbc9 100644
--- a/frontend/Components/ContactsPage/index.tsx
+++ b/frontend/Components/ContactsPage/index.tsx
@@ -6,7 +6,12 @@ import { AppContext } from '../../Contexts/AppContext';
import Icon from 'react-native-vector-icons/FontAwesome5';
import { Event, EventKind } from '../../lib/nostr/Events';
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 { RelayPoolContext } from '../../Contexts/RelayPoolContext';
import Relay from '../../lib/nostr/Relay';
@@ -22,7 +27,7 @@ export const ContactsPage: React.FC = () => {
const { t } = useTranslation('common');
useEffect(() => {
- if (database) {
+ if (database && publicKey) {
getUsers(database, { contacts: true }).then((results) => {
if (results) {
setUsers(results);
@@ -37,19 +42,18 @@ export const ContactsPage: React.FC = () => {
useEffect(() => {
relayPool?.on('event', 'contacts', (relay: Relay, _subId?: string, event?: Event) => {
- console.log('RELAYPOOL EVENT =======>', relay.url, event);
- if (database && event?.id && event.kind === EventKind.petNames) {
- insertUserContact(event, database).finally(() => setLastEventId(event?.id ?? ''));
- }
- },
- );
- }, [])
+ console.log('RELAYPOOL EVENT =======>', relay.url, event);
+ if (database && event?.id && event.kind === EventKind.petNames) {
+ insertUserContact(event, database).finally(() => setLastEventId(event?.id ?? ''));
+ }
+ });
+ }, []);
const onPressAddContact: () => void = () => {
- if (contactInput && relayPool && database) {
+ if (contactInput && relayPool && database && publicKey) {
addContact(contactInput, database).then(() => {
- populatePets(relayPool, database, publicKey)
- setShowAddContant(false)
+ populatePets(relayPool, database, publicKey);
+ setShowAddContant(false);
});
}
};
@@ -125,4 +129,3 @@ export const ContactsPage: React.FC = () => {
};
export default ContactsPage;
-
diff --git a/frontend/Components/HomePage/index.tsx b/frontend/Components/HomePage/index.tsx
index fe5b075..afc4c7a 100644
--- a/frontend/Components/HomePage/index.tsx
+++ b/frontend/Components/HomePage/index.tsx
@@ -31,10 +31,10 @@ export const HomePage: React.FC = () => {
};
const subscribeNotes: () => void = () => {
- if (database) {
+ if (database && publicKey) {
getNotes(database, { limit: 1 }).then((notes) => {
getUsers(database, { contacts: true }).then((users) => {
- setTotalContacts(users.length)
+ setTotalContacts(users.length);
let message: RelayFilters = {
kinds: [EventKind.textNote, EventKind.recommendServer],
authors: [publicKey, ...users.map((user) => user.id)],
@@ -55,7 +55,7 @@ export const HomePage: React.FC = () => {
};
useEffect(() => {
- loadNotes()
+ loadNotes();
}, [lastEventId]);
useEffect(() => {
diff --git a/frontend/Components/LandingPage/index.tsx b/frontend/Components/LandingPage/index.tsx
index 8cdd06f..6e28771 100644
--- a/frontend/Components/LandingPage/index.tsx
+++ b/frontend/Components/LandingPage/index.tsx
@@ -5,25 +5,22 @@ import Loading from '../Loading';
import { RelayPoolContext } from '../../Contexts/RelayPoolContext';
import { useTranslation } from 'react-i18next';
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 { AppContext } from '../../Contexts/AppContext';
-import { getUsers, insertUserContact } from '../../Functions/DatabaseFunctions/Users';
-import { getPublickey } from '../../lib/nostr/Bip';
+import { insertUserContact } from '../../Functions/DatabaseFunctions/Users';
import EncryptedStorage from 'react-native-encrypted-storage';
-import { SQLiteDatabase } from 'react-native-sqlite-storage';
export const LandingPage: React.FC = () => {
- const { privateKey, setPrivateKey, publicKey, setPublicKey, relayPool, initRelays } =
- useContext(RelayPoolContext);
- const { database, setPage, runMigrations, loadingDb } = useContext(AppContext);
+ const { database, setPage } = useContext(AppContext);
+ const { privateKey, publicKey, relayPool, setPrivateKey } = useContext(RelayPoolContext);
const { t } = useTranslation('common');
- const [init, setInit] = useState(true);
const [loading, setLoading] = useState(false);
const [status, setStatus] = useState(0);
const [totalPets, setTotalPets] = useState();
- const [loadedUsers, setLoadedUsers] = useState(0);
- const [usersReady, setUsersReady] = useState(false);
+ const [inputValue, setInputValue] = useState('');
+ const [loadedUsers, setLoadedUsers] = useState();
+ const [loadedNotes, setLoadedNotes] = useState();
const styles = StyleSheet.create({
tab: {
height: '100%',
@@ -45,110 +42,97 @@ export const LandingPage: React.FC = () => {
},
});
- useEffect(() => { // #1 STEP
- if (init) {
- EncryptedStorage.getItem('privateKey').then((result) => {
- if (result && result !== '') {
- setPrivateKey(result);
- setPublicKey(getPublickey(result));
- setUsersReady(true);
- } if (!loadingDb) {
- setInit(false);
- } else {
- runMigrations();
- }
+ useEffect(() => {
+ // #1 STEP
+ if (relayPool && publicKey) {
+ setStatus(1);
+ initEvents();
+ relayPool?.subscribe('main-channel', {
+ kinds: [EventKind.petNames],
+ authors: [publicKey],
});
}
- }, [init, relayPool, loadingDb]);
+ }, [relayPool, publicKey]);
useEffect(() => {
- if (usersReady && relayPool && !loadingDb) {
- initRelays()
+ if (status > 3) {
+ relayPool?.removeOn('event', 'landing');
setPage('home');
}
- }, [usersReady, relayPool]);
+ }, [status]);
useEffect(() => {
- if (loading && publicKey !== '') {
- initEvents();
+ if (loadedUsers ?? loadedNotes) {
+ const timer = setTimeout(() => setStatus(4), 4000);
+ return () => {
+ clearTimeout(timer);
+ };
}
- }, [loading, publicKey]);
-
- useEffect(() => {
- if (loading && loadedUsers) {
- loadUsers();
- }
- }, [loading, totalPets, loadedUsers]);
+ }, [loadedUsers, loadedNotes]);
const initEvents: () => void = () => {
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) {
- loadPets(event);
- } else {
- if (event.kind === EventKind.meta && event.pubkey !== publicKey) {
- setLoadedUsers((prev) => prev + 1)
- }
+ loadPets(event);
+ } else if (event.kind === EventKind.meta) {
+ setLoadedUsers((prev) => (prev ? prev + 1 : 1));
+ if (loadedUsers && loadedUsers - 1 === totalPets) setStatus(3);
+ } else if (event.kind === EventKind.textNote) {
+ setLoadedNotes((prev) => (prev ? prev + 1 : 1));
}
}
});
- relayPool?.subscribe('main-channel', {
- kinds: [EventKind.meta, EventKind.petNames],
- authors: [publicKey],
- });
};
const loadPets: (event: Event) => void = (event) => {
if (database) {
setTotalPets(event.tags.length);
- insertUserContact(event, database).then(() => {
- relayPool?.subscribe('main-channel', {
- kinds: [EventKind.meta],
- authors: event.tags.map((tag) => tagToUser(tag).id),
+ if (event.tags.length > 0) {
+ setStatus(2);
+ insertUserContact(event, database).then(() => {
+ requestUserData(event);
});
- })
- setStatus(2);
+ } else {
+ setStatus(4);
+ }
}
};
- const requestUsers: (database: SQLiteDatabase) => void = () => {
- if (database && status < 3) {
- setUsersReady(true);
- getUsers(database, { exludeIds: [publicKey], contacts: true }).then((users) => {
- const message: RelayFilters = {
- kinds: [EventKind.textNote, EventKind.recommendServer],
- 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)
- }
+ const requestUserData: (event: Event) => void = (event) => {
+ if (publicKey) {
+ const authors: string[] = [publicKey, ...event.tags.map((tag) => tagToUser(tag).id)];
+ relayPool?.subscribe('main-channel', {
+ kinds: [EventKind.meta],
+ authors,
+ });
+ relayPool?.subscribe('main-channel', {
+ kinds: [EventKind.textNote, EventKind.recommendServer],
+ authors,
+ limit: 20,
+ });
+ relayPool?.subscribe('main-channel', {
+ kinds: [EventKind.textNote, EventKind.recommendServer],
+ authors: [publicKey],
+ limit: 10,
});
- setTimeout(() => requestUsers(database), 10000);
}
};
const onPress: () => void = () => {
setLoading(true);
- setPublicKey(getPublickey(privateKey));
+ setPrivateKey(inputValue);
setStatus(1);
- EncryptedStorage.setItem('privateKey', privateKey);
+ EncryptedStorage.setItem('privateKey', inputValue);
};
const statusName: { [status: number]: string } = {
0: t('landing.connect'),
1: t('landing.connecting'),
- 2: `${t('landing.loadingContacts')} ${loadedUsers}/${totalPets ?? 0}`,
+ 2: t('landing.loadingContacts'),
3: t('landing.loadingTimeline'),
+ 4: t('landing.ready'),
};
return (
@@ -159,15 +143,15 @@ export const LandingPage: React.FC = () => {
NOSTROS
- {!init && (
+ {(!privateKey || status !== 0) && (
<>