Better events

This commit is contained in:
KoalaSat 2022-11-02 23:11:43 +01:00
parent dc16a5799c
commit 129ca8ed1f
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
11 changed files with 237 additions and 178 deletions

View File

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

View File

@ -14,7 +14,7 @@ import {
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'
import { populatePets, tagToUser } from '../../Functions/RelayFunctions/Users' import { populatePets } from '../../Functions/RelayFunctions/Users'
export const ContactsPage: React.FC = () => { export const ContactsPage: React.FC = () => {
const { database } = useContext(AppContext) const { database } = useContext(AppContext)
@ -23,22 +23,27 @@ export const ContactsPage: React.FC = () => {
const theme = useTheme() const theme = useTheme()
const [users, setUsers] = useState<User[]>() const [users, setUsers] = useState<User[]>()
const [refreshing, setRefreshing] = useState(true) const [refreshing, setRefreshing] = useState(true)
const [showAddContact, setShowAddContant] = useState<boolean>(false) const [showAddContact, setShowAddContact] = useState<boolean>(false)
const [contactInput, setContactInput] = useState<string>() const [contactInput, setContactInput] = useState<string>()
const { t } = useTranslation('common') const { t } = useTranslation('common')
useEffect(() => { useEffect(() => {
loadUsers()
}, [lastEventId])
useEffect(() => {
subscribeContacts()
}, [])
const loadUsers: () => void = () => {
if (database && publicKey) { if (database && publicKey) {
getUsers(database, { contacts: true }).then((results) => { getUsers(database, { contacts: true }).then((results) => {
if (users) setRefreshing(false) if (users) setRefreshing(false)
if (results) setUsers(results) if (results) setUsers(results)
}) })
} }
}, [lastEventId]) }
useEffect(() => {
subscribeContacts()
}, [])
const subscribeContacts: () => Promise<void> = async () => { const subscribeContacts: () => Promise<void> = async () => {
return await new Promise<void>((resolve, _reject) => { return await new Promise<void>((resolve, _reject) => {
@ -47,10 +52,6 @@ export const ContactsPage: React.FC = () => {
console.log('CONTACTS PAGE EVENT =======>', relay.url, event) console.log('CONTACTS PAGE 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 ?? ''))
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta],
authors: event.tags.map((tag) => tagToUser(tag).id),
})
relayPool?.removeOn('event', 'contacts') relayPool?.removeOn('event', 'contacts')
} }
}) })
@ -68,7 +69,8 @@ export const ContactsPage: React.FC = () => {
if (contactInput && relayPool && database && publicKey) { if (contactInput && relayPool && database && publicKey) {
addContact(contactInput, database).then(() => { addContact(contactInput, database).then(() => {
populatePets(relayPool, database, publicKey) populatePets(relayPool, database, publicKey)
setShowAddContant(false) setShowAddContact(false)
loadUsers()
}) })
} }
} }
@ -122,7 +124,7 @@ export const ContactsPage: React.FC = () => {
style={styles.modal} style={styles.modal}
visible={showAddContact} visible={showAddContact}
backdropStyle={styles.backdrop} backdropStyle={styles.backdrop}
onBackdropPress={() => setShowAddContant(false)} onBackdropPress={() => setShowAddContact(false)}
> >
<Card disabled={true}> <Card disabled={true}>
<Layout style={styles.actionContainer}> <Layout style={styles.actionContainer}>
@ -155,7 +157,7 @@ export const ContactsPage: React.FC = () => {
backgroundColor: theme['color-warning-500'], backgroundColor: theme['color-warning-500'],
borderRadius: 100, borderRadius: 100,
}} }}
onPress={() => setShowAddContant(true)} onPress={() => setShowAddContact(true)}
> >
<Icon name='user-plus' size={30} color={theme['text-basic-color']} solid /> <Icon name='user-plus' size={30} color={theme['text-basic-color']} solid />
</TouchableOpacity> </TouchableOpacity>

View File

@ -33,34 +33,35 @@ export const HomePage: React.FC = () => {
const calculateInitialNotes: () => Promise<void> = async () => { const calculateInitialNotes: () => Promise<void> = async () => {
return await new Promise<void>((resolve) => { return await new Promise<void>((resolve) => {
if (database && publicKey) { if (database && publicKey) {
getNotes(database, { limit: 1 }).then((notes) => {
getUsers(database, { contacts: true, includeIds: [publicKey] }).then((users) => { getUsers(database, { contacts: true, includeIds: [publicKey] }).then((users) => {
setAuthors(users) setAuthors(users)
subscribeNotes(users, notes[0]?.created_at) subscribeNotes(users)
resolve() resolve()
}) })
})
} }
}) })
} }
const subscribeNotes: (users: User[], since?: number, until?: number) => void = ( const subscribeNotes: (users: User[], past?: boolean) => void = (
users, users,
since, past
until,
) => { ) => {
if (!database || !publicKey) return
const limit = past ? pageSize : 1
getNotes(database, { contacts: true, includeIds: [publicKey], limit }).then((results) => {
const message: RelayFilters = { const message: RelayFilters = {
kinds: [EventKind.textNote, EventKind.recommendServer], kinds: [EventKind.textNote, EventKind.recommendServer],
authors: users.map((user) => user.id), authors: users.map((user) => user.id),
limit: initialPageSize, limit: initialPageSize,
} }
if (since) { if (past) {
message.since = since message.until = results[results.length - 1]?.created_at
} } else {
if (until) { message.since = results[0]?.created_at
message.until = until
} }
relayPool?.subscribe('main-channel', message) relayPool?.subscribe('main-channel', message)
})
} }
const loadNotes: () => void = () => { const loadNotes: () => void = () => {
@ -88,7 +89,7 @@ export const HomePage: React.FC = () => {
useEffect(() => { useEffect(() => {
if (pageSize > initialPageSize) { if (pageSize > initialPageSize) {
relayPool?.unsubscribeAll() relayPool?.unsubscribeAll()
subscribeNotes(authors, undefined, notes[notes.length - 1]?.created_at) subscribeNotes(authors, true)
loadNotes() loadNotes()
} }
}, [pageSize]) }, [pageSize])

View File

@ -22,13 +22,30 @@ export const Logger: React.FC = () => {
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 [isPrivate, setIsPrivate] = useState<boolean>(true) const [isPrivate, setIsPrivate] = useState<boolean>(true)
const [totalPets, setTotalPets] = useState<number>() const [authors, setAuthors] = useState<string[]>([])
const [inputValue, setInputValue] = useState<string>('') const [inputValue, setInputValue] = useState<string>('')
const [loadedUsers, setLoadedUsers] = useState<number>() const [loadedUsers, setLoadedUsers] = useState<number>()
const [lastEventId, setLastEventId] = useState<string>('')
const onPress: () => void = () => {
if (inputValue && inputValue !== '') {
setLoading(true)
setStatus(1)
if (isPrivate) {
setPrivateKey(inputValue)
const publicKey: string = getPublickey(inputValue)
setPublicKey(publicKey)
SInfo.setItem('privateKey', inputValue, {})
SInfo.setItem('publicKey', publicKey, {})
} else {
setPublicKey(inputValue)
SInfo.setItem('publicKey', inputValue, {})
}
}
}
useEffect(() => { useEffect(() => {
if (!loadingRelayPool && publicKey) { if (!loadingRelayPool && !loadingDb && publicKey) {
relayPool?.unsubscribeAll()
setStatus(1) setStatus(1)
initEvents() initEvents()
relayPool?.subscribe('main-channel', { relayPool?.subscribe('main-channel', {
@ -38,31 +55,16 @@ export const Logger: React.FC = () => {
} }
}, [loadingRelayPool, publicKey, loadingDb]) }, [loadingRelayPool, publicKey, loadingDb])
useEffect(() => {
if (status > 2) {
relayPool?.removeOn('event', 'landing')
goToPage('home', true)
}
}, [status])
useEffect(() => {
if (status > 1) {
const timer = setTimeout(() => setStatus(3), 8000)
return () => {
clearTimeout(timer)
}
}
}, [status])
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) => {
console.log('LANDING EVENT =======>', event) console.log('LANDING EVENT =======>', event)
if (event && database) { if (event && database) {
setLastEventId(event?.id ?? '')
if (event.kind === EventKind.petNames) { if (event.kind === EventKind.petNames) {
loadPets(event) loadPets(event)
} else if (event.kind === EventKind.meta) { } else if (event.kind === EventKind.meta) {
setLoadedUsers((prev) => (prev ? prev + 1 : 1)) setLoadedUsers((prev) => (prev ? prev + 1 : 1))
if (loadedUsers && loadedUsers - 1 === totalPets) setStatus(3) if (loadedUsers && loadedUsers >= authors.length && status < 3) setStatus(3)
} }
} }
}) })
@ -70,14 +72,13 @@ export const Logger: React.FC = () => {
const loadPets: (event: Event) => void = (event) => { const loadPets: (event: Event) => void = (event) => {
if (database) { if (database) {
setTotalPets(event.tags.length)
if (event.tags.length > 0) { if (event.tags.length > 0) {
setStatus(2) setStatus(2)
insertUserContact(event, database).then(() => { insertUserContact(event, database).then(() => {
requestUserData(event) requestUserData(event)
}) })
} else { } else {
setStatus(3) setStatus(4)
} }
} }
} }
@ -85,6 +86,7 @@ export const Logger: React.FC = () => {
const requestUserData: (event: Event) => void = (event) => { const requestUserData: (event: Event) => void = (event) => {
if (publicKey) { if (publicKey) {
const authors: string[] = [publicKey, ...event.tags.map((tag) => tagToUser(tag).id)] const authors: string[] = [publicKey, ...event.tags.map((tag) => tagToUser(tag).id)]
setAuthors(authors)
relayPool?.subscribe('main-channel', { relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta], kinds: [EventKind.meta],
authors, authors,
@ -92,6 +94,25 @@ export const Logger: React.FC = () => {
} }
} }
useEffect(() => {
if (status > 3) {
relayPool?.removeOn('event', 'landing')
goToPage('home', true)
} else if (status === 2) {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.textNote, EventKind.recommendServer],
authors,
limit: 15
})
}
if (status > 1) {
const timer = setTimeout(() => setStatus(status + 1), 5000)
return () => {
clearTimeout(timer)
}
}
}, [status, lastEventId])
const randomKeyGenerator: () => JSX.Element = () => { const randomKeyGenerator: () => JSX.Element = () => {
if (!isPrivate) return <></> if (!isPrivate) return <></>
@ -119,28 +140,12 @@ export const Logger: React.FC = () => {
) )
} }
const onPress: () => void = () => {
if (inputValue && inputValue !== '') {
setLoading(true)
setStatus(1)
if (isPrivate) {
setPrivateKey(inputValue)
const publicKey: string = getPublickey(inputValue)
setPublicKey(publicKey)
SInfo.setItem('privateKey', inputValue, {})
SInfo.setItem('publicKey', publicKey, {})
} else {
setPublicKey(inputValue)
SInfo.setItem('publicKey', 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'), 2: t('landing.loadingContacts'),
3: t('landing.ready'), 3: t('landing.loadingEvents'),
4: t('landing.ready'),
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
inputsContainer: { inputsContainer: {

View File

@ -61,7 +61,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({ note }) => {
<Markdown style={markdownStyle}>{note.content}</Markdown> <Markdown style={markdownStyle}>{note.content}</Markdown>
</Layout> </Layout>
<Layout style={styles.footer}> <Layout style={styles.footer}>
<Text appearance='hint'>{moment.unix(note.created_at).format('DD-MM-YYYY HH:MM')}</Text> <Text appearance='hint'>{moment.unix(note.created_at).format('DD-MM-YY hh:mm')}</Text>
</Layout> </Layout>
</Layout> </Layout>
</> </>

View File

@ -49,38 +49,22 @@ export const ProfilePage: React.FC = () => {
const username = user?.name === '' ? user?.id : user?.name const username = user?.name === '' ? user?.id : user?.name
useEffect(() => { useEffect(() => {
if (page !== '') { setRefreshing(true)
relayPool?.unsubscribeAll()
setContactsIds(undefined) setContactsIds(undefined)
setNotes(undefined) setNotes(undefined)
setUser(undefined) setUser(undefined)
loadProfile()
} loadUser()
loadNotes()
subscribeNotes()
}, [page]) }, [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 = () => { const loadUser: () => void = () => {
if (database) { if (database) {
getUser(userId, database).then((result) => { getUser(userId, database).then((result) => {
if (result) { if (result) {
subscribeProfile()
setUser(result) setUser(result)
setIsContact(result?.contact) setIsContact(result?.contact)
} }
@ -88,6 +72,78 @@ export const ProfilePage: React.FC = () => {
} }
} }
const loadNotes: (past?: boolean) => void = (past) => {
if (database) {
getNotes(database, { filters: { pubkey: userId }, limit: pageSize }).then((results) => {
setNotes(results)
setRefreshing(false)
})
}
}
const subscribeNotes: (past?: boolean) => void = (past) => {
if (!database) return
const limit = past ? pageSize : 1
getNotes(database, { filters: { pubkey: userId }, limit }).then((results) => {
const message: RelayFilters = {
kinds: [EventKind.textNote, EventKind.recommendServer],
authors: [userId],
limit: initialPageSize,
}
if (past) {
message.until = results[results.length - 1]?.created_at
} else {
message.since = results[0]?.created_at
}
relayPool?.subscribe('main-channel', message)
})
}
const subscribeProfile: () => Promise<void> = async () => {
return await new Promise<void>((resolve) => {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta, EventKind.petNames],
authors: [userId],
})
relayPool?.on('event', 'profile', (_relay: Relay, _subId?: string, event?: Event) => {
console.log('PROFILE EVENT =======>', event)
if (database) {
if (event?.id && event.pubkey === userId) {
if (event.kind === EventKind.petNames) {
const ids = event.tags.map((tag) => tagToUser(tag).id)
setContactsIds(ids)
} else if (event.kind === EventKind.meta) {
storeEvent(event, database).then(() => setRefreshing(false))
}
}
}
})
resolve()
})
}
useEffect(() => {
if (notes) {
loadUser()
loadNotes()
}
}, [lastEventId])
useEffect(() => {
if (pageSize > initialPageSize && notes) {
loadUser()
loadNotes()
subscribeNotes(true)
}
}, [pageSize])
const onRefresh = useCallback(() => {
setRefreshing(true)
relayPool?.unsubscribeAll()
loadNotes(true)
}, [])
const removeAuthor: () => void = () => { const removeAuthor: () => void = () => {
if (relayPool && database && publicKey) { if (relayPool && database && publicKey) {
removeContact(userId, database).then(() => { removeContact(userId, database).then(() => {
@ -156,69 +212,6 @@ export const ProfilePage: React.FC = () => {
} }
} }
const loadNotes: () => void = () => {
if (database) {
getNotes(database, { filters: { pubkey: userId }, limit: pageSize }).then((results) => {
if (results.length > 0) setNotes(results)
})
}
}
const subscribeNotes: (since?: number, until?: number) => void = (since, until) => {
const message: RelayFilters = {
kinds: [EventKind.textNote, EventKind.recommendServer],
authors: [userId],
limit: initialPageSize,
}
if (since) {
message.since = since
}
if (until) {
message.until = until
}
relayPool?.subscribe('main-channel', message)
}
const calculateInitialNotes: () => void = () => {
if (database) {
getNotes(database, { filters: { pubkey: userId }, limit: pageSize }).then((results) => {
if (results) {
subscribeNotes(results[0]?.created_at)
}
})
}
}
const loadProfile: () => Promise<void> = async () => {
return await new Promise<void>((resolve) => {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.meta, EventKind.petNames],
authors: [userId],
})
relayPool?.on('event', 'profile', (_relay: Relay, _subId?: string, event?: Event) => {
console.log('PROFILE EVENT =======>', event)
if (database) {
if (event?.id && event.pubkey === userId) {
if (event.kind === EventKind.petNames) {
const ids = event.tags.map((tag) => tagToUser(tag).id)
setContactsIds(ids)
} else if (event.kind === EventKind.meta) {
storeEvent(event, database)
}
calculateInitialNotes()
}
}
})
resolve()
})
}
const onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void = (event) => {
if (handleInfinityScroll(event)) {
setPageSize(pageSize + initialPageSize)
}
}
const styles = StyleSheet.create({ const styles = StyleSheet.create({
list: { list: {
flex: 1, flex: 1,
@ -302,6 +295,13 @@ export const ProfilePage: React.FC = () => {
return false return false
} }
const onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void = (event) => {
if (handleInfinityScroll(event)) {
const newSize: number = notes?.length === pageSize ? pageSize + initialPageSize : pageSize
setPageSize(newSize)
}
}
const stats: () => JSX.Element = () => { const stats: () => JSX.Element = () => {
if (contactsIds === undefined) { if (contactsIds === undefined) {
return ( return (
@ -339,7 +339,7 @@ export const ProfilePage: React.FC = () => {
{user ? ( {user ? (
<> <>
<UserAvatar <UserAvatar
name={username} name={username ?? user.id}
src={user?.picture} src={user?.picture}
size={130} size={130}
textColor={theme['text-basic-color']} textColor={theme['text-basic-color']}
@ -377,7 +377,7 @@ export const ProfilePage: React.FC = () => {
/> />
{profile} {profile}
<Layout style={styles.list} level='3'> <Layout style={styles.list} level='3'>
{notes ? ( {notes && notes.length > 0 ? (
<ScrollView <ScrollView
onScroll={onScroll} onScroll={onScroll}
horizontal={false} horizontal={false}

View File

@ -98,21 +98,23 @@ export const RelayPoolContextProvider = ({
useEffect(() => { useEffect(() => {
if (publicKey && publicKey !== '') { if (publicKey && publicKey !== '') {
if (!loadingRelayPool && page !== 'landing') {
goToPage('home', true)
} else {
loadRelayPool() loadRelayPool()
} }
}, [publicKey]) }
}, [publicKey, loadingRelayPool])
useEffect(() => { useEffect(() => {
if (!loadingDb) { if (!loadingDb) {
SInfo.getItem('privateKey', {}).then((privateResult) => { SInfo.getItem('privateKey', {}).then((privateResult) => {
if (privateResult && privateResult !== '') { if (privateResult && privateResult !== '') {
goToPage('home', true)
setPrivateKey(privateResult) setPrivateKey(privateResult)
setPublicKey(getPublickey(privateResult)) setPublicKey(getPublickey(privateResult))
} else { } else {
SInfo.getItem('publicKey', {}).then((publicResult) => { SInfo.getItem('publicKey', {}).then((publicResult) => {
if (publicResult && publicResult !== '') { if (publicResult && publicResult !== '') {
goToPage('home', true)
setPublicKey(publicResult) setPublicKey(publicResult)
} else { } else {
goToPage('landing', true) goToPage('landing', true)

View File

@ -4,6 +4,7 @@
"connect": "Connect", "connect": "Connect",
"connecting": "Connecting", "connecting": "Connecting",
"loadingContacts": "Loading Contacts", "loadingContacts": "Loading Contacts",
"loadingEvents": "Loading Events",
"ready": "Ready", "ready": "Ready",
"privateKey": "Private Key", "privateKey": "Private Key",
"publicKey": "Public Key" "publicKey": "Public Key"

View File

@ -1,3 +1,4 @@
// import { spawnThread } from 'react-native-multithreading'
import { signEvent, validateEvent, Event } from '../Events' import { signEvent, validateEvent, Event } from '../Events'
import Relay, { RelayFilters, RelayOptions } from '../Relay' import Relay, { RelayFilters, RelayOptions } from '../Relay'
@ -41,9 +42,9 @@ class RelayPool {
Object.keys(this.onFunctions.open).forEach((id) => this.onFunctions.open[id](openRelay)) Object.keys(this.onFunctions.open).forEach((id) => this.onFunctions.open[id](openRelay))
} }
relay.onEvent = (eventRelay, subId, event) => { relay.onEvent = (eventRelay, subId, event) => {
Object.keys(this.onFunctions.event).forEach((id) => Object.keys(this.onFunctions.event).forEach((id) => {
this.onFunctions.event[id](eventRelay, subId, event), this.onFunctions.event[id](eventRelay, subId, event)
) })
} }
relay.onEsoe = (eventRelay, subId) => { relay.onEsoe = (eventRelay, subId) => {
Object.keys(this.onFunctions.esoe).forEach((id) => Object.keys(this.onFunctions.esoe).forEach((id) =>

View File

@ -29,6 +29,8 @@
"react-native-bidirectional-infinite-scroll": "^0.3.3", "react-native-bidirectional-infinite-scroll": "^0.3.3",
"react-native-flash-message": "^0.3.1", "react-native-flash-message": "^0.3.1",
"react-native-markdown-display": "^7.0.0-alpha.2", "react-native-markdown-display": "^7.0.0-alpha.2",
"react-native-multithreading": "^1.1.1",
"react-native-reanimated": "^2.12.0",
"react-native-securerandom": "^1.0.1", "react-native-securerandom": "^1.0.1",
"react-native-sensitive-info": "^5.5.8", "react-native-sensitive-info": "^5.5.8",
"react-native-sqlite-storage": "^6.0.1", "react-native-sqlite-storage": "^6.0.1",

View File

@ -579,6 +579,13 @@
"@babel/helper-create-regexp-features-plugin" "^7.19.0" "@babel/helper-create-regexp-features-plugin" "^7.19.0"
"@babel/helper-plugin-utils" "^7.19.0" "@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-transform-object-assign@^7.16.7":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.18.6.tgz#7830b4b6f83e1374a5afb9f6111bcfaea872cdd2"
integrity sha512-mQisZ3JfqWh2gVXvfqYCAAyRs6+7oev+myBsTwW5RnPhYXOTuCEw2oe3YgxlXMViXUS53lG8koulI7mJ+8JE+A==
dependencies:
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-transform-object-super@^7.0.0": "@babel/plugin-transform-object-super@^7.0.0":
version "7.18.6" version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c"
@ -700,7 +707,7 @@
"@babel/helper-validator-option" "^7.18.6" "@babel/helper-validator-option" "^7.18.6"
"@babel/plugin-transform-flow-strip-types" "^7.18.6" "@babel/plugin-transform-flow-strip-types" "^7.18.6"
"@babel/preset-typescript@^7.13.0": "@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.16.7":
version "7.18.6" version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399"
integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==
@ -1427,6 +1434,11 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/invariant@^2.2.35":
version "2.2.35"
resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be"
integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44"
@ -4935,6 +4947,11 @@ lodash.debounce@^4.0.8:
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
lodash.merge@^4.6.1, lodash.merge@^4.6.2: lodash.merge@^4.6.1, lodash.merge@^4.6.2:
version "4.6.2" version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
@ -6106,6 +6123,24 @@ react-native-markdown-display@^7.0.0-alpha.2:
prop-types "^15.7.2" prop-types "^15.7.2"
react-native-fit-image "^1.5.5" react-native-fit-image "^1.5.5"
react-native-multithreading@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/react-native-multithreading/-/react-native-multithreading-1.1.1.tgz#e1522ecd56115993d444a69c21bca49ca123bf4e"
integrity sha512-ceJQRZAPjH5LfrDjb5svF4F18Ne7QR7QLQUFO0huAe+9w0hd2C3PR12ATxljo+590GXCzWRt2ruR9pY3EstFAQ==
react-native-reanimated@^2.12.0:
version "2.12.0"
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.12.0.tgz#5821eecfb1769b1617a67a2d4dec12fdeedb2b6e"
integrity sha512-nrlPyw+Hx9u4iJhZk9PoTvDo/QmVAd+bo7OK9Tv3hveNEF9++5oig/g3Uv9V93shy9avTYGsUprUvAEt/xdzeQ==
dependencies:
"@babel/plugin-transform-object-assign" "^7.16.7"
"@babel/preset-typescript" "^7.16.7"
"@types/invariant" "^2.2.35"
invariant "^2.2.4"
lodash.isequal "^4.5.0"
setimmediate "^1.0.5"
string-hash-64 "^1.0.3"
react-native-securerandom@^1.0.1: react-native-securerandom@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/react-native-securerandom/-/react-native-securerandom-1.0.1.tgz#dc983cce980c80d1af62406e2ef2917ed0ada55f" resolved "https://registry.yarnpkg.com/react-native-securerandom/-/react-native-securerandom-1.0.1.tgz#dc983cce980c80d1af62406e2ef2917ed0ada55f"
@ -6548,6 +6583,11 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3" is-plain-object "^2.0.3"
split-string "^3.0.1" split-string "^3.0.1"
setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
setprototypeof@1.2.0: setprototypeof@1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
@ -6773,6 +6813,11 @@ stream@^0.0.2:
dependencies: dependencies:
emitter-component "^1.1.1" emitter-component "^1.1.1"
string-hash-64@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322"
integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==
string-length@^4.0.1: string-length@^4.0.1:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"