Try out connect

This commit is contained in:
xmflsct 2023-01-29 15:32:40 +01:00
parent 3451a021e9
commit 95a99ef7cd
12 changed files with 233 additions and 32 deletions

View File

@ -2,6 +2,7 @@ import { ActionSheetProvider } from '@expo/react-native-action-sheet'
import * as Sentry from '@sentry/react-native' import * as Sentry from '@sentry/react-native'
import { QueryClientProvider } from '@tanstack/react-query' import { QueryClientProvider } from '@tanstack/react-query'
import AccessibilityManager from '@utils/accessibility/AccessibilityManager' import AccessibilityManager from '@utils/accessibility/AccessibilityManager'
import { connectVerify } from '@utils/api/helpers/connect'
import getLanguage from '@utils/helpers/getLanguage' import getLanguage from '@utils/helpers/getLanguage'
import { queryClient } from '@utils/queryHooks' import { queryClient } from '@utils/queryHooks'
import audio from '@utils/startup/audio' import audio from '@utils/startup/audio'
@ -50,20 +51,28 @@ const App: React.FC = () => {
await migrateFromAsyncStorage() await migrateFromAsyncStorage()
setHasMigrated(true) setHasMigrated(true)
} catch {} } 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 { } else {
log('log', 'App', 'loading from MMKV') log('log', 'App', 'No active account available')
const account = getGlobalStorage.string('account.active') const accounts = getGlobalStorage.object('accounts')
if (account) { if (accounts?.length) {
await setAccount(account) log('log', 'App', `Setting active account ${accounts[accounts.length - 1]}`)
await setAccount(accounts[accounts.length - 1])
} else { } else {
log('log', 'App', 'No active account available') setGlobalStorage('account.active', undefined)
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)
}
} }
} }

View File

@ -2,6 +2,7 @@ import { emojis } from '@components/Emojis'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { connectImage } from '@utils/api/helpers/connect'
import { StorageAccount } from '@utils/storage/account' import { StorageAccount } from '@utils/storage/account'
import { getAccountStorage, setAccountStorage } from '@utils/storage/actions' import { getAccountStorage, setAccountStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
@ -133,7 +134,7 @@ const EmojisList = () => {
emoji: emoji.shortcode emoji: emoji.shortcode
})} })}
accessibilityHint={t('screenCompose:content.root.footer.emojis.accessibilityHint')} accessibilityHint={t('screenCompose:content.root.footer.emojis.accessibilityHint')}
source={{ uri }} source={connectImage({ uri })}
style={{ width: 32, height: 32 }} style={{ width: 32, height: 32 }}
/> />
</Pressable> </Pressable>

View File

@ -1,4 +1,5 @@
import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { connectImage } from '@utils/api/helpers/connect'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { import {
@ -56,7 +57,7 @@ const GracefullyImage = ({
const [imageLoaded, setImageLoaded] = useState(false) const [imageLoaded, setImageLoaded] = useState(false)
const [currentUri, setCurrentUri] = useState<string | undefined>(uri.original || uri.remote) const [currentUri, setCurrentUri] = useState<string | undefined>(uri.original || uri.remote)
const source = { const source: { uri?: string } = {
uri: reduceMotionEnabled && uri.static ? uri.static : currentUri uri: reduceMotionEnabled && uri.static ? uri.static : currentUri
} }
useEffect(() => { useEffect(() => {
@ -90,12 +91,12 @@ const GracefullyImage = ({
> >
{uri.preview && !imageLoaded ? ( {uri.preview && !imageLoaded ? (
<FastImage <FastImage
source={{ uri: uri.preview }} source={connectImage({ uri: uri.preview })}
style={[styles.placeholder, { backgroundColor: colors.shimmerDefault }]} style={[styles.placeholder, { backgroundColor: colors.shimmerDefault }]}
/> />
) : null} ) : null}
<FastImage <FastImage
source={source} source={connectImage(source)}
style={[{ flex: 1 }, imageStyle]} style={[{ flex: 1 }, imageStyle]}
onLoad={() => { onLoad={() => {
setImageLoaded(true) setImageLoaded(true)

View File

@ -1,5 +1,6 @@
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { connectImage } from '@utils/api/helpers/connect'
import { useGlobalStorage } from '@utils/storage/actions' import { useGlobalStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { adaptiveScale } from '@utils/styles/scaling' import { adaptiveScale } from '@utils/styles/scaling'
@ -75,7 +76,7 @@ const ParseEmojis: React.FC<Props> = ({
<CustomText key={emojiShortcode + i}> <CustomText key={emojiShortcode + i}>
{i === 0 ? ' ' : undefined} {i === 0 ? ' ' : undefined}
<FastImage <FastImage
source={{ uri: uri.trim() }} source={connectImage({ uri: uri.trim() })}
style={{ style={{
width: adaptedFontsize, width: adaptedFontsize,
height: adaptedFontsize, height: adaptedFontsize,

View File

@ -6,6 +6,7 @@ import RelativeTime from '@components/RelativeTime'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { BlurView } from '@react-native-community/blur' import { BlurView } from '@react-native-community/blur'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager' import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
import { connectImage } from '@utils/api/helpers/connect'
import { RootStackScreenProps } from '@utils/navigation/navigators' import { RootStackScreenProps } from '@utils/navigation/navigators'
import { useAnnouncementMutation, useAnnouncementQuery } from '@utils/queryHooks/announcement' import { useAnnouncementMutation, useAnnouncementQuery } from '@utils/queryHooks/announcement'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
@ -139,9 +140,9 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
> >
{reaction.url ? ( {reaction.url ? (
<FastImage <FastImage
source={{ source={connectImage({
uri: reduceMotionEnabled ? reaction.static_url : reaction.url uri: reduceMotionEnabled ? reaction.static_url : reaction.url
}} })}
style={{ style={{
width: StyleConstants.Font.LineHeight.M + 3, width: StyleConstants.Font.LineHeight.M + 3,
height: StyleConstants.Font.LineHeight.M height: StyleConstants.Font.LineHeight.M

View File

@ -3,6 +3,7 @@ import Icon from '@components/Icon'
import { SwipeToActions } from '@components/SwipeToActions' import { SwipeToActions } from '@components/SwipeToActions'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created' import HeaderSharedCreated from '@components/Timeline/Shared/HeaderShared/Created'
import { connectImage } from '@utils/api/helpers/connect'
import apiInstance from '@utils/api/instance' import apiInstance from '@utils/api/instance'
import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators' import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators'
import { getAccountStorage, setAccountStorage, useAccountStorage } from '@utils/storage/actions' import { getAccountStorage, setAccountStorage, useAccountStorage } from '@utils/storage/actions'
@ -154,9 +155,11 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
4, 4,
marginLeft: index !== 0 ? StyleConstants.Spacing.S : 0 marginLeft: index !== 0 ? StyleConstants.Spacing.S : 0
}} }}
source={{ source={
uri: attachment.local?.thumbnail || attachment.remote?.preview_url attachment.local?.thumbnail
}} ? { uri: attachment.local?.thumbnail }
: connectImage({ uri: attachment.remote?.preview_url })
}
/> />
))} ))}
</View> </View>

View File

@ -6,6 +6,7 @@ import { MAX_MEDIA_ATTACHMENTS } from '@components/mediaSelector'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { useActionSheet } from '@expo/react-native-action-sheet' import { useActionSheet } from '@expo/react-native-action-sheet'
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { connectImage } from '@utils/api/helpers/connect'
import { featureCheck } from '@utils/helpers/featureCheck' import { featureCheck } from '@utils/helpers/featureCheck'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation' import layoutAnimation from '@utils/styles/layoutAnimation'
@ -105,7 +106,11 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
> >
<FastImage <FastImage
style={{ width: '100%', height: '100%' }} style={{ width: '100%', height: '100%' }}
source={{ uri: item.local?.thumbnail || item.remote?.preview_url }} source={
item.local?.thumbnail
? { uri: item.local?.thumbnail }
: connectImage({ uri: item.remote?.preview_url })
}
/> />
{item.remote?.meta?.original?.duration ? ( {item.remote?.meta?.original?.duration ? (
<CustomText <CustomText

View File

@ -1,16 +1,17 @@
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { MenuContainer, MenuRow } from '@components/Menu' import { MenuContainer, MenuRow } from '@components/Menu'
import { useActionSheet } from '@expo/react-native-action-sheet' import { useActionSheet } from '@expo/react-native-action-sheet'
import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles' import { LOCALES } from '@i18n/locales'
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { connectVerify } from '@utils/api/helpers/connect'
import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles'
import { useGlobalStorage } from '@utils/storage/actions' import { useGlobalStorage } from '@utils/storage/actions'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import * as Localization from 'expo-localization' import * as Localization from 'expo-localization'
import React from 'react' import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Linking, Platform } from 'react-native' import { Linking, Platform } from 'react-native'
import { mapFontsizeToName } from '../SettingsFontsize' import { mapFontsizeToName } from '../SettingsFontsize'
import { LOCALES } from '@i18n/locales'
const SettingsApp: React.FC = () => { const SettingsApp: React.FC = () => {
const navigation = useNavigation<any>() const navigation = useNavigation<any>()
@ -24,6 +25,22 @@ const SettingsApp: React.FC = () => {
const [browser, setBrowser] = useGlobalStorage.string('app.browser') const [browser, setBrowser] = useGlobalStorage.string('app.browser')
const [autoplayGifv, setAutoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv') 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 ( return (
<MenuContainer> <MenuContainer>
<MenuRow <MenuRow
@ -152,6 +169,13 @@ const SettingsApp: React.FC = () => {
switchValue={autoplayGifv} switchValue={autoplayGifv}
switchOnValueChange={() => setAutoplayGifv(!autoplayGifv)} switchOnValueChange={() => setAutoplayGifv(!autoplayGifv)}
/> />
{showConnect ? (
<MenuRow
title='使用代理'
switchValue={connect || false}
switchOnValueChange={() => setConnect(!connect)}
/>
) : null}
</MenuContainer> </MenuContainer>
) )
} }

View File

@ -1,5 +1,7 @@
import { getGlobalStorage } from '@utils/storage/actions'
import axios from 'axios' import axios from 'axios'
import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers' import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers'
import { CONNECT_DOMAIN } from './helpers/connect'
export type Params = { export type Params = {
method: 'get' | 'post' | 'put' | 'delete' method: 'get' | 'post' | 'put' | 'delete'
@ -32,17 +34,20 @@ const apiGeneral = async <T = unknown>({
params ? params : '' params ? params : ''
) )
const useConnect = getGlobalStorage.boolean('app.connect')
return axios({ return axios({
timeout: method === 'post' ? 1000 * 60 : 1000 * 15, timeout: method === 'post' ? 1000 * 60 : 1000 * 15,
method, method,
baseURL: `https://${domain}/`, baseURL: `https://${useConnect ? CONNECT_DOMAIN() : domain}`,
url, url,
params, params,
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
...userAgent, ...userAgent,
...headers, ...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 data: body
}) })

View File

@ -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)
})

View File

@ -1,7 +1,8 @@
import { getAccountDetails } from '@utils/storage/actions' import { getAccountDetails, getGlobalStorage } from '@utils/storage/actions'
import { StorageGlobal } from '@utils/storage/global' import { StorageGlobal } from '@utils/storage/global'
import axios, { AxiosRequestConfig } from 'axios' import axios, { AxiosRequestConfig } from 'axios'
import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers' import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers'
import { CONNECT_DOMAIN } from './helpers/connect'
export type Params = { export type Params = {
account?: StorageGlobal['account.active'] account?: StorageGlobal['account.active']
@ -43,11 +44,15 @@ const apiInstance = async <T = unknown>({
method + ctx.blue(' -> ') + `/${url}` + (params ? ctx.blue(' -> ') : ''), method + ctx.blue(' -> ') + `/${url}` + (params ? ctx.blue(' -> ') : ''),
params ? params : '' params ? params : ''
) )
console.log('body', body)
const useConnect = getGlobalStorage.boolean('app.connect')
return axios({ return axios({
timeout: method === 'post' ? 1000 * 60 : 1000 * 15, timeout: method === 'post' ? 1000 * 60 : 1000 * 15,
method, method,
baseURL: `https://${accountDetails['auth.domain']}/api/${version}/`, baseURL: `https://${
useConnect ? CONNECT_DOMAIN() : accountDetails['auth.domain']
}/api/${version}`,
url, url,
params, params,
headers: { headers: {
@ -55,7 +60,8 @@ const apiInstance = async <T = unknown>({
...userAgent, ...userAgent,
...headers, ...headers,
Authorization: `Bearer ${accountDetails['auth.token']}`, 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, data: body,
...extras ...extras

View File

@ -17,6 +17,7 @@ export type GlobalV0 = {
'version.account': number 'version.account': number
// boolean // boolean
'app.auto_play_gifv'?: boolean 'app.auto_play_gifv'?: boolean
'app.connect'?: boolean
//// account //// account
// string // string