diff --git a/package.json b/package.json
index cbbae056..6435d64d 100644
--- a/package.json
+++ b/package.json
@@ -89,7 +89,7 @@
"react-native-tab-view": "^3.3.4",
"react-redux": "^8.0.5",
"rn-placeholder": "^3.0.3",
- "valid-url": "^1.0.9",
+ "url-parse": "^1.5.10",
"zeego": "^1.0.2"
},
"devDependencies": {
@@ -104,7 +104,7 @@
"@types/react-dom": "^18.0.10",
"@types/react-native": "^0.70.8",
"@types/react-native-share-menu": "^5.0.2",
- "@types/valid-url": "^1.0.3",
+ "@types/url-parse": "^1",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"chalk": "^4.1.2",
diff --git a/src/App.tsx b/src/App.tsx
index 1e872150..cf102047 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,8 +3,9 @@ import * as Sentry from '@sentry/react-native'
import { QueryClientProvider } from '@tanstack/react-query'
import AccessibilityManager from '@utils/accessibility/AccessibilityManager'
import getLanguage from '@utils/helpers/getLanguage'
-import queryClient from '@utils/queryHooks'
+import { queryClient } from '@utils/queryHooks'
import audio from '@utils/startup/audio'
+import { dev } from '@utils/startup/dev'
import log from '@utils/startup/log'
import netInfo from '@utils/startup/netInfo'
import push from '@utils/startup/push'
@@ -34,6 +35,7 @@ Platform.select({
android: LogBox.ignoreLogs(['Setting a timer for a long period of time'])
})
+dev()
sentry()
audio()
push()
diff --git a/src/components/Emojis/List.tsx b/src/components/Emojis/List.tsx
index 6a443585..5cf7df55 100644
--- a/src/components/Emojis/List.tsx
+++ b/src/components/Emojis/List.tsx
@@ -19,7 +19,6 @@ import {
View
} from 'react-native'
import FastImage from 'react-native-fast-image'
-import validUrl from 'valid-url'
import EmojisContext from './Context'
const EmojisList = () => {
@@ -68,83 +67,77 @@ const EmojisList = () => {
>
{item.map(emoji => {
const uri = reduceMotionEnabled ? emoji.static_url : emoji.url
- if (validUrl.isHttpsUri(uri)) {
- return (
- {
- addEmoji(`:${emoji.shortcode}:`)
+ return (
+ {
+ addEmoji(`:${emoji.shortcode}:`)
- const HALF_LIFE = 60 * 60 * 24 * 7 // 1 week
- const calculateScore = (
- emoji: StorageAccount['emojis_frequent'][number]
- ): number => {
- var seconds = (new Date().getTime() - emoji.lastUsed) / 1000
- var score = emoji.count + 1
- var order = Math.log(Math.max(score, 1)) / Math.LN10
- var sign = score > 0 ? 1 : score === 0 ? 0 : -1
- return (sign * order + seconds / HALF_LIFE) * 10
+ const HALF_LIFE = 60 * 60 * 24 * 7 // 1 week
+ const calculateScore = (
+ emoji: StorageAccount['emojis_frequent'][number]
+ ): number => {
+ var seconds = (new Date().getTime() - emoji.lastUsed) / 1000
+ var score = emoji.count + 1
+ var order = Math.log(Math.max(score, 1)) / Math.LN10
+ var sign = score > 0 ? 1 : score === 0 ? 0 : -1
+ return (sign * order + seconds / HALF_LIFE) * 10
+ }
+
+ const currentEmojis = getAccountStorage.object('emojis_frequent')
+ const foundEmojiIndex = currentEmojis?.findIndex(
+ e => e.emoji.shortcode === emoji.shortcode && e.emoji.url === emoji.url
+ )
+
+ let newEmojisSort: StorageAccount['emojis_frequent']
+ if (foundEmojiIndex === -1) {
+ newEmojisSort = currentEmojis || []
+ const temp = {
+ emoji,
+ score: 0,
+ count: 0,
+ lastUsed: new Date().getTime()
}
+ newEmojisSort.push({
+ ...temp,
+ score: calculateScore(temp),
+ count: temp.count + 1
+ })
+ } else {
+ newEmojisSort =
+ currentEmojis
+ ?.map((e, i) =>
+ i === foundEmojiIndex
+ ? {
+ ...e,
+ score: calculateScore(e),
+ count: e.count + 1,
+ lastUsed: new Date().getTime()
+ }
+ : e
+ )
+ .sort((a, b) => b.score - a.score) || []
+ }
- const currentEmojis = getAccountStorage.object('emojis_frequent')
- const foundEmojiIndex = currentEmojis?.findIndex(
- e => e.emoji.shortcode === emoji.shortcode && e.emoji.url === emoji.url
- )
-
- let newEmojisSort: StorageAccount['emojis_frequent']
- if (foundEmojiIndex === -1) {
- newEmojisSort = currentEmojis || []
- const temp = {
- emoji,
- score: 0,
- count: 0,
- lastUsed: new Date().getTime()
- }
- newEmojisSort.push({
- ...temp,
- score: calculateScore(temp),
- count: temp.count + 1
- })
- } else {
- newEmojisSort =
- currentEmojis
- ?.map((e, i) =>
- i === foundEmojiIndex
- ? {
- ...e,
- score: calculateScore(e),
- count: e.count + 1,
- lastUsed: new Date().getTime()
- }
- : e
- )
- .sort((a, b) => b.score - a.score) || []
+ setAccountStorage([
+ {
+ key: 'emojis_frequent',
+ value: newEmojisSort.sort((a, b) => b.score - a.score).slice(0, 20)
}
-
- setAccountStorage([
- {
- key: 'emojis_frequent',
- value: newEmojisSort.sort((a, b) => b.score - a.score).slice(0, 20)
- }
- ])
- }}
- style={{ padding: StyleConstants.Spacing.S }}
- >
-
-
- )
- } else {
- return null
- }
+ ])
+ }}
+ style={{ padding: StyleConstants.Spacing.S }}
+ >
+
+
+ )
})}
)
diff --git a/src/components/Instance/index.tsx b/src/components/Instance/index.tsx
index eb104b14..4940bf23 100644
--- a/src/components/Instance/index.tsx
+++ b/src/components/Instance/index.tsx
@@ -5,7 +5,7 @@ import apiGeneral from '@utils/api/general'
import browserPackage from '@utils/helpers/browserPackage'
import { featureCheck } from '@utils/helpers/featureCheck'
import { TabMeStackNavigationProp } from '@utils/navigation/navigators'
-import queryClient from '@utils/queryHooks'
+import { queryClient } from '@utils/queryHooks'
import { redirectUri, useAppsMutation } from '@utils/queryHooks/apps'
import { useInstanceQuery } from '@utils/queryHooks/instance'
import { storage } from '@utils/storage'
@@ -19,7 +19,6 @@ import {
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as AuthSession from 'expo-auth-session'
-import * as Random from 'expo-random'
import * as WebBrowser from 'expo-web-browser'
import { debounce } from 'lodash'
import React, { RefObject, useCallback, useState } from 'react'
@@ -27,7 +26,7 @@ import { Trans, useTranslation } from 'react-i18next'
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
import { ScrollView } from 'react-native-gesture-handler'
import { MMKV } from 'react-native-mmkv'
-import validUrl from 'valid-url'
+import parse from 'url-parse'
import CustomText from '../Text'
export interface Props {
@@ -50,7 +49,7 @@ const ComponentInstance: React.FC = ({
const whitelisted: boolean =
!!domain.length &&
!!errorCode &&
- !!validUrl.isHttpsUri(`https://${domain}`) &&
+ !!(parse(`https://${domain}/`).hostname === domain) &&
errorCode === 401
const instanceQuery = useInstanceQuery({
diff --git a/src/components/Parse/Emojis.tsx b/src/components/Parse/Emojis.tsx
index c1cb9aa7..0c23a5f7 100644
--- a/src/components/Parse/Emojis.tsx
+++ b/src/components/Parse/Emojis.tsx
@@ -7,7 +7,6 @@ import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react'
import { Platform, TextStyle } from 'react-native'
import FastImage from 'react-native-fast-image'
-import validUrl from 'valid-url'
const regexEmoji = new RegExp(/(:[A-Za-z0-9_]+:)/)
@@ -72,23 +71,19 @@ const ParseEmojis: React.FC = ({
const uri = reduceMotionEnabled
? emojis[emojiIndex].static_url
: emojis[emojiIndex].url
- if (validUrl.isHttpsUri(uri)) {
- return (
-
- {i === 0 ? ' ' : undefined}
-
-
- )
- } else {
- return null
- }
+ return (
+
+ {i === 0 ? ' ' : undefined}
+
+
+ )
}
} else {
return {str}
diff --git a/src/components/Timeline/Shared/Card.tsx b/src/components/Timeline/Shared/Card.tsx
index d9bf2600..12a065f3 100644
--- a/src/components/Timeline/Shared/Card.tsx
+++ b/src/components/Timeline/Shared/Card.tsx
@@ -3,9 +3,10 @@ import GracefullyImage from '@components/GracefullyImage'
import openLink from '@components/openLink'
import CustomText from '@components/Text'
import { useNavigation } from '@react-navigation/native'
-import { matchAccount, matchStatus } from '@utils/helpers/urlMatcher'
+import { StackNavigationProp } from '@react-navigation/stack'
+import { urlMatcher } from '@utils/helpers/urlMatcher'
+import { TabLocalStackParamList } from '@utils/navigation/navigators'
import { useAccountQuery } from '@utils/queryHooks/account'
-import { useSearchQuery } from '@utils/queryHooks/search'
import { useStatusQuery } from '@utils/queryHooks/status'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
@@ -20,97 +21,44 @@ const TimelineCard: React.FC = () => {
if (!status || !status.card) return null
const { colors } = useTheme()
- const navigation = useNavigation()
+ const navigation = useNavigation>()
const [loading, setLoading] = useState(false)
- const isStatus = matchStatus(status.card.url)
+ const match = urlMatcher(status.card.url)
const [foundStatus, setFoundStatus] = useState()
- const isAccount = matchAccount(status.card.url)
const [foundAccount, setFoundAccount] = useState()
- const searchQuery = useSearchQuery({
- type: (() => {
- if (isStatus) return 'statuses'
- if (isAccount) return 'accounts'
- })(),
- term: (() => {
- if (isStatus) {
- if (isStatus.sameInstance) {
- return
- } else {
- return status.card.url
- }
- }
- if (isAccount) {
- if (isAccount.sameInstance) {
- if (isAccount.style === 'default') {
- return
- } else {
- return isAccount.username
- }
- } else {
- return status.card.url
- }
- }
- })(),
- limit: 1,
- options: { enabled: false }
- })
-
const statusQuery = useStatusQuery({
- id: isStatus?.id || '',
+ status: match?.status ? { ...match.status, uri: status.card.url } : undefined,
options: { enabled: false }
})
useEffect(() => {
- if (isStatus) {
+ if (match?.status) {
setLoading(true)
- if (isStatus.sameInstance) {
- statusQuery
- .refetch()
- .then(res => {
- res.data && setFoundStatus(res.data)
- setLoading(false)
- })
- .catch(() => setLoading(false))
- } else {
- searchQuery
- .refetch()
- .then(res => {
- const status = (res.data as any)?.statuses?.[0]
- status && setFoundStatus(status)
- setLoading(false)
- })
- .catch(() => setLoading(false))
- }
+ statusQuery
+ .refetch()
+ .then(res => {
+ res.data && setFoundStatus(res.data)
+ setLoading(false)
+ })
+ .catch(() => setLoading(false))
}
}, [])
const accountQuery = useAccountQuery({
- account:
- isAccount?.style === 'default' ? { id: isAccount.id, url: status.card.url } : undefined,
+ account: match?.account ? { ...match?.account, url: status.card.url } : undefined,
options: { enabled: false }
})
useEffect(() => {
- if (isAccount) {
+ if (match?.account) {
setLoading(true)
- if (isAccount.sameInstance && isAccount.style === 'default') {
- accountQuery
- .refetch()
- .then(res => {
- res.data && setFoundAccount(res.data)
- setLoading(false)
- })
- .catch(() => setLoading(false))
- } else {
- searchQuery
- .refetch()
- .then(res => {
- const account = (res.data as any)?.accounts?.[0]
- account && setFoundAccount(account)
- setLoading(false)
- })
- .catch(() => setLoading(false))
- }
+ accountQuery
+ .refetch()
+ .then(res => {
+ res.data && setFoundAccount(res.data)
+ setLoading(false)
+ })
+ .catch(() => setLoading(false))
}
}, [])
@@ -129,10 +77,10 @@ const TimelineCard: React.FC = () => {
)
}
- if (isStatus && foundStatus) {
+ if (match?.status && foundStatus) {
return
}
- if (isAccount && foundAccount) {
+ if (match?.account && foundAccount) {
return
}
return (
@@ -198,7 +146,18 @@ const TimelineCard: React.FC = () => {
overflow: 'hidden',
borderColor: colors.border
}}
- onPress={async () => status.card && (await openLink(status.card.url, navigation))}
+ onPress={async () => {
+ if (match?.status && foundStatus) {
+ navigation.push('Tab-Shared-Toot', { toot: foundStatus })
+ return
+ }
+ if (match?.account && foundAccount) {
+ navigation.push('Tab-Shared-Account', { account: foundAccount })
+ return
+ }
+
+ status.card?.url && (await openLink(status.card.url, navigation))
+ }}
children={cardContent()}
/>
)
diff --git a/src/components/Timeline/Shared/Feedback.tsx b/src/components/Timeline/Shared/Feedback.tsx
index ec5bd793..79a17911 100644
--- a/src/components/Timeline/Shared/Feedback.tsx
+++ b/src/components/Timeline/Shared/Feedback.tsx
@@ -19,7 +19,7 @@ const TimelineFeedback = () => {
const navigation = useNavigation>()
const { data } = useStatusHistory({
- id: status.id,
+ status,
options: { enabled: status.edited_at !== undefined }
})
@@ -82,7 +82,7 @@ const TimelineFeedback = () => {
style={[styles.text, { marginRight: 0, color: colors.blue }]}
onPress={() =>
navigation.push('Tab-Shared-History', {
- id: status.id,
+ status,
detectedLanguage: detectedLanguage?.current || status.language || ''
})
}
diff --git a/src/components/Timeline/Shared/Filtered.tsx b/src/components/Timeline/Shared/Filtered.tsx
index 520fc18d..9a8c11de 100644
--- a/src/components/Timeline/Shared/Filtered.tsx
+++ b/src/components/Timeline/Shared/Filtered.tsx
@@ -1,6 +1,6 @@
import CustomText from '@components/Text'
-import queryClient from '@utils/queryHooks'
import removeHTML from '@utils/helpers/removeHTML'
+import { queryClient } from '@utils/queryHooks'
import { QueryKeyFilters } from '@utils/queryHooks/filters'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import { StyleConstants } from '@utils/styles/constants'
diff --git a/src/components/Timeline/Shared/HeaderConversation.tsx b/src/components/Timeline/Shared/HeaderConversation.tsx
index db9c481e..69252478 100644
--- a/src/components/Timeline/Shared/HeaderConversation.tsx
+++ b/src/components/Timeline/Shared/HeaderConversation.tsx
@@ -73,13 +73,8 @@ const HeaderConversation = ({ conversation }: Props) => {
marginBottom: StyleConstants.Spacing.S
}}
>
- {conversation.last_status?.created_at ? (
-
- ) : null}
-
+ {conversation.last_status?.created_at ? : null}
+
diff --git a/src/components/Timeline/Shared/HeaderDefault.tsx b/src/components/Timeline/Shared/HeaderDefault.tsx
index e5795207..48bf2e03 100644
--- a/src/components/Timeline/Shared/HeaderDefault.tsx
+++ b/src/components/Timeline/Shared/HeaderDefault.tsx
@@ -17,7 +17,7 @@ import HeaderSharedReplies from './HeaderShared/Replies'
import HeaderSharedVisibility from './HeaderShared/Visibility'
const TimelineHeaderDefault: React.FC = () => {
- const { queryKey, rootQueryKey, status, highlighted, disableDetails, rawContent, isRemote } =
+ const { queryKey, rootQueryKey, status, disableDetails, rawContent, isRemote } =
useContext(StatusContext)
if (!status) return null
@@ -66,15 +66,11 @@ const TimelineHeaderDefault: React.FC = () => {
style={{ marginRight: StyleConstants.Spacing.S }}
/>
) : null}
-
-
-
+
+
+
-
+
diff --git a/src/components/Timeline/Shared/HeaderNotification.tsx b/src/components/Timeline/Shared/HeaderNotification.tsx
index 531cd543..2c63182e 100644
--- a/src/components/Timeline/Shared/HeaderNotification.tsx
+++ b/src/components/Timeline/Shared/HeaderNotification.tsx
@@ -146,15 +146,10 @@ const TimelineHeaderNotification: React.FC = ({ notification }) => {
marginBottom: StyleConstants.Spacing.S
}}
>
-
- {notification.status?.visibility ? (
-
- ) : null}
-
-
+
+ {notification.status?.visibility ? : null}
+
+
diff --git a/src/components/Timeline/Shared/HeaderShared/Application.tsx b/src/components/Timeline/Shared/HeaderShared/Application.tsx
index 9f5f3344..2e021b2f 100644
--- a/src/components/Timeline/Shared/HeaderShared/Application.tsx
+++ b/src/components/Timeline/Shared/HeaderShared/Application.tsx
@@ -2,32 +2,31 @@ import openLink from '@components/openLink'
import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
-import React from 'react'
+import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
+import StatusContext from '../Context'
-export interface Props {
- application?: Mastodon.Application
-}
-
-const HeaderSharedApplication: React.FC = ({ application }) => {
+const HeaderSharedApplication: React.FC = () => {
+ const { status } = useContext(StatusContext)
const { colors } = useTheme()
const { t } = useTranslation('componentTimeline')
- return application && application.name !== 'Web' ? (
+ return status?.application?.name && status.application.name !== 'Web' ? (
{
- application.website && (await openLink(application.website))
+ status.application?.website && (await openLink(status.application.website))
}}
style={{
+ flex: 1,
marginLeft: StyleConstants.Spacing.S,
color: colors.secondary
}}
numberOfLines={1}
>
{t('shared.header.shared.application', {
- application: application.name
+ application: status.application.name
})}
) : null
diff --git a/src/components/Timeline/Shared/HeaderShared/Created.tsx b/src/components/Timeline/Shared/HeaderShared/Created.tsx
index bcc39aa4..091715f3 100644
--- a/src/components/Timeline/Shared/HeaderShared/Created.tsx
+++ b/src/components/Timeline/Shared/HeaderShared/Created.tsx
@@ -3,21 +3,23 @@ import RelativeTime from '@components/RelativeTime'
import CustomText from '@components/Text'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
-import React from 'react'
+import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { FormattedDate } from 'react-intl'
+import StatusContext from '../Context'
export interface Props {
- created_at: Mastodon.Status['created_at'] | number
- edited_at?: Mastodon.Status['edited_at']
- highlighted?: boolean
+ created_at?: Mastodon.Status['created_at'] | number
}
-const HeaderSharedCreated: React.FC = ({ created_at, edited_at, highlighted = false }) => {
+const HeaderSharedCreated: React.FC = ({ created_at }) => {
+ const { status, highlighted } = useContext(StatusContext)
const { t } = useTranslation('componentTimeline')
const { colors } = useTheme()
- const actualTime = edited_at || created_at
+ if (!status) return null
+
+ const actualTime = created_at || status.edited_at || status.created_at
return (
<>
@@ -30,7 +32,7 @@ const HeaderSharedCreated: React.FC = ({ created_at, edited_at, highlight
)}
- {edited_at ? (
+ {status.edited_at && !highlighted ? (
= ({ muted }) => {
+const HeaderSharedMuted: React.FC = () => {
+ const { status } = useContext(StatusContext)
const { t } = useTranslation('componentTimeline')
const { colors } = useTheme()
- return muted ? (
+ return status?.muted ? (
= ({ visibility }) => {
+const HeaderSharedVisibility: React.FC = () => {
+ const { status } = useContext(StatusContext)
const { t } = useTranslation('componentTimeline')
const { colors } = useTheme()
- switch (visibility) {
+ switch (status?.visibility) {
case 'unlisted':
return (
{
return
}
- const handleNavigation = (page: 'Tab-Shared-Toot' | 'Tab-Shared-Account', options: {}) => {
+ const handleNavigation = (page: 'Tab-Shared-Toot' | 'Tab-Shared-Account', options: any) => {
if (navigation) {
navigation.push(page, options)
} else {
@@ -24,83 +25,79 @@ const openLink = async (url: string, navigation?: any) => {
}
}
+ const match = urlMatcher(url)
// If a tooot can be found
- const isStatus = matchStatus(url)
- if (isStatus) {
- if (isStatus.sameInstance) {
- handleNavigation('Tab-Shared-Toot', { toot: { id: isStatus.id } })
- return
- }
-
+ if (match?.status?.id) {
loadingLink = true
- let response
- try {
- response = await apiInstance({
- version: 'v2',
- method: 'get',
- url: 'search',
- params: { type: 'statuses', q: url, limit: 1, resolve: true }
- })
- } catch {}
- if (response && response.body && response.body.statuses.length) {
- handleNavigation('Tab-Shared-Toot', {
- toot: response.body.statuses[0]
- })
+ let response: Mastodon.Status | undefined = undefined
+
+ const queryKey: QueryKeyStatus = [
+ 'Status',
+ { id: match.status.id, uri: url, _remote: match.status._remote }
+ ]
+ const cache = queryClient.getQueryData(queryKey)
+
+ if (cache) {
+ handleNavigation('Tab-Shared-Toot', { toot: cache })
loadingLink = false
return
+ } else {
+ try {
+ response = await searchLocalStatus(url)
+ } catch {}
+ if (response) {
+ handleNavigation('Tab-Shared-Toot', { toot: response })
+ loadingLink = false
+ return
+ }
}
}
// If an account can be found
- const isAccount = matchAccount(url)
- if (isAccount) {
- if (isAccount.sameInstance) {
- if (isAccount.style === 'default' && isAccount.id) {
- handleNavigation('Tab-Shared-Account', { account: isAccount })
- return
- }
+ if (match?.account) {
+ if (!match.account._remote && match.account.id) {
+ handleNavigation('Tab-Shared-Account', { account: match.account.id })
+ return
}
loadingLink = true
- let response
- try {
- response = await apiInstance({
- version: 'v2',
- method: 'get',
- url: 'search',
- params: {
- type: 'accounts',
- q: isAccount.sameInstance && isAccount.style === 'pretty' ? isAccount.username : url,
- limit: 1,
- resolve: true
- }
- })
- } catch {}
- if (response && response.body && response.body.accounts.length) {
- handleNavigation('Tab-Shared-Account', {
- account: response.body.accounts[0]
- })
+ let response: Mastodon.Account | undefined = undefined
+
+ const queryKey: QueryKeyAccount = [
+ 'Account',
+ { id: match.account.id, url: url, _remote: match.account._remote }
+ ]
+ const cache = queryClient.getQueryData(queryKey)
+
+ if (cache) {
+ handleNavigation('Tab-Shared-Account', { account: cache })
loadingLink = false
return
+ } else {
+ try {
+ response = await searchLocalAccount(url)
+ } catch {}
+ if (response) {
+ handleNavigation('Tab-Shared-Account', { account: response })
+ loadingLink = false
+ return
+ }
}
}
loadingLink = false
- const validatedUrl = validUrl.isWebUri(url)
- if (validatedUrl) {
- switch (getGlobalStorage.string('app.browser')) {
- // Some links might end with an empty space at the end that triggers an error
- case 'internal':
- await WebBrowser.openBrowserAsync(validatedUrl, {
- dismissButtonStyle: 'close',
- enableBarCollapsing: true,
- ...(await browserPackage())
- })
- break
- case 'external':
- await Linking.openURL(validatedUrl)
- break
- }
+ switch (getGlobalStorage.string('app.browser')) {
+ // Some links might end with an empty space at the end that triggers an error
+ case 'internal':
+ await WebBrowser.openBrowserAsync(url.trim(), {
+ dismissButtonStyle: 'close',
+ enableBarCollapsing: true,
+ ...(await browserPackage())
+ })
+ break
+ case 'external':
+ await Linking.openURL(url.trim())
+ break
}
}
diff --git a/src/screens/Compose/index.tsx b/src/screens/Compose/index.tsx
index f832afbf..b6c74688 100644
--- a/src/screens/Compose/index.tsx
+++ b/src/screens/Compose/index.tsx
@@ -10,7 +10,7 @@ import { handleError } from '@utils/api/helpers'
import { RootStackScreenProps } from '@utils/navigation/navigators'
import { useInstanceQuery } from '@utils/queryHooks/instance'
import { usePreferencesQuery } from '@utils/queryHooks/preferences'
-import { searchFetchToot, SearchResult } from '@utils/queryHooks/search'
+import { searchLocalStatus } from '@utils/queryHooks/search'
import { useTimelineMutation } from '@utils/queryHooks/timeline'
import {
getAccountStorage,
@@ -156,7 +156,7 @@ const ScreenCompose: React.FC> = ({
content: params.accts.map(acct => `@${acct}`).join(' ') + ' ',
disableDebounce: true
})
- searchFetchToot(params.incomingStatus.uri).then(status => {
+ searchLocalStatus(params.incomingStatus.uri).then(status => {
if (status?.uri === params.incomingStatus.uri) {
composeDispatch({ type: 'updateReply', payload: status })
}
diff --git a/src/screens/Compose/utils/processText.tsx b/src/screens/Compose/utils/processText.tsx
index 561f1534..01b457fe 100644
--- a/src/screens/Compose/utils/processText.tsx
+++ b/src/screens/Compose/utils/processText.tsx
@@ -1,6 +1,6 @@
import { emojis } from '@components/Emojis'
import CustomText from '@components/Text'
-import queryClient from '@utils/queryHooks'
+import { queryClient } from '@utils/queryHooks'
import { QueryKeyInstance } from '@utils/queryHooks/instance'
import { useTheme } from '@utils/styles/ThemeManager'
import LinkifyIt from 'linkify-it'
diff --git a/src/screens/Tabs/Me/Profile/Root.tsx b/src/screens/Tabs/Me/Profile/Root.tsx
index a2f6a319..27d4331f 100644
--- a/src/screens/Tabs/Me/Profile/Root.tsx
+++ b/src/screens/Tabs/Me/Profile/Root.tsx
@@ -1,8 +1,8 @@
import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles'
-import queryClient from '@utils/queryHooks'
import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators'
+import { queryClient } from '@utils/queryHooks'
import { QueryKeyPreferences } from '@utils/queryHooks/preferences'
import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile'
import { useTheme } from '@utils/styles/ThemeManager'
diff --git a/src/screens/Tabs/Me/Settings/Dev.tsx b/src/screens/Tabs/Me/Settings/Dev.tsx
index c015f00c..2e91b354 100644
--- a/src/screens/Tabs/Me/Settings/Dev.tsx
+++ b/src/screens/Tabs/Me/Settings/Dev.tsx
@@ -4,11 +4,13 @@ import { displayMessage } from '@components/Message'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { useNavigation } from '@react-navigation/native'
import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles'
+import { urlMatcher } from '@utils/helpers/urlMatcher'
import { storage } from '@utils/storage'
import { getGlobalStorage, useGlobalStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react'
+import { Alert } from 'react-native'
import { MMKV } from 'react-native-mmkv'
const SettingsDev: React.FC = () => {
@@ -37,6 +39,17 @@ const SettingsDev: React.FC = () => {
)
}
/>
+