From a40f0d9f82ef67b2d02b8154f937d0936f9a225c Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 26 Dec 2022 01:06:33 +0100 Subject: [PATCH] Fix #620 #606 --- ...ative-htmlview-npm-0.16.0-501f1b89ba.patch | 22 - fastlane/metadata/en-US/release_notes.txt | 3 +- fastlane/metadata/zh-Hans/release_notes.txt | 3 +- package.json | 3 +- src/@types/untyped.d.ts | 2 - src/components/Parse/HTML.tsx | 429 ++++++++---------- src/components/Timeline/Shared/Content.tsx | 6 +- src/helpers/removeHTML.ts | 2 +- src/helpers/urlMatcher.ts | 2 +- yarn.lock | 106 +---- 10 files changed, 215 insertions(+), 363 deletions(-) delete mode 100644 .yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch diff --git a/.yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch b/.yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch deleted file mode 100644 index f42c82e7..00000000 --- a/.yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/HTMLView.js b/HTMLView.js -index 43f8b7eb552d9a44b5feef74ec2ae7d7ddbc2fca..334d144f1fb96067726bca199ff37267c2fa0fb2 100644 ---- a/HTMLView.js -+++ b/HTMLView.js -@@ -1,7 +1,7 @@ - import React, {PureComponent} from 'react'; - import PropTypes from 'prop-types'; - import htmlToElement from './htmlToElement'; --import {Linking, Platform, StyleSheet, View, ViewPropTypes} from 'react-native'; -+import {Linking, Platform, StyleSheet, View} from 'react-native'; - - const boldStyle = {fontWeight: 'bold'}; - const italicStyle = {fontStyle: 'italic'}; -@@ -146,7 +146,7 @@ HtmlView.propTypes = { - renderNode: PropTypes.func, - RootComponent: PropTypes.func, - rootComponentProps: PropTypes.object, -- style: ViewPropTypes.style, -+ style: PropTypes.object, - stylesheet: PropTypes.object, - TextComponent: PropTypes.func, - textComponentProps: PropTypes.object, diff --git a/fastlane/metadata/en-US/release_notes.txt b/fastlane/metadata/en-US/release_notes.txt index 731c525f..62516967 100644 --- a/fastlane/metadata/en-US/release_notes.txt +++ b/fastlane/metadata/en-US/release_notes.txt @@ -1,4 +1,5 @@ Enjoy toooting! This version includes following improvements and fixes: - Allowing adding more context of reports - Option to disable autoplay gif -- Hide boosts from users \ No newline at end of file +- Hide boosts from users +- Followed hashtags are underlined \ No newline at end of file diff --git a/fastlane/metadata/zh-Hans/release_notes.txt b/fastlane/metadata/zh-Hans/release_notes.txt index af941da8..8225007b 100644 --- a/fastlane/metadata/zh-Hans/release_notes.txt +++ b/fastlane/metadata/zh-Hans/release_notes.txt @@ -1,4 +1,5 @@ toooting愉快!此版本包括以下改进和修复: - 可添加举报细节 - 新增暂停自动播放gif动画选项 -- 隐藏用户的转嘟 \ No newline at end of file +- 隐藏用户的转嘟 +- 下划线高亮正在关注的话题标签 \ No newline at end of file diff --git a/package.json b/package.json index aba133e8..ab857b27 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "expo-store-review": "^6.0.0", "expo-video-thumbnails": "^7.0.0", "expo-web-browser": "~12.0.0", + "htmlparser2": "^8.0.1", "i18next": "^22.4.6", "linkify-it": "^4.0.1", "lodash": "^4.17.21", @@ -75,7 +76,6 @@ "react-native-feather": "^1.1.2", "react-native-flash-message": "^0.3.1", "react-native-gesture-handler": "~2.8.0", - "react-native-htmlview": "^0.16.0", "react-native-image-picker": "^4.10.3", "react-native-ios-context-menu": "^1.15.1", "react-native-language-detection": "^0.2.2", @@ -120,7 +120,6 @@ "resolutions": { "react-native-fast-image@^8.6.3": "patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch", "expo-av@^13.0.2": "patch:expo-av@npm%3A13.0.2#./.yarn/patches/expo-av-npm-13.0.2-7a651776f1.patch", - "react-native-htmlview@^0.16.0": "patch:react-native-htmlview@npm%3A0.16.0#./.yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch", "react-native-share-menu@^6.0.0": "patch:react-native-share-menu@npm%3A6.0.0#./.yarn/patches/react-native-share-menu-npm-6.0.0-f1094c3204.patch", "@types/react-native-share-menu@^5.0.2": "patch:@types/react-native-share-menu@npm%3A5.0.2#./.yarn/patches/@types-react-native-share-menu-npm-5.0.2-373df17ecc.patch" } diff --git a/src/@types/untyped.d.ts b/src/@types/untyped.d.ts index ad27df89..e00bdb1d 100644 --- a/src/@types/untyped.d.ts +++ b/src/@types/untyped.d.ts @@ -1,7 +1,5 @@ declare module 'gl-react-blurhash' -declare module 'htmlparser2-without-node-native' declare module 'react-native-feather' -declare module 'react-native-htmlview' declare module 'react-native-toast-message' declare module 'rtl-detect' diff --git a/src/components/Parse/HTML.tsx b/src/components/Parse/HTML.tsx index 1bb73532..2c5f29a9 100644 --- a/src/components/Parse/HTML.tsx +++ b/src/components/Parse/HTML.tsx @@ -1,147 +1,23 @@ import Icon from '@components/Icon' import openLink from '@components/openLink' import ParseEmojis from '@components/Parse/Emojis' -import CustomText from '@components/Text' -import { getHost } from '@helpers/urlMatcher' import { useNavigation, useRoute } from '@react-navigation/native' import { StackNavigationProp } from '@react-navigation/stack' import { TabLocalStackParamList } from '@utils/navigation/navigators' +import { useFollowedTagsQuery } from '@utils/queryHooks/tags' import { getSettingsFontsize } from '@utils/slices/settingsSlice' import { StyleConstants } from '@utils/styles/constants' import layoutAnimation from '@utils/styles/layoutAnimation' import { adaptiveScale } from '@utils/styles/scaling' import { useTheme } from '@utils/styles/ThemeManager' +import { ChildNode } from 'domhandler' +import { ElementType, parseDocument } from 'htmlparser2' import { isEqual } from 'lodash' -import React, { useCallback, useState } from 'react' +import React, { useState } from 'react' import { useTranslation } from 'react-i18next' -import { Pressable, TextStyleIOS, View } from 'react-native' -import HTMLView from 'react-native-htmlview' +import { Pressable, Text, TextStyleIOS, View } from 'react-native' import { useSelector } from 'react-redux' -// Prevent going to the same hashtag multiple times -const renderNode = ({ - routeParams, - colors, - node, - index, - adaptedFontsize, - adaptedLineheight, - navigation, - mentions, - tags, - showFullLink, - disableDetails -}: { - routeParams?: any - colors: any - node: any - index: number - adaptedFontsize: number - adaptedLineheight: number - navigation: StackNavigationProp - mentions?: Mastodon.Mention[] - tags?: Mastodon.Tag[] - showFullLink: boolean - disableDetails: boolean -}) => { - switch (node.name) { - case 'a': - const classes = node.attribs.class - const href = node.attribs.href - if (classes) { - if (classes.includes('hashtag')) { - const tag = href?.split(new RegExp(/\/tag\/(.*)|\/tags\/(.*)/)) - const differentTag = routeParams?.hashtag - ? routeParams.hashtag !== tag[1] && routeParams.hashtag !== tag[2] - : true - return ( - { - !disableDetails && - differentTag && - navigation.push('Tab-Shared-Hashtag', { - hashtag: tag[1] || tag[2] - }) - }} - > - {node.children[0].data} - {node.children[1]?.children[0].data} - - ) - } else if (classes.includes('mention') && mentions) { - const accountIndex = mentions.findIndex(mention => mention.url === href) - const differentAccount = routeParams?.account - ? routeParams.account.id !== mentions[accountIndex]?.id - : true - return ( - { - accountIndex !== -1 && - !disableDetails && - differentAccount && - navigation.push('Tab-Shared-Account', { - account: mentions[accountIndex] - }) - }} - > - {node.children[0].data} - {node.children[1]?.children[0].data} - - ) - } - } else { - const host = getHost(href) - // Need example here - const content = node.children && node.children[0] && node.children[0].data - const shouldBeTag = tags && tags.filter(tag => `#${tag.name}` === content).length > 0 - return ( - { - if (!disableDetails) { - if (shouldBeTag) { - navigation.push('Tab-Shared-Hashtag', { - hashtag: content.substring(1) - }) - } else { - await openLink(href, navigation) - } - } - }} - > - {content && content !== href ? content : showFullLink ? href : host} - {!shouldBeTag ? '/...' : null} - - ) - } - break - case 'p': - if (!node.children.length) { - return // bug when the tag is empty - } - break - } -} - export interface Props { content: string size?: 'S' | 'M' | 'L' @@ -187,8 +63,8 @@ const ParseHTML = React.memo( ) const navigation = useNavigation>() - const route = useRoute() - const { colors, theme } = useTheme() + const { params } = useRoute() + const { colors } = useTheme() const { t } = useTranslation('componentParse') if (!expandHint) { expandHint = t('HTML.defaultHint') @@ -198,116 +74,195 @@ const ParseHTML = React.memo( numberOfLines = 4 } - const renderNodeCallback = useCallback( - (node: any, index: any) => - renderNode({ - routeParams: route.params, - colors, - node, - index, - adaptedFontsize, - adaptedLineheight, - navigation, - mentions, - tags, - showFullLink, - disableDetails - }), - [] - ) - const textComponent = useCallback(({ children }: any) => { - if (children) { - return ( - - ) - } else { - return null + const followedTags = useFollowedTagsQuery() + + const [totalLines, setTotalLines] = useState() + const [expanded, setExpanded] = useState(highlighted) + + const document = parseDocument(content) + const unwrapNode = (node: ChildNode): string => { + switch (node.type) { + case ElementType.Text: + return node.data + case ElementType.Tag: + if (node.name === 'span') { + if (node.attribs.class?.includes('invisible')) return '' + if (node.attribs.class?.includes('ellipsis')) + return node.children.map(child => unwrapNode(child)).join('') + '...' + } + return node.children.map(child => unwrapNode(child)).join('') + default: + return '' } - }, []) - const rootComponent = useCallback( - ({ children }: any) => { - const { t } = useTranslation('componentParse') - - const [totalLines, setTotalLines] = useState() - const [expanded, setExpanded] = useState(highlighted) - - return ( - - {(!disableDetails && typeof totalLines === 'number') || numberOfLines === 1 ? ( - { - layoutAnimation() - setExpanded(!expanded) - if (setSpoilerExpanded) { - setSpoilerExpanded(!expanded) - } - }} - style={{ - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center', - minHeight: 44, - backgroundColor: colors.backgroundDefault - }} - > - 1 && typeof totalLines === 'number' - ? t('HTML.moreLines', { count: totalLines - numberOfLines }) - : '' - })} - /> - - - ) : null} - { - if (numberOfLines === 1 || nativeEvent.lines.length >= numberOfLines + 5) { - setTotalLines(nativeEvent.lines.length) - } - }} - style={{ - ...textStyles, - height: numberOfLines === 1 && !expanded ? 0 : undefined - }} - numberOfLines={ - typeof totalLines === 'number' ? (expanded ? 999 : numberOfLines) : undefined - } - selectable={selectable} + } + const renderNode = (node: ChildNode, index: number) => { + switch (node.type) { + case ElementType.Text: + return ( + - - ) - }, - [theme] - ) + ) + case ElementType.Tag: + switch (node.name) { + case 'a': + const classes = node.attribs.class + const href = node.attribs.href + if (classes) { + if (classes.includes('hashtag')) { + const tag = href.match(new RegExp(/\/tags?\/(.*)/, 'i'))?.[1] + const paramsHashtag = (params as { hashtag: Mastodon.Tag['name'] } | undefined) + ?.hashtag + const sameHashtag = paramsHashtag === tag + const isFollowing = followedTags.data?.pages[0]?.body.find(t => t.name === tag) + return ( + + tag?.length && + !disableDetails && + !sameHashtag && + navigation.push('Tab-Shared-Hashtag', { hashtag: tag }) + } + children={node.children.map(unwrapNode).join('')} + /> + ) + } + if (classes.includes('mention') && mentions?.length) { + const mentionIndex = mentions.findIndex(mention => mention.url === href) + const paramsAccount = (params as { account: Mastodon.Account } | undefined) + ?.account + const sameAccount = paramsAccount?.id === mentions[mentionIndex]?.id + return ( + -1 ? colors.blue : undefined }} + onPress={() => + mentionIndex > -1 && + !disableDetails && + !sameAccount && + navigation.push('Tab-Shared-Account', { account: mentions[mentionIndex] }) + } + children={node.children.map(unwrapNode).join('')} + /> + ) + } + } + const content = node.children.map(child => unwrapNode(child)).join('') + const shouldBeTag = tags && tags.find(tag => `#${tag.name}` === content) + return ( + { + if (!disableDetails) { + if (shouldBeTag) { + navigation.push('Tab-Shared-Hashtag', { + hashtag: content.substring(1) + }) + } else { + await openLink(href, navigation) + } + } + }} + children={content !== href ? content : showFullLink ? href : content} + /> + ) + break + case 'p': + if (index < document.children.length - 1) { + return ( + + {node.children.map((c, i) => renderNode(c, i))} + {'\n\n'} + + ) + } else { + return renderNode(c, i))} /> + } + default: + return renderNode(c, i))} /> + } + } + return null + } return ( - + + {(!disableDetails && typeof totalLines === 'number') || numberOfLines === 1 ? ( + { + layoutAnimation() + setExpanded(!expanded) + if (setSpoilerExpanded) { + setSpoilerExpanded(!expanded) + } + }} + style={{ + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + minHeight: 44, + backgroundColor: colors.backgroundDefault + }} + > + 1 && typeof totalLines === 'number' + ? t('HTML.moreLines', { count: totalLines - numberOfLines }) + : '' + })} + /> + + + ) : null} + { + if (numberOfLines === 1 || nativeEvent.lines.length >= numberOfLines + 5) { + setTotalLines(nativeEvent.lines.length) + } + }} + style={{ + fontSize: adaptedFontsize, + lineHeight: adaptedLineheight, + ...textStyles, + height: numberOfLines === 1 && !expanded ? 0 : undefined + }} + numberOfLines={ + typeof totalLines === 'number' ? (expanded ? 999 : numberOfLines) : undefined + } + selectable={selectable} + /> + ) }, (prev, next) => prev.content === next.content && isEqual(prev.emojis, next.emojis) diff --git a/src/components/Timeline/Shared/Content.tsx b/src/components/Timeline/Shared/Content.tsx index b250d56a..ef09c945 100644 --- a/src/components/Timeline/Shared/Content.tsx +++ b/src/components/Timeline/Shared/Content.tsx @@ -5,7 +5,7 @@ import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { useContext } from 'react' import { useTranslation } from 'react-i18next' -import { Platform } from 'react-native' +import { Platform, View } from 'react-native' import { useSelector } from 'react-redux' import { isRtlLang } from 'rtl-detect' import StatusContext from './Context' @@ -24,7 +24,7 @@ const TimelineContent: React.FC = ({ notificationOwnToot = false, setSpoi const instanceAccount = useSelector(getInstanceAccount, () => true) return ( - <> + {status.spoiler_text?.length ? ( <> = ({ notificationOwnToot = false, setSpoi } /> )} - + ) } diff --git a/src/helpers/removeHTML.ts b/src/helpers/removeHTML.ts index e8a3d4c1..7f1b9832 100644 --- a/src/helpers/removeHTML.ts +++ b/src/helpers/removeHTML.ts @@ -1,4 +1,4 @@ -import htmlparser2 from 'htmlparser2-without-node-native' +import * as htmlparser2 from 'htmlparser2' const removeHTML = (text: string): string => { let raw: string = '' diff --git a/src/helpers/urlMatcher.ts b/src/helpers/urlMatcher.ts index c08f036e..8c2286d9 100644 --- a/src/helpers/urlMatcher.ts +++ b/src/helpers/urlMatcher.ts @@ -1,7 +1,7 @@ import { store } from '@root/store' import { getInstanceUrl } from '@utils/slices/instancesSlice' -const getHost = (url: unknown): string | void => { +const getHost = (url: unknown): string | undefined | null => { if (typeof url !== 'string') return undefined const matches = url.match(/^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/i) diff --git a/yarn.lock b/yarn.lock index f555d518..284740c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5210,16 +5210,6 @@ __metadata: languageName: node linkType: hard -"dom-serializer@npm:0": - version: 0.2.2 - resolution: "dom-serializer@npm:0.2.2" - dependencies: - domelementtype: ^2.0.1 - entities: ^2.0.0 - checksum: 376344893e4feccab649a14ca1a46473e9961f40fe62479ea692d4fee4d9df1c00ca8654811a79c1ca7b020096987e1ca4fb4d7f8bae32c1db800a680a0e5d5e - languageName: node - linkType: hard - "dom-serializer@npm:^2.0.0": version: 2.0.0 resolution: "dom-serializer@npm:2.0.0" @@ -5231,29 +5221,13 @@ __metadata: languageName: node linkType: hard -"domelementtype@npm:1, domelementtype@npm:^1.3.0": - version: 1.3.1 - resolution: "domelementtype@npm:1.3.1" - checksum: 7893da40218ae2106ec6ffc146b17f203487a52f5228b032ea7aa470e41dfe03e1bd762d0ee0139e792195efda765434b04b43cddcf63207b098f6ae44b36ad6 - languageName: node - linkType: hard - -"domelementtype@npm:^2.0.1, domelementtype@npm:^2.3.0": +"domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" checksum: ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 languageName: node linkType: hard -"domhandler@npm:^2.3.0": - version: 2.4.2 - resolution: "domhandler@npm:2.4.2" - dependencies: - domelementtype: 1 - checksum: 49bd70c9c784f845cd047e1dfb3611bd10891c05719acfc93f01fc726a419ed09fbe0b69f9064392d556a63fffc5a02010856cedae9368f4817146d95a97011f - languageName: node - linkType: hard - "domhandler@npm:^5.0.1, domhandler@npm:^5.0.2": version: 5.0.3 resolution: "domhandler@npm:5.0.3" @@ -5263,16 +5237,6 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^1.5.1": - version: 1.7.0 - resolution: "domutils@npm:1.7.0" - dependencies: - dom-serializer: 0 - domelementtype: 1 - checksum: f60a725b1f73c1ae82f4894b691601ecc6ecb68320d87923ac3633137627c7865725af813ae5d188ad3954283853bcf46779eb50304ec5d5354044569fcefd2b - languageName: node - linkType: hard - "domutils@npm:^3.0.1": version: 3.0.1 resolution: "domutils@npm:3.0.1" @@ -5337,21 +5301,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^1.1.1": - version: 1.1.2 - resolution: "entities@npm:1.1.2" - checksum: d537b02799bdd4784ffd714d000597ed168727bddf4885da887c5a491d735739029a00794f1998abbf35f3f6aeda32ef5c15010dca1817d401903a501b6d3e05 - languageName: node - linkType: hard - -"entities@npm:^2.0.0": - version: 2.2.0 - resolution: "entities@npm:2.2.0" - checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 - languageName: node - linkType: hard - -"entities@npm:^4.2.0": +"entities@npm:^4.2.0, entities@npm:^4.3.0": version: 4.4.0 resolution: "entities@npm:4.4.0" checksum: 84d250329f4b56b40fa93ed067b194db21e8815e4eb9b59f43a086f0ecd342814f6bc483de8a77da5d64e0f626033192b1b4f1792232a7ea6b970ebe0f3187c2 @@ -5489,13 +5439,6 @@ __metadata: languageName: node linkType: hard -"eventemitter2@npm:^1.0.0": - version: 1.0.5 - resolution: "eventemitter2@npm:1.0.5" - checksum: f501d8ad439aad85b4d5494d96a83abbb156ed4acf5897fed53a99f4fa427c5a968959276461d8640b613ed16a34995fcd63a13404262e725131a29df9177c96 - languageName: node - linkType: hard - "exec-async@npm:^2.2.0": version: 2.2.0 resolution: "exec-async@npm:2.2.0" @@ -6609,18 +6552,15 @@ __metadata: languageName: node linkType: hard -"htmlparser2-without-node-native@npm:^3.9.2": - version: 3.9.2 - resolution: "htmlparser2-without-node-native@npm:3.9.2" +"htmlparser2@npm:^8.0.1": + version: 8.0.1 + resolution: "htmlparser2@npm:8.0.1" dependencies: - domelementtype: ^1.3.0 - domhandler: ^2.3.0 - domutils: ^1.5.1 - entities: ^1.1.1 - eventemitter2: ^1.0.0 - inherits: ^2.0.1 - readable-stream: ^2.0.2 - checksum: 95754dc0f9ab057b5c072eaf2daed6db7595ec7a51290fde0cde6df803cbe528927764da4acb7bc9e633ff6396b07046eff7edb6f1f619fe665df4eaa8c735ad + domelementtype: ^2.3.0 + domhandler: ^5.0.2 + domutils: ^3.0.1 + entities: ^4.3.0 + checksum: 06d5c71e8313597722bc429ae2a7a8333d77bd3ab07ccb916628384b37332027b047f8619448d8f4a3312b6609c6ea3302a4e77435d859e9e686999e6699ca39 languageName: node linkType: hard @@ -6792,7 +6732,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -9633,26 +9573,6 @@ __metadata: languageName: node linkType: hard -"react-native-htmlview@npm:0.16.0": - version: 0.16.0 - resolution: "react-native-htmlview@npm:0.16.0" - dependencies: - entities: ^1.1.1 - htmlparser2-without-node-native: ^3.9.2 - checksum: fb46bc162e41ba9c1222f9386215496f9ac7d4f7f3353b2732101abc57f89d570e9e0881c581bec04d77c2aeaac916b4bd157eedc2098ea2e94b7a29c5c739b1 - languageName: node - linkType: hard - -"react-native-htmlview@patch:react-native-htmlview@npm%3A0.16.0#./.yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch::locator=tooot%40workspace%3A.": - version: 0.16.0 - resolution: "react-native-htmlview@patch:react-native-htmlview@npm%3A0.16.0#./.yarn/patches/react-native-htmlview-npm-0.16.0-501f1b89ba.patch::version=0.16.0&hash=aa9ca8&locator=tooot%40workspace%3A." - dependencies: - entities: ^1.1.1 - htmlparser2-without-node-native: ^3.9.2 - checksum: 87e79231315bedf821bc30d342d5bc70ae6fe73b34d535051aba3a5142a40675a9687b37333968194aa9e28a5bdc476f6e12ea921f207ac4b80396615696e81c - languageName: node - linkType: hard - "react-native-image-picker@npm:^4.10.3": version: 4.10.3 resolution: "react-native-image-picker@npm:4.10.3" @@ -9974,7 +9894,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.6, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.6, readable-stream@npm:~2.3.6": version: 2.3.7 resolution: "readable-stream@npm:2.3.7" dependencies: @@ -11397,6 +11317,7 @@ __metadata: expo-store-review: ^6.0.0 expo-video-thumbnails: ^7.0.0 expo-web-browser: ~12.0.0 + htmlparser2: ^8.0.1 i18next: ^22.4.6 linkify-it: ^4.0.1 lodash: ^4.17.21 @@ -11413,7 +11334,6 @@ __metadata: react-native-feather: ^1.1.2 react-native-flash-message: ^0.3.1 react-native-gesture-handler: ~2.8.0 - react-native-htmlview: ^0.16.0 react-native-image-picker: ^4.10.3 react-native-ios-context-menu: ^1.15.1 react-native-language-detection: ^0.2.2