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

View File

@ -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 }}
/>
</Pressable>

View File

@ -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<string | undefined>(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 ? (
<FastImage
source={{ uri: uri.preview }}
source={connectImage({ uri: uri.preview })}
style={[styles.placeholder, { backgroundColor: colors.shimmerDefault }]}
/>
) : null}
<FastImage
source={source}
source={connectImage(source)}
style={[{ flex: 1 }, imageStyle]}
onLoad={() => {
setImageLoaded(true)

View File

@ -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<Props> = ({
<CustomText key={emojiShortcode + i}>
{i === 0 ? ' ' : undefined}
<FastImage
source={{ uri: uri.trim() }}
source={connectImage({ uri: uri.trim() })}
style={{
width: adaptedFontsize,
height: adaptedFontsize,

View File

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

View File

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

View File

@ -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<Props> = ({ accessibleRefAttachments }) => {
>
<FastImage
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 ? (
<CustomText

View File

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

View File

@ -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 <T = unknown>({
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
})

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 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 <T = unknown>({
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 <T = unknown>({
...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

View File

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