mirror of
https://github.com/tooot-app/app
synced 2025-03-09 16:10:05 +01:00
Try out connect
This commit is contained in:
parent
3451a021e9
commit
95a99ef7cd
33
src/App.tsx
33
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
})
|
||||
|
144
src/utils/api/helpers/connect.ts
Normal file
144
src/utils/api/helpers/connect.ts
Normal 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)
|
||||
})
|
@ -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
|
||||
|
@ -17,6 +17,7 @@ export type GlobalV0 = {
|
||||
'version.account': number
|
||||
// boolean
|
||||
'app.auto_play_gifv'?: boolean
|
||||
'app.connect'?: boolean
|
||||
|
||||
//// account
|
||||
// string
|
||||
|
Loading…
x
Reference in New Issue
Block a user