From 95a99ef7cd513d4b5bf914d8bf1f7a587b2dbc6c Mon Sep 17 00:00:00 2001 From: xmflsct Date: Sun, 29 Jan 2023 15:32:40 +0100 Subject: [PATCH 01/19] Try out connect --- src/App.tsx | 33 ++-- src/components/Emojis/List.tsx | 3 +- src/components/GracefullyImage.tsx | 7 +- src/components/Parse/Emojis.tsx | 3 +- src/screens/Announcements.tsx | 5 +- src/screens/Compose/DraftsList.tsx | 9 +- .../Compose/Root/Footer/Attachments.tsx | 7 +- src/screens/Tabs/Me/Settings/App.tsx | 30 +++- src/utils/api/general.ts | 9 +- src/utils/api/helpers/connect.ts | 144 ++++++++++++++++++ src/utils/api/instance.ts | 14 +- src/utils/storage/global/v0.ts | 1 + 12 files changed, 233 insertions(+), 32 deletions(-) create mode 100644 src/utils/api/helpers/connect.ts diff --git a/src/App.tsx b/src/App.tsx index c1d671e2..a5cb9969 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import { ActionSheetProvider } from '@expo/react-native-action-sheet' import * as Sentry from '@sentry/react-native' import { QueryClientProvider } from '@tanstack/react-query' import AccessibilityManager from '@utils/accessibility/AccessibilityManager' +import { connectVerify } from '@utils/api/helpers/connect' import getLanguage from '@utils/helpers/getLanguage' import { queryClient } from '@utils/queryHooks' import audio from '@utils/startup/audio' @@ -50,20 +51,28 @@ const App: React.FC = () => { await migrateFromAsyncStorage() setHasMigrated(true) } catch {} + } + + const useConnect = getGlobalStorage.boolean('app.connect') + log('log', 'App', `connect: ${useConnect}`) + if (useConnect) { + await connectVerify() + .then(() => log('log', 'App', 'connected')) + .catch(() => log('warn', 'App', 'connect verify failed')) + } + + log('log', 'App', 'loading from MMKV') + const account = getGlobalStorage.string('account.active') + if (account) { + await setAccount(account) } else { - log('log', 'App', 'loading from MMKV') - const account = getGlobalStorage.string('account.active') - if (account) { - await setAccount(account) + log('log', 'App', 'No active account available') + const accounts = getGlobalStorage.object('accounts') + if (accounts?.length) { + log('log', 'App', `Setting active account ${accounts[accounts.length - 1]}`) + await setAccount(accounts[accounts.length - 1]) } else { - log('log', 'App', 'No active account available') - const accounts = getGlobalStorage.object('accounts') - if (accounts?.length) { - log('log', 'App', `Setting active account ${accounts[accounts.length - 1]}`) - await setAccount(accounts[accounts.length - 1]) - } else { - setGlobalStorage('account.active', undefined) - } + setGlobalStorage('account.active', undefined) } } diff --git a/src/components/Emojis/List.tsx b/src/components/Emojis/List.tsx index e8d2f953..6d72be23 100644 --- a/src/components/Emojis/List.tsx +++ b/src/components/Emojis/List.tsx @@ -2,6 +2,7 @@ import { emojis } from '@components/Emojis' import Icon from '@components/Icon' import CustomText from '@components/Text' import { useAccessibility } from '@utils/accessibility/AccessibilityManager' +import { connectImage } from '@utils/api/helpers/connect' import { StorageAccount } from '@utils/storage/account' import { getAccountStorage, setAccountStorage } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' @@ -133,7 +134,7 @@ const EmojisList = () => { emoji: emoji.shortcode })} accessibilityHint={t('screenCompose:content.root.footer.emojis.accessibilityHint')} - source={{ uri }} + source={connectImage({ uri })} style={{ width: 32, height: 32 }} /> diff --git a/src/components/GracefullyImage.tsx b/src/components/GracefullyImage.tsx index 3ad17fbf..9a708980 100644 --- a/src/components/GracefullyImage.tsx +++ b/src/components/GracefullyImage.tsx @@ -1,4 +1,5 @@ import { useAccessibility } from '@utils/accessibility/AccessibilityManager' +import { connectImage } from '@utils/api/helpers/connect' import { useTheme } from '@utils/styles/ThemeManager' import React, { useEffect, useState } from 'react' import { @@ -56,7 +57,7 @@ const GracefullyImage = ({ const [imageLoaded, setImageLoaded] = useState(false) const [currentUri, setCurrentUri] = useState(uri.original || uri.remote) - const source = { + const source: { uri?: string } = { uri: reduceMotionEnabled && uri.static ? uri.static : currentUri } useEffect(() => { @@ -90,12 +91,12 @@ const GracefullyImage = ({ > {uri.preview && !imageLoaded ? ( ) : null} { setImageLoaded(true) diff --git a/src/components/Parse/Emojis.tsx b/src/components/Parse/Emojis.tsx index 0c23a5f7..91a5ad40 100644 --- a/src/components/Parse/Emojis.tsx +++ b/src/components/Parse/Emojis.tsx @@ -1,5 +1,6 @@ import CustomText from '@components/Text' import { useAccessibility } from '@utils/accessibility/AccessibilityManager' +import { connectImage } from '@utils/api/helpers/connect' import { useGlobalStorage } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' import { adaptiveScale } from '@utils/styles/scaling' @@ -75,7 +76,7 @@ const ParseEmojis: React.FC = ({ {i === 0 ? ' ' : undefined} > {reaction.url ? ( ))} diff --git a/src/screens/Compose/Root/Footer/Attachments.tsx b/src/screens/Compose/Root/Footer/Attachments.tsx index 0853d5e3..3aae6988 100644 --- a/src/screens/Compose/Root/Footer/Attachments.tsx +++ b/src/screens/Compose/Root/Footer/Attachments.tsx @@ -6,6 +6,7 @@ import { MAX_MEDIA_ATTACHMENTS } from '@components/mediaSelector' import CustomText from '@components/Text' import { useActionSheet } from '@expo/react-native-action-sheet' import { useNavigation } from '@react-navigation/native' +import { connectImage } from '@utils/api/helpers/connect' import { featureCheck } from '@utils/helpers/featureCheck' import { StyleConstants } from '@utils/styles/constants' import layoutAnimation from '@utils/styles/layoutAnimation' @@ -105,7 +106,11 @@ const ComposeAttachments: React.FC = ({ accessibleRefAttachments }) => { > {item.remote?.meta?.original?.duration ? ( { const navigation = useNavigation() @@ -24,6 +25,22 @@ const SettingsApp: React.FC = () => { const [browser, setBrowser] = useGlobalStorage.string('app.browser') const [autoplayGifv, setAutoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv') + const [connect, setConnect] = useGlobalStorage.boolean('app.connect') + const [showConnect, setShowConnect] = useState(connect) + useEffect(() => { + connectVerify() + .then(() => { + setShowConnect(true) + }) + .catch(() => { + if (connect) { + setConnect(false) + } else { + setShowConnect(false) + } + }) + }, []) + return ( { switchValue={autoplayGifv} switchOnValueChange={() => setAutoplayGifv(!autoplayGifv)} /> + {showConnect ? ( + setConnect(!connect)} + /> + ) : null} ) } diff --git a/src/utils/api/general.ts b/src/utils/api/general.ts index b1ef9780..7f72a091 100644 --- a/src/utils/api/general.ts +++ b/src/utils/api/general.ts @@ -1,5 +1,7 @@ +import { getGlobalStorage } from '@utils/storage/actions' import axios from 'axios' import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers' +import { CONNECT_DOMAIN } from './helpers/connect' export type Params = { method: 'get' | 'post' | 'put' | 'delete' @@ -32,17 +34,20 @@ const apiGeneral = async ({ params ? params : '' ) + const useConnect = getGlobalStorage.boolean('app.connect') + return axios({ timeout: method === 'post' ? 1000 * 60 : 1000 * 15, method, - baseURL: `https://${domain}/`, + baseURL: `https://${useConnect ? CONNECT_DOMAIN() : domain}`, url, params, headers: { Accept: 'application/json', ...userAgent, ...headers, - ...(body && body instanceof FormData && { 'Content-Type': 'multipart/form-data' }) + ...(body && body instanceof FormData && { 'Content-Type': 'multipart/form-data' }), + ...(useConnect && { 'x-tooot-domain': domain }) }, data: body }) diff --git a/src/utils/api/helpers/connect.ts b/src/utils/api/helpers/connect.ts new file mode 100644 index 00000000..327fa380 --- /dev/null +++ b/src/utils/api/helpers/connect.ts @@ -0,0 +1,144 @@ +import { mapEnvironment } from '@utils/helpers/checkEnvironment' +import { getGlobalStorage, setGlobalStorage } from '@utils/storage/actions' +import axios from 'axios' +import parse from 'url-parse' +import { userAgent } from '.' + +const list = [ + 'n61owz4leck', + 'z9skyp2f0m', + 'nc2dqtyxevj', + 'tgl97fgudrf', + 'eo2sj0ut2s', + 'a75auwihvyi', + 'vzkpud5y5b', + '3uivf7yyex', + 'pxfoa1wbor', + '3cor5jempc', + '9o32znuepr', + '9ayt1l2dzpi', + '60iu4rz8js', + 'dzoa1lbxbv', + '82rpiiqw21', + 'fblij1c9gyl', + 'wk2x048g8gl', + '9x91yrbtmn', + 'dgu5p7eif6', + 'uftwyhrkgrh', + 'vv5hay15vjk', + 'ooj9ihtyur', + 'o8r7phzd58', + 'pujwyg269s', + 'l6yq5nr8lv', + 'ocyrlfmdnl', + 'rdtpeip5e2', + 'ykzb5784js', + 'm34z7j5us1i', + 'tqsfr0orqa', + '8ncrt0mifa', + 'ygce2fdmsm', + '22vk7csljz', + '7mmb6hrih1', + 'grla5cpgau', + '0vygyvs4k7', + '1texbe32sf', + 'ckwvauiiol', + 'qkxryrbpxx', + 'ptb19c0ks9g', + '3bpe76o6stg', + 'd507ejce9g', + 'jpul5v2mqej', + '6m5uxemc79', + 'wxbtoo9t3p', + '8qco3d0idh', + 'u00c2xiabvf', + 'hutkqwrcy8', + 't6vrkzhpzo', + 'wy6e529mnb', + 'kzzrlfa59pg', + 'mmo4sv4a7s', + 'u0dishl20k', + '8qyx25bq3u', + 'd3mucdzlu1', + 'y123m81vsjl', + '51opvzdo6k', + 'r4z333th9u', + 'q77hl0ggfr', + 'bsk1f2wi52g', + 'eubnxpv0pz', + 'h11pk7qm8i', + 'brhxw45vd5', + 'vtnvlsrn1z', + '0q5w0hhzb5', + 'vq2rz02ayf', + 'hml3igfwkq', + '39qs7vhenl', + '5vcv775rug', + 'kjom5gr7i3', + 't2kmaoeb5x', + 'ni6ow1z11b', + 'yvgtoc3d88', + 'iax04eatnz', + 'esxyu9zujg', + '73xa28n278', + '5x63a8l24k', + 'dy1trb0b3sj', + 'd4c31j23m8', + 'ho76046l0j', + 'sw8lj5u2ef', + 'z5cn21mew5', + 'wxj73nmqwa', + 'gdj00dlx98', + '0v76xag64i', + 'j35104qduhj', + 'l63r7h0ss6', + 'e5xdv7t1q0h', + '4icoh8t4c8', + 'nbk36jt4sq', + 'zi0n0cv4tk', + 'o7qkfp3rxu', + 'xd2wefzd27', + 'rg7e6tsacx', + '9lrq3s4vfm', + 'srs9p21lxoh', + 'n8xymau42t', + 'q5cik283fg', + '68ye9feqs5', + 'xjc5anubnv' +] + +export const CONNECT_DOMAIN = () => + mapEnvironment({ + release: `${list[Math.floor(Math.random() * (100 - 0) + 0)]}.tooot.app`, + candidate: 'connect-candidate.tooot.app', + development: 'connect-development.tooot.app' + }) + +export const connectImage = ({ + uri +}: { + uri?: string +}): { uri?: string; headers?: { 'x-tooot-domain': string } } => { + const connect = getGlobalStorage.boolean('app.connect') + if (connect) { + if (uri) { + const host = parse(uri).host + return { uri: uri.replace(host, CONNECT_DOMAIN()), headers: { 'x-tooot-domain': host } } + } else { + return { uri } + } + } else { + return { uri } + } +} + +export const connectVerify = () => + axios({ + method: 'get', + baseURL: `https://${CONNECT_DOMAIN()}`, + url: 'verify', + headers: { ...userAgent } + }).catch(err => { + setGlobalStorage('app.connect', false) + return Promise.reject(err) + }) diff --git a/src/utils/api/instance.ts b/src/utils/api/instance.ts index ea435c4d..71568650 100644 --- a/src/utils/api/instance.ts +++ b/src/utils/api/instance.ts @@ -1,7 +1,8 @@ -import { getAccountDetails } from '@utils/storage/actions' +import { getAccountDetails, getGlobalStorage } from '@utils/storage/actions' import { StorageGlobal } from '@utils/storage/global' import axios, { AxiosRequestConfig } from 'axios' import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers' +import { CONNECT_DOMAIN } from './helpers/connect' export type Params = { account?: StorageGlobal['account.active'] @@ -43,11 +44,15 @@ const apiInstance = async ({ method + ctx.blue(' -> ') + `/${url}` + (params ? ctx.blue(' -> ') : ''), params ? params : '' ) - console.log('body', body) + + const useConnect = getGlobalStorage.boolean('app.connect') + return axios({ timeout: method === 'post' ? 1000 * 60 : 1000 * 15, method, - baseURL: `https://${accountDetails['auth.domain']}/api/${version}/`, + baseURL: `https://${ + useConnect ? CONNECT_DOMAIN() : accountDetails['auth.domain'] + }/api/${version}`, url, params, headers: { @@ -55,7 +60,8 @@ const apiInstance = async ({ ...userAgent, ...headers, Authorization: `Bearer ${accountDetails['auth.token']}`, - ...(body && body instanceof FormData && { 'Content-Type': 'multipart/form-data' }) + ...(body && body instanceof FormData && { 'Content-Type': 'multipart/form-data' }), + ...(useConnect && { 'x-tooot-domain': accountDetails['auth.domain'] }) }, data: body, ...extras diff --git a/src/utils/storage/global/v0.ts b/src/utils/storage/global/v0.ts index 8554c084..4acdfc39 100644 --- a/src/utils/storage/global/v0.ts +++ b/src/utils/storage/global/v0.ts @@ -17,6 +17,7 @@ export type GlobalV0 = { 'version.account': number // boolean 'app.auto_play_gifv'?: boolean + 'app.connect'?: boolean //// account // string From 8c87841fed6b3fb8b6afc2e369b860f598230b61 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Sun, 29 Jan 2023 16:20:31 +0100 Subject: [PATCH 02/19] Improve account switch hint --- src/components/Filter.tsx | 7 ++--- src/components/SwipeToActions.tsx | 6 ++-- src/screens/Tabs/index.tsx | 47 ++++++++++++++++--------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/components/Filter.tsx b/src/components/Filter.tsx index f9c57fef..92fa9c40 100644 --- a/src/components/Filter.tsx +++ b/src/components/Filter.tsx @@ -2,8 +2,7 @@ import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import { Fragment } from 'react' import { Trans, useTranslation } from 'react-i18next' -import { View, ViewStyle } from 'react-native' -import { TouchableNativeFeedback } from 'react-native-gesture-handler' +import { Pressable, View, ViewStyle } from 'react-native' import Icon from './Icon' import CustomText from './Text' @@ -19,7 +18,7 @@ export const Filter: React.FC = ({ onPress, filter, button, style }) => { const { colors } = useTheme() return ( - + = ({ onPress, filter, button, style }) => { /> )} - + ) } diff --git a/src/components/SwipeToActions.tsx b/src/components/SwipeToActions.tsx index 1b391de3..74f6e01f 100644 --- a/src/components/SwipeToActions.tsx +++ b/src/components/SwipeToActions.tsx @@ -1,5 +1,5 @@ import { StyleConstants } from '@utils/styles/constants' -import { ColorValue, TouchableNativeFeedback, View } from 'react-native' +import { ColorValue, Pressable, View } from 'react-native' import { SwipeListView } from 'react-native-swipe-list-view' import haptics from './haptics' import Icon, { IconName } from './Icon' @@ -25,7 +25,7 @@ export const SwipeToActions = ({ renderHiddenItem={({ item }) => ( {actions.map((action, index) => ( - { haptics(action.haptic || 'Light') @@ -43,7 +43,7 @@ export const SwipeToActions = ({ > - + ))} )} diff --git a/src/screens/Tabs/index.tsx b/src/screens/Tabs/index.tsx index 2f1505aa..4d15445d 100644 --- a/src/screens/Tabs/index.tsx +++ b/src/screens/Tabs/index.tsx @@ -2,11 +2,11 @@ import GracefullyImage from '@components/GracefullyImage' import haptics from '@components/haptics' import Icon from '@components/Icon' import { createBottomTabNavigator } from '@react-navigation/bottom-tabs' -import { RootStackScreenProps, ScreenTabsStackParamList } from '@utils/navigation/navigators' +import { ScreenTabsStackParamList } from '@utils/navigation/navigators' import { getGlobalStorage, useAccountStorage, useGlobalStorage } from '@utils/storage/actions' import { useTheme } from '@utils/styles/ThemeManager' import React from 'react' -import { Platform } from 'react-native' +import { Platform, View } from 'react-native' import TabLocal from './Local' import TabMe from './Me' import TabNotifications from './Notifications' @@ -14,7 +14,7 @@ import TabPublic from './Public' const Tab = createBottomTabNavigator() -const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => { +const ScreenTabs = () => { const { colors } = useTheme() const [accountActive] = useGlobalStorage.string('account.active') @@ -50,19 +50,19 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => { return case 'Tab-Me': return ( - + + + + ) default: return @@ -74,13 +74,13 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => { ({ tabPress: e => { e.preventDefault() haptics('Light') navigation.navigate('Screen-Compose') } - }} + })} > {() => null} @@ -88,15 +88,18 @@ const ScreenTabs = ({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => { ({ + tabPress: () => { + if (navigation.isFocused()) { + navigation.navigate('Tab-Me', { screen: 'Tab-Me-Switch' }) + } + }, tabLongPress: () => { haptics('Light') - //@ts-ignore navigation.navigate('Tab-Me', { screen: 'Tab-Me-Root' }) - //@ts-ignore navigation.navigate('Tab-Me', { screen: 'Tab-Me-Switch' }) } - }} + })} /> ) From e447a91cfbb79683602bad76a864639834c51f0e Mon Sep 17 00:00:00 2001 From: xmflsct Date: Sun, 29 Jan 2023 16:59:14 +0100 Subject: [PATCH 03/19] Fix remote prop not appended in all places --- src/screens/Tabs/Shared/Toot.tsx | 40 +++---------------------------- src/screens/Tabs/Shared/Users.tsx | 38 +++-------------------------- src/utils/helpers/appendRemote.ts | 23 ++++++++++++++++++ src/utils/queryHooks/account.ts | 5 ++-- src/utils/queryHooks/status.ts | 3 ++- src/utils/queryHooks/users.ts | 7 +++++- 6 files changed, 40 insertions(+), 76 deletions(-) create mode 100644 src/utils/helpers/appendRemote.ts diff --git a/src/screens/Tabs/Shared/Toot.tsx b/src/screens/Tabs/Shared/Toot.tsx index 99af54bf..ebbe72e4 100644 --- a/src/screens/Tabs/Shared/Toot.tsx +++ b/src/screens/Tabs/Shared/Toot.tsx @@ -7,6 +7,7 @@ import TimelineDefault from '@components/Timeline/Default' import { useQuery } from '@tanstack/react-query' import apiGeneral from '@utils/api/general' import apiInstance from '@utils/api/instance' +import { appendRemote } from '@utils/helpers/appendRemote' import { urlMatcher } from '@utils/helpers/urlMatcher' import { TabSharedStackScreenProps } from '@utils/navigation/navigators' import { queryClient } from '@utils/queryHooks' @@ -206,26 +207,7 @@ const TabSharedToot: React.FC> = ({ if (localMatch) { return localMatch } else { - return { - ...ancestor, - _remote: true, - account: { ...ancestor.account, _remote: true }, - mentions: ancestor.mentions.map(mention => ({ - ...mention, - _remote: true - })), - ...(ancestor.reblog && { - reblog: { - ...ancestor.reblog, - _remote: true, - account: { ...ancestor.reblog.account, _remote: true }, - mentions: ancestor.reblog.mentions.map(mention => ({ - ...mention, - _remote: true - })) - } - }) - } + return appendRemote.status(ancestor) } }) } @@ -268,23 +250,7 @@ const TabSharedToot: React.FC> = ({ if (localMatch) { return { ...localMatch, _level: remote._level } } else { - return { - ...remote, - _remote: true, - account: { ...remote.account, _remote: true }, - mentions: remote.mentions.map(mention => ({ ...mention, _remote: true })), - ...(remote.reblog && { - reblog: { - ...remote.reblog, - _remote: true, - account: { ...remote.reblog.account, _remote: true }, - mentions: remote.reblog.mentions.map(mention => ({ - ...mention, - _remote: true - })) - } - }) - } + return appendRemote.status(remote) } }) } diff --git a/src/screens/Tabs/Shared/Users.tsx b/src/screens/Tabs/Shared/Users.tsx index f0c4f71f..cfa07adc 100644 --- a/src/screens/Tabs/Shared/Users.tsx +++ b/src/screens/Tabs/Shared/Users.tsx @@ -4,14 +4,12 @@ import Icon from '@components/Icon' import { Loading } from '@components/Loading' import ComponentSeparator from '@components/Separator' import CustomText from '@components/Text' -import apiInstance from '@utils/api/instance' import { TabSharedStackScreenProps } from '@utils/navigation/navigators' -import { SearchResult } from '@utils/queryHooks/search' import { QueryKeyUsers, useUsersQuery } from '@utils/queryHooks/users' import { flattenPages } from '@utils/queryHooks/utils' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' -import React, { useEffect, useState } from 'react' +import React, { useEffect } from 'react' import { useTranslation } from 'react-i18next' import { View } from 'react-native' import { FlatList } from 'react-native-gesture-handler' @@ -36,8 +34,6 @@ const TabSharedUsers: React.FC> = ...queryKey[1] }) - const [isSearching, setIsSearching] = useState(null) - return ( > = minHeight: '100%', paddingVertical: StyleConstants.Spacing.Global.PagePadding }} - renderItem={({ item, index }) => ( + renderItem={({ item }) => ( { - if (data?.pages[0]?.remoteData) { - setIsSearching(index) - apiInstance({ - version: 'v2', - method: 'get', - url: 'search', - params: { - q: `@${item.acct}`, - type: 'accounts', - limit: 1, - resolve: true - } - }) - .then(res => { - setIsSearching(null) - if (res.body.accounts[0]) { - navigation.push('Tab-Shared-Account', { account: res.body.accounts[0] }) - } - }) - .catch(() => setIsSearching(null)) - } else { - navigation.push('Tab-Shared-Account', { account: item }) - } - } - }} - children={} + props={{ onPress: () => navigation.push('Tab-Shared-Account', { account: item }) }} /> )} onEndReached={() => hasNextPage && !isFetchingNextPage && fetchNextPage()} diff --git a/src/utils/helpers/appendRemote.ts b/src/utils/helpers/appendRemote.ts new file mode 100644 index 00000000..2ebf92cf --- /dev/null +++ b/src/utils/helpers/appendRemote.ts @@ -0,0 +1,23 @@ +// Central place appending _remote internal prop + +export const appendRemote = { + status: (status: Mastodon.Status) => ({ + ...status, + ...(status.reblog && { + reblog: { + ...status.reblog, + account: appendRemote.account(status.reblog.account), + mentions: appendRemote.mentions(status.reblog.mentions) + } + }), + account: appendRemote.account(status.account), + mentions: appendRemote.mentions(status.mentions), + _remote: true + }), + account: (account: Mastodon.Account) => ({ + ...account, + _remote: true + }), + mentions: (mentions: Mastodon.Mention[]) => + mentions.map(mention => ({ ...mention, _remote: true })) +} diff --git a/src/utils/queryHooks/account.ts b/src/utils/queryHooks/account.ts index 2154b34d..61c2bfca 100644 --- a/src/utils/queryHooks/account.ts +++ b/src/utils/queryHooks/account.ts @@ -1,6 +1,7 @@ import { QueryFunctionContext, useQuery, UseQueryOptions } from '@tanstack/react-query' import apiGeneral from '@utils/api/general' import apiInstance from '@utils/api/instance' +import { appendRemote } from '@utils/helpers/appendRemote' import { urlMatcher } from '@utils/helpers/urlMatcher' import { AxiosError } from 'axios' import { searchLocalAccount } from './search' @@ -34,14 +35,14 @@ const accountQueryFunction = async ({ queryKey }: QueryFunctionContext ({ ...res.body, _remote: true })) + }).then(res => appendRemote.account(res.body)) } else if (acct) { matchedAccount = await apiGeneral({ method: 'get', domain: domain, url: 'api/v1/accounts/lookup', params: { acct } - }).then(res => ({ ...res.body, _remote: true })) + }).then(res => appendRemote.account(res.body)) } } catch {} } diff --git a/src/utils/queryHooks/status.ts b/src/utils/queryHooks/status.ts index eb927208..602c039c 100644 --- a/src/utils/queryHooks/status.ts +++ b/src/utils/queryHooks/status.ts @@ -1,6 +1,7 @@ import { QueryFunctionContext, useQuery, UseQueryOptions } from '@tanstack/react-query' import apiGeneral from '@utils/api/general' import apiInstance from '@utils/api/instance' +import { appendRemote } from '@utils/helpers/appendRemote' import { urlMatcher } from '@utils/helpers/urlMatcher' import { AxiosError } from 'axios' import { searchLocalStatus } from './search' @@ -26,7 +27,7 @@ const queryFunction = async ({ queryKey }: QueryFunctionContext) method: 'get', domain, url: `api/v1/statuses/${id}` - }).then(res => ({ ...res.body, _remote: true })) + }).then(res => appendRemote.status(res.body)) } catch {} } diff --git a/src/utils/queryHooks/users.ts b/src/utils/queryHooks/users.ts index 87fd1366..6b9a43e0 100644 --- a/src/utils/queryHooks/users.ts +++ b/src/utils/queryHooks/users.ts @@ -6,6 +6,7 @@ import { import apiGeneral from '@utils/api/general' import { PagedResponse } from '@utils/api/helpers' import apiInstance from '@utils/api/instance' +import { appendRemote } from '@utils/helpers/appendRemote' import { urlMatcher } from '@utils/helpers/urlMatcher' import { TabSharedStackParamList } from '@utils/navigation/navigators' import { AxiosError } from 'axios' @@ -54,7 +55,11 @@ const queryFunction = async ({ queryKey, pageParam }: QueryFunctionContext appendRemote.account(account)), + remoteData: true + } } else { throw new Error() } From 752d33d5b3b801f7818ebbb50eb380126340ac2a Mon Sep 17 00:00:00 2001 From: xmflsct Date: Sun, 29 Jan 2023 17:28:49 +0100 Subject: [PATCH 04/19] Dimming images for dark mode --- src/components/Account.tsx | 1 + src/components/GracefullyImage.tsx | 14 ++++++++++++-- src/components/Timeline/Conversation.tsx | 1 + .../Timeline/Shared/Attachment/Audio.tsx | 6 ++---- .../Timeline/Shared/Attachment/Image.tsx | 1 + src/components/Timeline/Shared/Avatar.tsx | 4 ++-- src/components/Timeline/Shared/Card.tsx | 1 + src/screens/Tabs/Shared/Account/Attachments.tsx | 1 + src/screens/Tabs/Shared/Account/Header.tsx | 1 + .../Tabs/Shared/Account/Information/Avatar.tsx | 1 + src/screens/Tabs/index.tsx | 5 ----- 11 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/Account.tsx b/src/components/Account.tsx index a59b51f1..da062c03 100644 --- a/src/components/Account.tsx +++ b/src/components/Account.tsx @@ -45,6 +45,7 @@ const ComponentAccount: React.FC = ({ account, props, borderRadius: 8, marginRight: StyleConstants.Spacing.S }} + dim /> diff --git a/src/components/GracefullyImage.tsx b/src/components/GracefullyImage.tsx index 9a708980..30aec804 100644 --- a/src/components/GracefullyImage.tsx +++ b/src/components/GracefullyImage.tsx @@ -38,6 +38,7 @@ export interface Props { height: number }> > + dim?: boolean } const GracefullyImage = ({ @@ -50,10 +51,11 @@ const GracefullyImage = ({ onPress, style, imageStyle, - setImageDimensions + setImageDimensions, + dim }: Props) => { const { reduceMotionEnabled } = useAccessibility() - const { colors } = useTheme() + const { colors, theme } = useTheme() const [imageLoaded, setImageLoaded] = useState(false) const [currentUri, setCurrentUri] = useState(uri.original || uri.remote) @@ -111,6 +113,14 @@ const GracefullyImage = ({ }} /> {blurhashView()} + {dim && theme !== 'light' ? ( + + ) : null} ) } diff --git a/src/components/Timeline/Conversation.tsx b/src/components/Timeline/Conversation.tsx index 3f492e49..182fde47 100644 --- a/src/components/Timeline/Conversation.tsx +++ b/src/components/Timeline/Conversation.tsx @@ -88,6 +88,7 @@ const TimelineConversation: React.FC = ({ conversation, queryKey, highlig : StyleConstants.Avatar.M }} style={{ flex: 1, flexBasis: '50%' }} + dim /> ))} diff --git a/src/components/Timeline/Shared/Attachment/Audio.tsx b/src/components/Timeline/Shared/Attachment/Audio.tsx index 3c3cd5ee..94cbdde0 100644 --- a/src/components/Timeline/Shared/Attachment/Audio.tsx +++ b/src/components/Timeline/Shared/Attachment/Audio.tsx @@ -83,11 +83,9 @@ const AttachmentAudio: React.FC = ({ total, index, sensitiveShown, audio <> {audio.preview_url ? ( ) : null}