This commit is contained in:
KoalaSat 2022-12-25 18:28:07 +01:00
parent f6093f1f22
commit 2ecb4261db
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
14 changed files with 242 additions and 174 deletions

View File

@ -38,7 +38,7 @@ public class Event {
if (kind.equals("0")) {
saveUserMeta(database);
} else if (kind.equals("1") || kind.equals("2")) {
saveNote(database);
saveNote(database, userPubKey);
} else if (kind.equals("3")) {
if (pubkey.equals(userPubKey)) {
savePets(database);
@ -98,6 +98,23 @@ public class Event {
return replyEventId;
}
protected Boolean getUserMentioned(String userPubKey) {
JSONArray eTags = filterTags("p");
Boolean userMentioned = false;
try {
for (int i = 0; i < eTags.length(); ++i) {
JSONArray tag = eTags.getJSONArray(i);
if (tag.getString(1).equals(userPubKey)) {
userMentioned = true;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return userMentioned;
}
protected String saveFollower(String pubKey) {
JSONArray eTags = filterTags("p");
String mainEventId = null;
@ -136,7 +153,7 @@ public class Event {
return filtered;
}
protected void saveNote(SQLiteDatabase database) {
protected void saveNote(SQLiteDatabase database, String userPubKey) {
ContentValues values = new ContentValues();
values.put("id", id);
values.put("content", content.replace("'", "''"));
@ -147,6 +164,7 @@ public class Event {
values.put("tags", tags.toString());
values.put("main_event_id", getMainEventId());
values.put("reply_event_id", getReplyEventId());
values.put("user_mentioned", getUserMentioned(userPubKey));
database.replace("nostros_notes", null, values);
}

View File

@ -57,6 +57,8 @@ public class DatabaseModule {
" conversation_id TEXT NOT NULL,\n" +
" read BOOLEAN DEFAULT FALSE\n" +
" );");
database.execSQL("ALTER TABLE nostros_notes ADD COLUMN user_mentioned BOOLEAN DEFAULT FALSE;");
database.execSQL("ALTER TABLE nostros_notes ADD COLUMN seen BOOLEAN DEFAULT FALSE;");
}
public void saveEvent(JSONObject data, String userPubKey) throws JSONException {

View File

@ -16,8 +16,7 @@ import Icon from 'react-native-vector-icons/FontAwesome5'
import { username, usersToTags } from '../../Functions/RelayFunctions/Users'
import moment from 'moment'
import { encrypt } from '../../lib/nostr/Crypto'
import Markdown from 'react-native-markdown-display'
import { markdownIt, markdownStyle } from '../../Constants/AppConstants'
import TextBox from '../TextBox'
export const ConversationPage: React.FC = () => {
const theme = useTheme()
@ -124,9 +123,9 @@ export const ConversationPage: React.FC = () => {
{moment.unix(message.created_at).format('HH:mm DD-MM-YY')}
</Text>
</Layout>
<Markdown style={markdownStyle(theme)} markdownit={markdownIt}>
{message.content}
</Markdown>
<TextBox note={message}>
<Text>{message.content}</Text>
</TextBox>
</Layout>
</Layout>
</Layout>
@ -146,9 +145,9 @@ export const ConversationPage: React.FC = () => {
)}
</Layout>
</Layout>
<Markdown style={markdownStyle(theme)} markdownit={markdownIt}>
{message.content}
</Markdown>
<TextBox note={message}>
<Text>{message.content}</Text>
</TextBox>
</Layout>
</Layout>
)

View File

@ -142,7 +142,10 @@ export const Logger: React.FC = () => {
<Layout style={styles.buttonssContainer}>
<Layout style={styles.buttonLeft}>
<Button
onPress={() => setIsPrivate(!isPrivate)}
onPress={() => {
setIsPrivate(!isPrivate)
setInputValue('')
}}
disabled={loading}
accessoryLeft={keyButton}
status={isPrivate ? 'warning' : 'default'}

View File

@ -2,7 +2,6 @@ import React, { useContext, useEffect, useState } from 'react'
import { Button, Divider, Layout, Text, useTheme } from '@ui-kitten/components'
import { getNotes, Note } from '../../Functions/DatabaseFunctions/Notes'
import { StyleSheet, TouchableOpacity } from 'react-native'
import Markdown from 'react-native-markdown-display'
import { EventKind } from '../../lib/nostr/Events'
import Icon from 'react-native-vector-icons/FontAwesome5'
import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
@ -13,9 +12,10 @@ import { getDirectReplies, getReplyEventId } from '../../Functions/RelayFunction
import moment from 'moment'
import { populateRelay } from '../../Functions/RelayFunctions'
import Avatar from '../Avatar'
import { markdownIt, markdownStyle } from '../../Constants/AppConstants'
import { searchRelays } from '../../Functions/DatabaseFunctions/Relays'
import { RelayFilters } from '../../lib/nostr/RelayPool/intex'
import TextBox from '../TextBox'
import { formatPubKey } from '../../Functions/RelayFunctions/Users'
interface NoteCardProps {
note: Note
@ -75,7 +75,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
<TouchableOpacity onPress={onPressUser}>
<Layout style={styles.pubkey}>
<Text appearance='hint'>
{note.name ?? `${note.pubkey.slice(0, 6)}...${note.pubkey.slice(-6)}`}
{note.name ?? formatPubKey(note.pubkey)}
</Text>
</Layout>
</TouchableOpacity>
@ -86,9 +86,9 @@ export const NoteCard: React.FC<NoteCardProps> = ({
</Layout>
</Layout>
<Layout style={styles.text}>
<Markdown style={markdownStyle(theme)} markdownit={markdownIt}>
{note.content}
</Markdown>
<TextBox note={note}>
<Text>{note.content}</Text>
</TextBox>
</Layout>
<Layout style={styles.footer}>
<Text appearance='hint'>{moment.unix(note.created_at).format('HH:mm DD-MM-YY')}</Text>
@ -153,6 +153,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
flexDirection: 'row',
backgroundColor: 'transparent',
paddingTop: 16,
paddingLeft: 50
},
divider: {
paddingTop: 16,

View File

@ -16,7 +16,7 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import { getUser, User, updateUserContact } from '../../Functions/DatabaseFunctions/Users'
import { EventKind } from '../../lib/nostr/Events'
import Icon from 'react-native-vector-icons/FontAwesome5'
import { populatePets } from '../../Functions/RelayFunctions/Users'
import { formatPubKey, populatePets } from '../../Functions/RelayFunctions/Users'
import { getReplyEventId } from '../../Functions/RelayFunctions/Events'
import Loading from '../Loading'
import { handleInfinityScroll } from '../../Functions/NativeFunctions'
@ -35,7 +35,7 @@ export const ProfilePage: React.FC = () => {
const [refreshing, setRefreshing] = useState(false)
const breadcrump = page.split('%')
const userId = breadcrump[breadcrump.length - 1].split('#')[1] ?? publicKey
const username = user?.name === '' ? user?.id : user?.name
const username = user?.name === '' ? formatPubKey(user.id) : user?.name
useEffect(() => {
setRefreshing(true)

View File

@ -1,6 +1,6 @@
import { Button, Input, Layout, Spinner, TopNavigation, useTheme } from '@ui-kitten/components'
import React, { useContext, useEffect, useState } from 'react'
import { StyleSheet } from 'react-native'
import { Button, Input, Layout, List, ListItem, Spinner, TopNavigation, useTheme } from '@ui-kitten/components'
import React, { useContext, useEffect, useRef, useState } from 'react'
import { ScrollView, StyleSheet } from 'react-native'
import { AppContext } from '../../Contexts/AppContext'
import Icon from 'react-native-vector-icons/FontAwesome5'
import { Event, EventKind } from '../../lib/nostr/Events'
@ -9,14 +9,20 @@ import { RelayPoolContext } from '../../Contexts/RelayPoolContext'
import moment from 'moment'
import { getNotes } from '../../Functions/DatabaseFunctions/Notes'
import { getETags } from '../../Functions/RelayFunctions/Events'
import { getUsers, User } from '../../Functions/DatabaseFunctions/Users'
import { formatPubKey } from '../../Functions/RelayFunctions/Users'
import Avatar from '../Avatar'
export const SendPage: React.FC = () => {
const theme = useTheme()
const { goBack, page, database } = useContext(AppContext)
const { relayPool, publicKey } = useContext(RelayPoolContext)
const { t } = useTranslation('common')
const scrollViewRef = useRef<Input>()
const [content, setContent] = useState<string>('')
const [sending, setSending] = useState<boolean>(false)
const [userSuggestions, setUserSuggestions] = useState<User[]>([])
const [userMentions, setUserMentions] = useState<User[]>([])
const breadcrump = page.split('%')
const eventId = breadcrump[breadcrump.length - 1].split('#')[1]
@ -42,12 +48,30 @@ export const SendPage: React.FC = () => {
goBack()
}
const onChangeText: (text: string) => void = (text) => {
const match = text.match(/@(\S*)$/)
if (database && match && match[1].length > 0) {
getUsers(database, { name: match[1] }).then((results) => {
setUserSuggestions(results)
})
} else {
setUserSuggestions([])
}
setContent(text)
}
const mentionText: (user: User) => string = (user) => {
return `@${user.name ?? formatPubKey(user.id)}`
}
const onPressSend: () => void = () => {
if (database && publicKey) {
getNotes(database, { filters: { id: eventId } }).then((notes) => {
let tags: string[][] = []
const note = notes[0]
let rawContent = content
if (note) {
tags = note.tags
if (getETags(note).length === 0) {
@ -56,28 +80,63 @@ export const SendPage: React.FC = () => {
tags.push(['e', eventId, '', 'reply'])
}
}
if (userMentions.length > 0) {
userMentions.forEach((user) => {
const userText = mentionText(user)
if (rawContent.includes(userText)) {
rawContent = rawContent.replace(userText, `#[${tags.length}]`)
tags.push(['p', user.id])
}
})
}
const event: Event = {
content,
content: rawContent,
created_at: moment().unix(),
kind: EventKind.textNote,
pubkey: publicKey,
tags,
}
relayPool?.sendEvent(event).then((sentNote) => {
if (sentNote?.id) {
relayPool?.subscribe('main-channel', {
kinds: [EventKind.textNote],
ids: [sentNote.id],
})
goBack()
}
})
relayPool?.sendEvent(event)
setSending(true)
})
}
}
const addUserMention: (user: User) => void = (user) => {
setUserMentions((prev) => {
prev.push(user)
return prev
})
setContent((prev) => {
const splitText = prev.split("@")
splitText.pop()
return `${splitText.join("@")}${mentionText(user)}`
})
setUserSuggestions([])
scrollViewRef.current?.focus()
}
const suggestionsList: () => JSX.Element = () => {
const renderItem: (item: { item: User }) => JSX.Element = ({item}) => {
return <ListItem
title={`${item.name ?? item.id}`}
accessoryLeft={<Avatar name={item.name} src={item.picture} pubKey={item.id} size={25}/>}
onPress={() => addUserMention(item)}
/>
};
return userSuggestions.length > 0 ?
(
<List
data={userSuggestions}
renderItem={renderItem}
/>
) : (
<></>
)
};
const renderBackAction = (): JSX.Element => (
<Button
accessoryRight={<Icon name='arrow-left' size={16} color={theme['text-basic-color']} />}
@ -97,11 +156,12 @@ export const SendPage: React.FC = () => {
<Layout style={styles.actionContainer} level='2'>
<Layout>
<Input
ref={scrollViewRef}
multiline={true}
textStyle={{ minHeight: 64 }}
placeholder={t('sendPage.placeholder')}
value={content}
onChangeText={setContent}
onChangeText={onChangeText}
size='large'
autoFocus={true}
keyboardType='twitter'
@ -116,6 +176,7 @@ export const SendPage: React.FC = () => {
{t('sendPage.send')}
</Button>
</Layout>
{suggestionsList()}
</Layout>
</Layout>
</>

View File

@ -0,0 +1,94 @@
import React, { useContext, useState } from 'react'
import ParsedText from 'react-native-parsed-text';
import { useTheme } from '@ui-kitten/components'
import { Event } from '../../lib/nostr/Events'
import { Linking, StyleSheet } from 'react-native';
import { AppContext } from '../../Contexts/AppContext';
import { getUser } from '../../Functions/DatabaseFunctions/Users';
import { formatPubKey } from '../../Functions/RelayFunctions/Users';
interface TextBoxProps {
note: Event
}
export const TextBox: React.FC<TextBoxProps> = ({
note
}) => {
const theme = useTheme()
const { database, goToPage } = useContext(AppContext)
const [userNames, setUserNames] = useState<{[index: number]: string}>({})
const handleUrlPress: (url: string) => void = (url) => {
Linking.openURL(url);
}
const handleEmailPress: (email: string) => void = (email) => {
Linking.openURL(email);
}
const handleMentionPress: (text: string) => void = (text) => {
const mentionIndex: number = parseInt(text.substring(2, text.length - 1))
goToPage(`profile#${note.tags[mentionIndex][1]}`)
}
const renderMentionText: (matchingString: string, matches: string[]) => string = (_matchingString, matches) => {
const mentionIndex: number = parseInt(matches[1])
const pudKey = note.tags[mentionIndex][1]
if (userNames[mentionIndex]) {
return userNames[mentionIndex]
} else {
if (database) {
getUser(pudKey, database).then((user) => {
setUserNames((prev) => {
if (user?.name) {
prev[mentionIndex] = `@${user.name}`
}
return prev
})
})
}
return `@${formatPubKey(pudKey)}`
}
}
const styles = StyleSheet.create({
url: {
textDecorationLine: 'underline',
},
email: {
textDecorationLine: 'underline',
},
text: {
color: theme['text-basic-color'],
},
mention: {
fontWeight: 'bold',
textDecorationLine: 'underline',
},
hashTag: {
fontStyle: 'italic',
},
})
return (
note && (
<ParsedText
style={styles.text}
parse={
[
{type: 'url', style: styles.url, onPress: handleUrlPress},
{type: 'email', style: styles.email, onPress: handleEmailPress},
{pattern: /#\[(\d+)\]/, style: styles.mention, onPress: handleMentionPress, renderText: renderMentionText},
{pattern: /#(\w+)/, style: styles.hashTag},
]
}
childrenProps={{allowFontScaling: false}}
>
{note.content}
</ParsedText>
)
)
}
export default TextBox

View File

@ -1,48 +0,0 @@
import { StyleSheet } from 'react-native'
import { MarkdownIt } from 'react-native-markdown-display'
export const markdownStyle: (theme: Record<string, string>) => StyleSheet.NamedStyles<any> = (
theme,
) => {
return {
text: {
color: theme['text-basic-color'],
},
tr: {
borderColor: theme['border-primary-color-5'],
},
table: {
borderColor: theme['border-primary-color-5'],
},
blocklink: {
borderColor: theme['border-primary-color-5'],
},
hr: {
backgroundColor: theme['background-basic-color-3'],
},
blockquote: {
backgroundColor: theme['background-basic-color-3'],
borderColor: theme['border-primary-color-5'],
color: theme['text-basic-color'],
},
code_inline: {
borderColor: theme['border-primary-color-5'],
backgroundColor: theme['background-basic-color-3'],
color: theme['text-basic-color'],
},
code_block: {
borderColor: theme['border-primary-color-5'],
backgroundColor: theme['background-basic-color-3'],
color: theme['text-basic-color'],
},
fence: {
borderColor: theme['border-primary-color-5'],
backgroundColor: theme['background-basic-color-3'],
color: theme['text-basic-color'],
},
}
}
export const markdownIt = new MarkdownIt({
linkify: true,
})

View File

@ -4,7 +4,6 @@ import { initDatabase } from '../Functions/DatabaseFunctions'
import FlashMessage from 'react-native-flash-message'
import SInfo from 'react-native-sensitive-info'
import { BackHandler } from 'react-native'
import { markdownIt } from '../Constants/AppConstants'
export interface AppContextProps {
page: string
@ -36,11 +35,6 @@ export const AppContextProvider = ({ children }: AppContextProviderProps): JSX.E
const [loadingDb, setLoadingDb] = useState<boolean>(initialAppContext.loadingDb)
const init: () => void = () => {
markdownIt.linkify
.tlds('onion', true)
.add('git:', 'http:')
.add('ftp:', null)
.set({ fuzzyIP: true })
const db = initDatabase()
setDatabase(db)
SInfo.getItem('privateKey', {}).then(() => {

View File

@ -54,8 +54,8 @@ export const addUser: (pubKey: string, db: QuickSQLiteConnection) => Promise<Que
export const getUsers: (
db: QuickSQLiteConnection,
options: { exludeIds?: string[]; contacts?: boolean; followers?: boolean; includeIds?: string[] },
) => Promise<User[]> = async (db, { exludeIds, contacts, followers, includeIds }) => {
options: { name?: string, exludeIds?: string[]; contacts?: boolean; followers?: boolean; includeIds?: string[] },
) => Promise<User[]> = async (db, { name, exludeIds, contacts, followers, includeIds }) => {
let userQuery = 'SELECT * FROM nostros_users '
const filters = []
@ -63,6 +63,10 @@ export const getUsers: (
if (contacts) {
filters.push('contact = 1')
}
if (name) {
filters.push(`name LIKE '%${name}%'`)
}
if (includeIds && includeIds.length > 0) {
filters.push(`id IN ('${includeIds.join("', '")}')`)

View File

@ -23,7 +23,7 @@ export const username: (user: User) => string = (user) => {
}
export const formatPubKey: (pubKey: string) => string = (pubKey) => {
return `${pubKey.slice(0, 8)}...${pubKey.slice(-8)}`
return `${pubKey.slice(0, 4)}...${pubKey.slice(-4)}`
}
export const populatePets: (

View File

@ -25,7 +25,6 @@
"events": "^3.3.0",
"i18next": "^22.0.6",
"lodash.debounce": "^4.0.8",
"markdown-it": "^13.0.1",
"moment": "^2.29.4",
"nostr-tools": "^0.24.1",
"react": "18.1.0",
@ -34,8 +33,8 @@
"react-native-action-button": "^2.8.5",
"react-native-bidirectional-infinite-scroll": "^0.3.3",
"react-native-flash-message": "^0.3.1",
"react-native-markdown-display": "^7.0.0-alpha.2",
"react-native-multithreading": "^1.1.1",
"react-native-parsed-text": "^0.0.22",
"react-native-quick-sqlite": "^6.1.1",
"react-native-reanimated": "^2.13.0",
"react-native-securerandom": "^1.0.1",
@ -55,6 +54,7 @@
"@react-native-community/eslint-config": "^3.2.0",
"@types/create-hash": "^1.2.2",
"@types/jest": "^29.2.2",
"@types/linkify-it": "^3.0.2",
"@types/lodash.debounce": "^4.0.7",
"@types/react-native": "^0.70.6",
"@types/react-native-sqlite-storage": "^5.0.2",

104
yarn.lock
View File

@ -1623,6 +1623,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
"@types/linkify-it@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9"
integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==
"@types/lodash.debounce@^4.0.7":
version "4.0.7"
resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz#0285879defb7cdb156ae633cecd62d5680eded9f"
@ -2637,11 +2642,6 @@ camelcase@^6.0.0, camelcase@^6.2.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
camelize@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3"
integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==
caniuse-lite@^1.0.30001400:
version "1.0.30001427"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz#d3a749f74be7ae0671fbec3a4eea18576e8ad646"
@ -2978,11 +2978,6 @@ cryptr@^6.0.3:
resolved "https://registry.yarnpkg.com/cryptr/-/cryptr-6.0.3.tgz#669364e7993a1cd19d77e32e90ffef38455ecd74"
integrity sha512-Nhaxn3CYl/OoWF3JSZlF8B6FQO600RRkU3g8213OGEIq4YvMlc3od8hL9chubhY1SmTq8ienvCRq1MSFjMTpOg==
css-color-keywords@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==
css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
@ -2994,15 +2989,6 @@ css-select@^5.1.0:
domutils "^3.0.1"
nth-check "^2.0.1"
css-to-react-native@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
dependencies:
camelize "^1.0.0"
css-color-keywords "^1.0.0"
postcss-value-parser "^4.0.2"
css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
@ -3296,16 +3282,6 @@ entities@^4.2.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
entities@~2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
entities@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
envinfo@^7.7.2:
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@ -5536,13 +5512,6 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
linkify-it@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
dependencies:
uc.micro "^1.0.1"
linkify-it@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec"
@ -5662,28 +5631,6 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
markdown-it@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
dependencies:
argparse "^1.0.7"
entities "~2.0.0"
linkify-it "^2.0.0"
mdurl "^1.0.1"
uc.micro "^1.0.5"
markdown-it@^13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430"
integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==
dependencies:
argparse "^2.0.1"
entities "~3.0.1"
linkify-it "^4.0.1"
mdurl "^1.0.1"
uc.micro "^1.0.5"
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@ -6693,11 +6640,6 @@ posix-character-classes@^0.1.0:
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==
postcss-value-parser@^4.0.2:
version "4.2.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@ -6768,7 +6710,7 @@ prompts@^2.0.1, prompts@^2.4.0:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@^15.5.10, prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.5.10, prop-types@^15.7.2, prop-types@^15.7.x, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -6885,13 +6827,6 @@ react-native-eva-icons@^1.3.1:
resolved "https://registry.yarnpkg.com/react-native-eva-icons/-/react-native-eva-icons-1.3.1.tgz#1e6e019b0fd3cb1669db50bd6bbdaa6d89327593"
integrity sha512-emd/aYXuOacuDVTx0SJoLi+xsOdCNdljQB3PTNCM9AQ3m/smG0X1TN0+ihelPO7MqoHzaH0h6lbANtwxGUy8Fw==
react-native-fit-image@^1.5.5:
version "1.5.5"
resolved "https://registry.yarnpkg.com/react-native-fit-image/-/react-native-fit-image-1.5.5.tgz#c660d1ad74b9dcaa1cba27a0d9c23837e000226c"
integrity sha512-Wl3Vq2DQzxgsWKuW4USfck9zS7YzhvLNPpkwUUCF90bL32e1a0zOVQ3WsJILJOwzmPdHfzZmWasiiAUNBkhNkg==
dependencies:
prop-types "^15.5.10"
react-native-flash-message@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/react-native-flash-message/-/react-native-flash-message-0.3.1.tgz#e88073dffa826385c92aebf9244438940fbcffec"
@ -6905,26 +6840,31 @@ react-native-gradle-plugin@^0.70.3:
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz#cbcf0619cbfbddaa9128701aa2d7b4145f9c4fc8"
integrity sha512-oOanj84fJEXUg9FoEAQomA8ISG+DVIrTZ3qF7m69VQUJyOGYyDZmPqKcjvRku4KXlEH6hWO9i4ACLzNBh8gC0A==
react-native-hyperlink@^0.0.22:
version "0.0.22"
resolved "https://registry.yarnpkg.com/react-native-hyperlink/-/react-native-hyperlink-0.0.22.tgz#9f553390b5f96ae473d942639c40bce6579abc89"
integrity sha512-IVhG+aP2bAnllUEr08/+rGA3cbpzyl83PtOfe94higfWUR8E7rUGThj21tdhx8SWAyl+4XO1K864tA6ybVbMFA==
dependencies:
linkify-it "^4.0.1"
mdurl "^1.0.1"
react-native-iphone-x-helper@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010"
integrity sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==
react-native-markdown-display@^7.0.0-alpha.2:
version "7.0.0-alpha.2"
resolved "https://registry.yarnpkg.com/react-native-markdown-display/-/react-native-markdown-display-7.0.0-alpha.2.tgz#a48a70d3cb5c510a52ecf7f1509a4a3d14d728aa"
integrity sha512-Od1a4wJEcVGwO1bh02sHivsEkKKpu99+ew/OtmVTPRmfT8V3B0aTut7k7ICV0Vej9F4ZjylRHvm28/maYUBeGw==
dependencies:
css-to-react-native "^3.0.0"
markdown-it "^10.0.0"
prop-types "^15.7.2"
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-parsed-text@^0.0.22:
version "0.0.22"
resolved "https://registry.yarnpkg.com/react-native-parsed-text/-/react-native-parsed-text-0.0.22.tgz#a23c756eaa5d6724296814755085127f9072e5f5"
integrity sha512-hfD83RDXZf9Fvth3DowR7j65fMnlqM9PpxZBGWkzVcUTFtqe6/yPcIoIAgrJbKn6YmtzkivmhWE2MCE4JKBXrQ==
dependencies:
prop-types "^15.7.x"
react-native-quick-sqlite@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/react-native-quick-sqlite/-/react-native-quick-sqlite-6.1.1.tgz#ba35d0a4a919a5a0962306c3fee4dc46983b0839"
@ -7997,7 +7937,7 @@ typescript@^4.9.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db"
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
uc.micro@^1.0.1, uc.micro@^1.0.5:
uc.micro@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==