Some fixes and SQL improvement

This commit is contained in:
KoalaSat 2022-11-02 03:35:11 +01:00
parent cda2d1d8f2
commit 4630f30eed
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
10 changed files with 116 additions and 127 deletions

View File

@ -1,6 +1,9 @@
import App from './frontend'
import { Buffer as SafeBuffer } from 'safe-buffer'
import SQLite from 'react-native-sqlite-storage'
global.Buffer = SafeBuffer
SQLite.DEBUG(true)
export default App

View File

@ -5,7 +5,7 @@ buildscript {
buildToolsVersion = "31.0.0"
minSdkVersion = 21
compileSdkVersion = 31
targetSdkVersion = 31
targetSdkVersion = 29
if (System.properties['os.arch'] == "aarch64") {
// For M1 Users we need to use the NDK 24 which added support for aarch64

View File

@ -21,8 +21,8 @@ export const ContactsPage: React.FC = () => {
const { relayPool, publicKey, lastEventId, setLastEventId, privateKey } =
useContext(RelayPoolContext)
const theme = useTheme()
const [users, setUsers] = useState<User[]>([])
const [refreshing, setRefreshing] = useState(false)
const [users, setUsers] = useState<User[]>()
const [refreshing, setRefreshing] = useState(true)
const [showAddContact, setShowAddContant] = useState<boolean>(false)
const [contactInput, setContactInput] = useState<string>()
const { t } = useTranslation('common')
@ -30,6 +30,7 @@ export const ContactsPage: React.FC = () => {
useEffect(() => {
if (database && publicKey) {
getUsers(database, { contacts: true }).then((results) => {
if (users) setRefreshing(false)
if (results) setUsers(results)
})
}
@ -75,7 +76,7 @@ export const ContactsPage: React.FC = () => {
const onRefresh = useCallback(() => {
setRefreshing(true)
relayPool?.unsubscribeAll()
subscribeContacts().finally(() => setRefreshing(false))
subscribeContacts()
}, [])
const styles = StyleSheet.create({
@ -112,7 +113,7 @@ export const ContactsPage: React.FC = () => {
horizontal={false}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
>
{users.map((user) => (
{users?.map((user) => (
<UserCard user={user} key={user.id} />
))}
</ScrollView>

View File

@ -18,7 +18,6 @@ import { EventKind } from '../../lib/nostr/Events'
import { RelayFilters } from '../../lib/nostr/Relay'
import { getReplyEventId } from '../../Functions/RelayFunctions/Events'
import { getUsers, User } from '../../Functions/DatabaseFunctions/Users'
import Loading from '../Loading'
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
export const HomePage: React.FC = () => {
@ -29,11 +28,11 @@ export const HomePage: React.FC = () => {
const [pageSize, setPageSize] = useState<number>(initialPageSize)
const [notes, setNotes] = useState<Note[]>([])
const [authors, setAuthors] = useState<User[]>([])
const [refreshing, setRefreshing] = useState(false)
const [refreshing, setRefreshing] = useState(true)
const calculateInitialNotes: () => Promise<void> = async () => {
return await new Promise<void>((resolve, reject) => {
if (database && publicKey && relayPool) {
return await new Promise<void>((resolve) => {
if (database && publicKey) {
getNotes(database, { limit: 1 }).then((notes) => {
getUsers(database, { contacts: true, includeIds: [publicKey] }).then((users) => {
setAuthors(users)
@ -41,8 +40,6 @@ export const HomePage: React.FC = () => {
resolve()
})
})
} else {
reject(new Error('Not Ready'))
}
})
}
@ -71,6 +68,9 @@ export const HomePage: React.FC = () => {
getNotes(database, { contacts: true, includeIds: [publicKey], limit: pageSize }).then(
(notes) => {
setNotes(notes)
if (notes.length > 0 || authors.length === 0) {
setRefreshing(false)
}
},
)
}
@ -78,7 +78,8 @@ export const HomePage: React.FC = () => {
useEffect(() => {
relayPool?.unsubscribeAll()
}, [])
calculateInitialNotes().then(() => loadNotes())
}, [publicKey])
useEffect(() => {
loadNotes()
@ -92,15 +93,10 @@ export const HomePage: React.FC = () => {
}
}, [pageSize])
useEffect(() => {
loadNotes()
calculateInitialNotes()
}, [database, publicKey, relayPool])
const onRefresh = useCallback(() => {
setRefreshing(true)
relayPool?.unsubscribeAll()
calculateInitialNotes().finally(() => setRefreshing(false))
calculateInitialNotes().then(() => loadNotes())
}, [])
const onPress: (note: Note) => void = (note) => {
@ -149,22 +145,18 @@ export const HomePage: React.FC = () => {
return (
<>
<Layout style={styles.container} level='3'>
{notes.length === 0 && authors.length !== 0 ? (
<Loading />
) : (
<ScrollView
onScroll={onScroll}
horizontal={false}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
>
{notes.map((note) => itemCard(note))}
{notes.length >= initialPageSize && (
<View style={styles.loadingBottom}>
<Spinner size='tiny' />
</View>
)}
</ScrollView>
)}
<ScrollView
onScroll={onScroll}
horizontal={false}
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
>
{notes.map((note) => itemCard(note))}
{notes.length >= initialPageSize && (
<View style={styles.loadingBottom}>
<Spinner size='tiny' />
</View>
)}
</ScrollView>
</Layout>
{privateKey && (
<TouchableOpacity

View File

@ -14,8 +14,8 @@ import { generateRandomKey, getPublickey } from '../../../lib/nostr/Bip'
import { showMessage } from 'react-native-flash-message'
export const Logger: React.FC = () => {
const { database, goToPage } = useContext(AppContext)
const { privateKey, publicKey, relayPool, setPrivateKey, setPublicKey } =
const { database, goToPage, loadingDb } = useContext(AppContext)
const { privateKey, publicKey, relayPool, loadingRelayPool, setPrivateKey, setPublicKey } =
useContext(RelayPoolContext)
const { t } = useTranslation('common')
const theme = useTheme()
@ -27,7 +27,7 @@ export const Logger: React.FC = () => {
const [loadedUsers, setLoadedUsers] = useState<number>()
useEffect(() => {
if (relayPool && publicKey) {
if (!loadingRelayPool && publicKey) {
relayPool?.unsubscribeAll()
setStatus(1)
initEvents()
@ -36,7 +36,7 @@ export const Logger: React.FC = () => {
authors: [publicKey],
})
}
}, [relayPool, publicKey])
}, [loadingRelayPool, publicKey, loadingDb])
useEffect(() => {
if (status > 2) {
@ -46,7 +46,7 @@ export const Logger: React.FC = () => {
}, [status])
useEffect(() => {
if (status) {
if (status > 1) {
const timer = setTimeout(() => setStatus(3), 8000)
return () => {
clearTimeout(timer)

View File

@ -110,7 +110,7 @@ export const NotePage: React.FC = () => {
}
const subscribeNotes: () => Promise<void> = async () => {
return await new Promise<void>((resolve, reject) => {
return await new Promise<void>((resolve) => {
if (database) {
getNotes(database, { filters: { id: eventId } }).then((events) => {
if (events.length > 0) {
@ -140,8 +140,6 @@ export const NotePage: React.FC = () => {
resolve()
}
})
} else {
reject(new Error('Not Ready'))
}
})
}

View File

@ -23,13 +23,7 @@ import UserAvatar from 'react-native-user-avatar'
import { getNotes, Note } from '../../Functions/DatabaseFunctions/Notes'
import NoteCard from '../NoteCard'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import {
getUser,
removeContact,
addContact,
User,
getUsers,
} from '../../Functions/DatabaseFunctions/Users'
import { getUser, removeContact, addContact, User } from '../../Functions/DatabaseFunctions/Users'
import { EventKind, Event } from '../../lib/nostr/Events'
import Relay, { RelayFilters } from '../../lib/nostr/Relay'
import Icon from 'react-native-vector-icons/FontAwesome5'
@ -38,14 +32,11 @@ import { getReplyEventId } from '../../Functions/RelayFunctions/Events'
import Loading from '../Loading'
import { storeEvent } from '../../Functions/DatabaseFunctions/Events'
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import { useTranslation } from 'react-i18next'
export const ProfilePage: React.FC = () => {
const { database, page, goToPage, goBack } = useContext(AppContext)
const { publicKey, privateKey, lastEventId, relayPool, setLastEventId } =
useContext(RelayPoolContext)
const { publicKey, privateKey, lastEventId, relayPool } = useContext(RelayPoolContext)
const theme = useTheme()
const { t } = useTranslation('common')
const initialPageSize = 10
const [notes, setNotes] = useState<Note[]>()
const [user, setUser] = useState<User>()
@ -58,13 +49,35 @@ export const ProfilePage: React.FC = () => {
const username = user?.name === '' ? user?.id : user?.name
useEffect(() => {
setContactsIds(undefined)
setNotes(undefined)
setUser(undefined)
loadProfile()
if (page !== '') {
setContactsIds(undefined)
setNotes(undefined)
setUser(undefined)
loadProfile()
}
}, [page])
useEffect(() => {
loadUser()
loadNotes()
}, [lastEventId])
useEffect(() => {
if (pageSize > initialPageSize && notes) {
relayPool?.unsubscribeAll()
loadUser()
loadNotes()
subscribeNotes(undefined, notes[notes.length - 1]?.created_at)
}
}, [pageSize])
const onRefresh = useCallback(() => {
setRefreshing(true)
relayPool?.unsubscribeAll()
loadProfile().finally(() => setRefreshing(false))
}, [])
const loadUser: () => void = () => {
if (database) {
getUser(userId, database).then((result) => {
if (result) {
@ -72,14 +85,8 @@ export const ProfilePage: React.FC = () => {
setIsContact(result?.contact)
}
})
if (userId === publicKey) {
getUsers(database, { contacts: true }).then((users) => {
setContactsIds(users.map((user) => user.id))
})
}
loadNotes()
}
}, [lastEventId])
}
const removeAuthor: () => void = () => {
if (relayPool && database && publicKey) {
@ -149,20 +156,6 @@ export const ProfilePage: React.FC = () => {
}
}
const onRefresh = useCallback(() => {
setRefreshing(true)
relayPool?.unsubscribeAll()
loadProfile().finally(() => setRefreshing(false))
}, [])
useEffect(() => {
if (pageSize > initialPageSize && notes) {
relayPool?.unsubscribeAll()
subscribeNotes(undefined, notes[notes.length - 1]?.created_at)
loadNotes()
}
}, [pageSize])
const loadNotes: () => void = () => {
if (database) {
getNotes(database, { filters: { pubkey: userId }, limit: pageSize }).then((results) => {
@ -197,7 +190,7 @@ export const ProfilePage: React.FC = () => {
}
const loadProfile: () => Promise<void> = async () => {
return await new Promise<void>((resolve, reject) => {
return await new Promise<void>((resolve) => {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta, EventKind.petNames],
authors: [userId],
@ -210,14 +203,10 @@ export const ProfilePage: React.FC = () => {
const ids = event.tags.map((tag) => tagToUser(tag).id)
setContactsIds(ids)
} else if (event.kind === EventKind.meta) {
storeEvent(event, database).finally(() => {
if (event?.id) setLastEventId(event.id)
})
storeEvent(event, database)
}
calculateInitialNotes()
}
} else {
reject(new Error('Not Ready'))
}
})
resolve()
@ -357,7 +346,7 @@ export const ProfilePage: React.FC = () => {
/>
</>
) : (
<Text>{t('profilePage.profileNotCreated')}</Text>
<></>
)}
</Layout>
<TouchableOpacity onPress={onPressId}>

View File

@ -34,15 +34,17 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
const init: () => void = () => {
SInfo.getItem('privateKey', {}).then((result) => {
const db = initDatabase()
setDatabase(db)
if (!result || result === '') {
createInitDatabase(db).then(() => {
const onReady: () => void = () => {
if (!result || result === '') {
createInitDatabase(db).then(() => {
setLoadingDb(false)
})
} else {
setLoadingDb(false)
})
} else {
setLoadingDb(false)
}
}
const db = initDatabase(onReady)
setDatabase(db)
})
}

View File

@ -10,6 +10,7 @@ import SInfo from 'react-native-sensitive-info'
import { getPublickey } from '../lib/nostr/Bip'
export interface RelayPoolContextProps {
loadingRelayPool: boolean
relayPool?: RelayPool
setRelayPool: (relayPool: RelayPool) => void
publicKey?: string
@ -25,6 +26,7 @@ export interface RelayPoolContextProviderProps {
}
export const initialRelayPoolContext: RelayPoolContextProps = {
loadingRelayPool: true,
setPublicKey: () => {},
setPrivateKey: () => {},
setRelayPool: () => {},
@ -39,7 +41,10 @@ export const RelayPoolContextProvider = ({
const [publicKey, setPublicKey] = useState<string>()
const [privateKey, setPrivateKey] = useState<string>()
const [relayPool, setRelayPool] = useState<RelayPool>()
const [lastEventId, setLastEventId] = useState<string>()
const [loadingRelayPool, setLoadingRelayPool] = useState<boolean>(
initialRelayPoolContext.loadingRelayPool,
)
const [lastEventId, setLastEventId] = useState<string>('')
const [lastPage, setLastPage] = useState<string>(page)
const loadRelayPool: () => void = () => {
@ -74,23 +79,16 @@ export const 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)
.then(() => setLastEventId(event.id))
.catch(() => setLastEventId(event.id))
storeEvent(event, database).finally(() => setLastEventId(event.id))
}
},
)
setRelayPool(initRelayPool)
setLoadingRelayPool(false)
})
}
}
useEffect(() => {
if ((privateKey !== '' || publicKey !== '') && !loadingDb && !relayPool) {
loadRelayPool()
}
}, [privateKey, loadingDb])
useEffect(() => {
if (relayPool && lastPage !== page) {
relayPool.removeOn('event', lastPage)
@ -99,29 +97,36 @@ export const RelayPoolContextProvider = ({
}, [page])
useEffect(() => {
SInfo.getItem('privateKey', {}).then((privateResult) => {
if (privateResult && privateResult !== '') {
loadRelayPool()
goToPage('home', true)
setPrivateKey(privateResult)
setPublicKey(getPublickey(privateResult))
} else {
SInfo.getItem('publicKey', {}).then((publicResult) => {
if (publicResult && publicResult !== '') {
loadRelayPool()
goToPage('home', true)
setPublicKey(publicResult)
} else {
goToPage('landing', true)
}
})
}
})
}, [])
if (publicKey && publicKey !== '') {
loadRelayPool()
}
}, [publicKey])
useEffect(() => {
if (!loadingDb) {
SInfo.getItem('privateKey', {}).then((privateResult) => {
if (privateResult && privateResult !== '') {
goToPage('home', true)
setPrivateKey(privateResult)
setPublicKey(getPublickey(privateResult))
} else {
SInfo.getItem('publicKey', {}).then((publicResult) => {
if (publicResult && publicResult !== '') {
goToPage('home', true)
setPublicKey(publicResult)
} else {
goToPage('landing', true)
}
})
}
})
}
}, [loadingDb])
return (
<RelayPoolContext.Provider
value={{
loadingRelayPool,
relayPool,
setRelayPool,
publicKey,

View File

@ -1,12 +1,11 @@
import SQLite, { ResultSet, SQLiteDatabase, Transaction } from 'react-native-sqlite-storage'
import { errorCallback } from './Errors'
export const initDatabase: () => SQLiteDatabase = () => {
return SQLite.openDatabase(
{ name: 'nostros.db', location: 'default' },
() => {},
() => {},
)
export const initDatabase: (onReady: () => void, onError?: () => void) => SQLiteDatabase = (
onReady,
onError,
) => {
return SQLite.openDatabase({ name: 'nostros.db' }, onReady, onError)
}
export const getItems: (resultSet: ResultSet) => object[] = (resultSet) => {