mirror of
https://github.com/tooot-app/app
synced 2024-12-22 07:34:06 +01:00
Improve push error messaging
This commit is contained in:
parent
1a069d5acc
commit
748351026f
@ -1,3 +1,5 @@
|
|||||||
Enjoy toooting! This version includes following improvements and fixes:
|
Enjoy toooting! This version includes following improvements and fixes:
|
||||||
- Automatic setting detected language when tooting
|
- Automatic setting detected language when tooting
|
||||||
|
- Added notification for admins
|
||||||
- Fix whole word filter matching
|
- Fix whole word filter matching
|
||||||
|
- Fix tablet cannot delete toot drafts
|
@ -1,3 +1,5 @@
|
|||||||
toooting愉快!此版本包括以下改进和修复:
|
toooting愉快!此版本包括以下改进和修复:
|
||||||
- 自动识别发嘟语言
|
- 自动识别发嘟语言
|
||||||
|
- 新增管理员推送通知
|
||||||
- 修复过滤整词功能
|
- 修复过滤整词功能
|
||||||
|
- 修复平板不能删除草稿
|
@ -1,90 +0,0 @@
|
|||||||
import browserPackage from '@helpers/browserPackage'
|
|
||||||
import { useNavigation } from '@react-navigation/native'
|
|
||||||
import { useAppDispatch } from '@root/store'
|
|
||||||
import { InstanceLatest } from '@utils/migrations/instances/migration'
|
|
||||||
import { TabMeStackNavigationProp } from '@utils/navigation/navigators'
|
|
||||||
import addInstance from '@utils/slices/instances/add'
|
|
||||||
import { checkInstanceFeature } from '@utils/slices/instancesSlice'
|
|
||||||
import * as AuthSession from 'expo-auth-session'
|
|
||||||
import React, { useEffect } from 'react'
|
|
||||||
import { useQueryClient } from 'react-query'
|
|
||||||
import { useSelector } from 'react-redux'
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
instanceDomain: string
|
|
||||||
// Domain can be different than uri
|
|
||||||
instance: Mastodon.Instance
|
|
||||||
appData: InstanceLatest['appData']
|
|
||||||
goBack?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const InstanceAuth = React.memo(
|
|
||||||
({ instanceDomain, instance, appData, goBack }: Props) => {
|
|
||||||
const redirectUri = AuthSession.makeRedirectUri({
|
|
||||||
native: 'tooot://instance-auth',
|
|
||||||
useProxy: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const navigation = useNavigation<TabMeStackNavigationProp<'Tab-Me-Root' | 'Tab-Me-Switch'>>()
|
|
||||||
const queryClient = useQueryClient()
|
|
||||||
const dispatch = useAppDispatch()
|
|
||||||
|
|
||||||
const deprecateAuthFollow = useSelector(checkInstanceFeature('deprecate_auth_follow'))
|
|
||||||
const [request, response, promptAsync] = AuthSession.useAuthRequest(
|
|
||||||
{
|
|
||||||
clientId: appData.clientId,
|
|
||||||
clientSecret: appData.clientSecret,
|
|
||||||
scopes: deprecateAuthFollow
|
|
||||||
? ['read', 'write', 'push']
|
|
||||||
: ['read', 'write', 'follow', 'push'],
|
|
||||||
redirectUri
|
|
||||||
},
|
|
||||||
{
|
|
||||||
authorizationEndpoint: `https://${instanceDomain}/oauth/authorize`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
useEffect(() => {
|
|
||||||
;(async () => {
|
|
||||||
if (request?.clientId) {
|
|
||||||
await promptAsync({ browserPackage: await browserPackage() }).catch(e => console.log(e))
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
}, [request])
|
|
||||||
useEffect(() => {
|
|
||||||
;(async () => {
|
|
||||||
if (response?.type === 'success') {
|
|
||||||
const { accessToken } = await AuthSession.exchangeCodeAsync(
|
|
||||||
{
|
|
||||||
clientId: appData.clientId,
|
|
||||||
clientSecret: appData.clientSecret,
|
|
||||||
scopes: ['read', 'write', 'follow', 'push'],
|
|
||||||
redirectUri,
|
|
||||||
code: response.params.code,
|
|
||||||
extraParams: {
|
|
||||||
grant_type: 'authorization_code'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tokenEndpoint: `https://${instanceDomain}/oauth/token`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
queryClient.clear()
|
|
||||||
dispatch(
|
|
||||||
addInstance({
|
|
||||||
domain: instanceDomain,
|
|
||||||
token: accessToken,
|
|
||||||
instance,
|
|
||||||
appData
|
|
||||||
})
|
|
||||||
)
|
|
||||||
goBack && navigation.goBack()
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
}, [response])
|
|
||||||
|
|
||||||
return <></>
|
|
||||||
},
|
|
||||||
() => true
|
|
||||||
)
|
|
||||||
|
|
||||||
export default InstanceAuth
|
|
@ -1,22 +1,27 @@
|
|||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import browserPackage from '@helpers/browserPackage'
|
import browserPackage from '@helpers/browserPackage'
|
||||||
import { useAppsQuery } from '@utils/queryHooks/apps'
|
import { redirectUri, useAppsMutation } from '@utils/queryHooks/apps'
|
||||||
import { useInstanceQuery } from '@utils/queryHooks/instance'
|
import { useInstanceQuery } from '@utils/queryHooks/instance'
|
||||||
import { getInstances } from '@utils/slices/instancesSlice'
|
import { checkInstanceFeature, getInstances } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
import * as AuthSession from 'expo-auth-session'
|
||||||
import * as WebBrowser from 'expo-web-browser'
|
import * as WebBrowser from 'expo-web-browser'
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
import React, { RefObject, useCallback, useMemo, useState } from 'react'
|
import React, { RefObject, useCallback, useState } from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
|
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
|
||||||
import { ScrollView } from 'react-native-gesture-handler'
|
import { ScrollView } from 'react-native-gesture-handler'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { Placeholder } from 'rn-placeholder'
|
import { Placeholder } from 'rn-placeholder'
|
||||||
import InstanceAuth from './Instance/Auth'
|
import InstanceInfo from './Info'
|
||||||
import InstanceInfo from './Instance/Info'
|
import CustomText from '../Text'
|
||||||
import CustomText from './Text'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
import { TabMeStackNavigationProp } from '@utils/navigation/navigators'
|
||||||
|
import queryClient from '@helpers/queryClient'
|
||||||
|
import { useAppDispatch } from '@root/store'
|
||||||
|
import addInstance from '@utils/slices/instances/add'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
scrollViewRef?: RefObject<ScrollView>
|
scrollViewRef?: RefObject<ScrollView>
|
||||||
@ -31,30 +36,64 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation('componentInstance')
|
const { t } = useTranslation('componentInstance')
|
||||||
const { colors, mode } = useTheme()
|
const { colors, mode } = useTheme()
|
||||||
|
const navigation = useNavigation<TabMeStackNavigationProp<'Tab-Me-Root' | 'Tab-Me-Switch'>>()
|
||||||
|
|
||||||
|
const [domain, setDomain] = useState<string>('')
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch()
|
||||||
const instances = useSelector(getInstances, () => true)
|
const instances = useSelector(getInstances, () => true)
|
||||||
const [domain, setDomain] = useState<string>()
|
|
||||||
|
|
||||||
const instanceQuery = useInstanceQuery({
|
const instanceQuery = useInstanceQuery({
|
||||||
domain,
|
domain,
|
||||||
options: { enabled: !!domain, retry: false }
|
options: { enabled: !!domain, retry: false }
|
||||||
})
|
})
|
||||||
const appsQuery = useAppsQuery({
|
|
||||||
domain,
|
|
||||||
options: { enabled: false, retry: false }
|
|
||||||
})
|
|
||||||
|
|
||||||
const onChangeText = useCallback(
|
const deprecateAuthFollow = useSelector(checkInstanceFeature('deprecate_auth_follow'))
|
||||||
debounce(
|
|
||||||
text => {
|
const appsMutation = useAppsMutation({
|
||||||
setDomain(text.replace(/^http(s)?\:\/\//i, ''))
|
retry: false,
|
||||||
appsQuery.remove()
|
onSuccess: async (data, variables) => {
|
||||||
|
const clientId = data.client_id
|
||||||
|
const clientSecret = data.client_secret
|
||||||
|
|
||||||
|
const discovery = { authorizationEndpoint: `https://${domain}/oauth/authorize` }
|
||||||
|
|
||||||
|
const request = new AuthSession.AuthRequest({
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
scopes: deprecateAuthFollow
|
||||||
|
? ['read', 'write', 'push']
|
||||||
|
: ['read', 'write', 'follow', 'push'],
|
||||||
|
redirectUri
|
||||||
|
})
|
||||||
|
await request.makeAuthUrlAsync(discovery)
|
||||||
|
|
||||||
|
const promptResult = await request.promptAsync(discovery)
|
||||||
|
|
||||||
|
if (promptResult?.type === 'success') {
|
||||||
|
const { accessToken } = await AuthSession.exchangeCodeAsync(
|
||||||
|
{
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
scopes: ['read', 'write', 'follow', 'push'],
|
||||||
|
redirectUri,
|
||||||
|
code: promptResult.params.code,
|
||||||
|
extraParams: { grant_type: 'authorization_code' }
|
||||||
},
|
},
|
||||||
1000,
|
{ tokenEndpoint: `https://${variables.domain}/oauth/token` }
|
||||||
{ trailing: true }
|
|
||||||
),
|
|
||||||
[]
|
|
||||||
)
|
)
|
||||||
|
queryClient.clear()
|
||||||
|
dispatch(
|
||||||
|
addInstance({
|
||||||
|
domain,
|
||||||
|
token: accessToken,
|
||||||
|
instance: instanceQuery.data!,
|
||||||
|
appData: { clientId, clientSecret }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
goBack && navigation.goBack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const processUpdate = useCallback(() => {
|
const processUpdate = useCallback(() => {
|
||||||
if (domain) {
|
if (domain) {
|
||||||
@ -66,39 +105,15 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: t('common:buttons.continue'),
|
text: t('common:buttons.continue'),
|
||||||
onPress: () => {
|
onPress: () => appsMutation.mutate({ domain })
|
||||||
appsQuery.refetch()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
appsQuery.refetch()
|
appsMutation.mutate({ domain })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [domain])
|
}, [domain])
|
||||||
|
|
||||||
const requestAuth = useMemo(() => {
|
|
||||||
if (
|
|
||||||
domain &&
|
|
||||||
instanceQuery.data?.uri &&
|
|
||||||
appsQuery.data?.client_id &&
|
|
||||||
appsQuery.data.client_secret
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<InstanceAuth
|
|
||||||
key={Math.random()}
|
|
||||||
instanceDomain={domain}
|
|
||||||
instance={instanceQuery.data}
|
|
||||||
appData={{
|
|
||||||
clientId: appsQuery.data.client_id,
|
|
||||||
clientSecret: appsQuery.data.client_secret
|
|
||||||
}}
|
|
||||||
goBack={goBack}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}, [domain, instanceQuery.data, appsQuery.data])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
@ -145,7 +160,9 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
borderBottomColor: instanceQuery.isError ? colors.red : colors.border
|
borderBottomColor: instanceQuery.isError ? colors.red : colors.border
|
||||||
}}
|
}}
|
||||||
onChangeText={onChangeText}
|
onChangeText={debounce(text => setDomain(text.replace(/^http(s)?\:\/\//i, '')), 1000, {
|
||||||
|
trailing: true
|
||||||
|
})}
|
||||||
autoCapitalize='none'
|
autoCapitalize='none'
|
||||||
clearButtonMode='never'
|
clearButtonMode='never'
|
||||||
keyboardType='url'
|
keyboardType='url'
|
||||||
@ -176,7 +193,7 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
content={t('server.button')}
|
content={t('server.button')}
|
||||||
onPress={processUpdate}
|
onPress={processUpdate}
|
||||||
disabled={!instanceQuery.data?.uri}
|
disabled={!instanceQuery.data?.uri}
|
||||||
loading={instanceQuery.isFetching || appsQuery.isFetching}
|
loading={instanceQuery.isFetching || appsMutation.isLoading}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@ -276,8 +293,6 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{requestAuth}
|
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import CustomText from '@components/Text'
|
|||||||
import browserPackage from '@helpers/browserPackage'
|
import browserPackage from '@helpers/browserPackage'
|
||||||
import { useAppDispatch } from '@root/store'
|
import { useAppDispatch } from '@root/store'
|
||||||
import { isDevelopment } from '@utils/checkEnvironment'
|
import { isDevelopment } from '@utils/checkEnvironment'
|
||||||
|
import { useAppsQuery } from '@utils/queryHooks/apps'
|
||||||
import { useProfileQuery } from '@utils/queryHooks/profile'
|
import { useProfileQuery } from '@utils/queryHooks/profile'
|
||||||
import { getExpoToken, retrieveExpoToken } from '@utils/slices/appSlice'
|
import { getExpoToken, retrieveExpoToken } from '@utils/slices/appSlice'
|
||||||
import {
|
import {
|
||||||
@ -30,7 +31,16 @@ import { useSelector } from 'react-redux'
|
|||||||
const TabMePush: React.FC = () => {
|
const TabMePush: React.FC = () => {
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const { t } = useTranslation('screenTabs')
|
const { t } = useTranslation('screenTabs')
|
||||||
|
|
||||||
const instance = useSelector(getInstance)
|
const instance = useSelector(getInstance)
|
||||||
|
const expoToken = useSelector(getExpoToken)
|
||||||
|
|
||||||
|
const [serverKeyAvailable, setServerKeyAvailable] = useState<boolean>()
|
||||||
|
useAppsQuery({
|
||||||
|
options: {
|
||||||
|
onSuccess: data => setServerKeyAvailable(!!data.vapid_key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const instancePush = useSelector(getInstancePush)
|
const instancePush = useSelector(getInstancePush)
|
||||||
@ -38,7 +48,8 @@ const TabMePush: React.FC = () => {
|
|||||||
const [pushAvailable, setPushAvailable] = useState<boolean>()
|
const [pushAvailable, setPushAvailable] = useState<boolean>()
|
||||||
const [pushEnabled, setPushEnabled] = useState<boolean>()
|
const [pushEnabled, setPushEnabled] = useState<boolean>()
|
||||||
const [pushCanAskAgain, setPushCanAskAgain] = useState<boolean>()
|
const [pushCanAskAgain, setPushCanAskAgain] = useState<boolean>()
|
||||||
const expoToken = useSelector(getExpoToken)
|
|
||||||
|
useEffect(() => {
|
||||||
const checkPush = async () => {
|
const checkPush = async () => {
|
||||||
switch (Platform.OS) {
|
switch (Platform.OS) {
|
||||||
case 'ios':
|
case 'ios':
|
||||||
@ -54,7 +65,8 @@ const TabMePush: React.FC = () => {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
|
||||||
|
if (serverKeyAvailable) {
|
||||||
checkPush()
|
checkPush()
|
||||||
|
|
||||||
if (isDevelopment) {
|
if (isDevelopment) {
|
||||||
@ -62,12 +74,13 @@ const TabMePush: React.FC = () => {
|
|||||||
} else {
|
} else {
|
||||||
setPushAvailable(!!expoToken)
|
setPushAvailable(!!expoToken)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const subscription = AppState.addEventListener('change', checkPush)
|
const subscription = AppState.addEventListener('change', checkPush)
|
||||||
return () => {
|
return () => {
|
||||||
subscription.remove()
|
subscription.remove()
|
||||||
}
|
}
|
||||||
}, [])
|
}, [serverKeyAvailable])
|
||||||
|
|
||||||
const alerts = () =>
|
const alerts = () =>
|
||||||
instancePush?.alerts
|
instancePush?.alerts
|
||||||
@ -120,6 +133,8 @@ const TabMePush: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
|
{!!serverKeyAvailable ? (
|
||||||
|
<>
|
||||||
{!!pushAvailable ? (
|
{!!pushAvailable ? (
|
||||||
<>
|
<>
|
||||||
{pushEnabled === false ? (
|
{pushEnabled === false ? (
|
||||||
@ -163,7 +178,9 @@ const TabMePush: React.FC = () => {
|
|||||||
loading={instancePush?.decode}
|
loading={instancePush?.decode}
|
||||||
switchDisabled={!pushEnabled || !instancePush?.global}
|
switchDisabled={!pushEnabled || !instancePush?.global}
|
||||||
switchValue={instancePush?.decode}
|
switchValue={instancePush?.decode}
|
||||||
switchOnValueChange={() => dispatch(updateInstancePushDecode(!instancePush?.decode))}
|
switchOnValueChange={() =>
|
||||||
|
dispatch(updateInstancePushDecode(!instancePush?.decode))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<MenuRow
|
<MenuRow
|
||||||
title={t('me.push.howitworks')}
|
title={t('me.push.howitworks')}
|
||||||
@ -201,6 +218,39 @@ const TabMePush: React.FC = () => {
|
|||||||
</CustomText>
|
</CustomText>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
minHeight: '100%',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
|
||||||
|
<CustomText
|
||||||
|
fontStyle='M'
|
||||||
|
style={{
|
||||||
|
color: colors.primaryDefault,
|
||||||
|
textAlign: 'center',
|
||||||
|
marginTop: StyleConstants.Spacing.S
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('me.push.missingServerKey.message')}
|
||||||
|
</CustomText>
|
||||||
|
<CustomText
|
||||||
|
fontStyle='S'
|
||||||
|
style={{
|
||||||
|
color: colors.primaryDefault,
|
||||||
|
textAlign: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('me.push.missingServerKey.description')}
|
||||||
|
</CustomText>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,41 @@
|
|||||||
import apiGeneral from '@api/general'
|
import apiGeneral from '@api/general'
|
||||||
|
import apiInstance from '@api/instance'
|
||||||
import { AxiosError } from 'axios'
|
import { AxiosError } from 'axios'
|
||||||
import * as AuthSession from 'expo-auth-session'
|
import * as AuthSession from 'expo-auth-session'
|
||||||
import { QueryFunctionContext, useQuery, UseQueryOptions } from 'react-query'
|
import {
|
||||||
|
QueryFunctionContext,
|
||||||
|
useMutation,
|
||||||
|
UseMutationOptions,
|
||||||
|
useQuery,
|
||||||
|
UseQueryOptions
|
||||||
|
} from 'react-query'
|
||||||
|
|
||||||
export type QueryKeyApps = ['Apps', { domain?: string }]
|
export type QueryKeyApps = ['Apps']
|
||||||
|
|
||||||
const queryFunction = ({ queryKey }: QueryFunctionContext<QueryKeyApps>) => {
|
const queryFunctionApps = async ({ queryKey }: QueryFunctionContext<QueryKeyApps>) => {
|
||||||
const redirectUri = AuthSession.makeRedirectUri({
|
const res = await apiInstance<Mastodon.Apps>({
|
||||||
|
method: 'get',
|
||||||
|
url: 'apps/verify_credentials'
|
||||||
|
})
|
||||||
|
return res.body
|
||||||
|
}
|
||||||
|
|
||||||
|
const useAppsQuery = (
|
||||||
|
params: {
|
||||||
|
options?: UseQueryOptions<Mastodon.Apps, AxiosError>
|
||||||
|
} | void
|
||||||
|
) => {
|
||||||
|
const queryKey: QueryKeyApps = ['Apps']
|
||||||
|
return useQuery(queryKey, queryFunctionApps, params?.options)
|
||||||
|
}
|
||||||
|
|
||||||
|
type MutationVarsApps = { domain: string }
|
||||||
|
|
||||||
|
export const redirectUri = AuthSession.makeRedirectUri({
|
||||||
native: 'tooot://instance-auth',
|
native: 'tooot://instance-auth',
|
||||||
useProxy: false
|
useProxy: false
|
||||||
})
|
})
|
||||||
|
const mutationFunctionApps = async ({ domain }: MutationVarsApps) => {
|
||||||
const { domain } = queryKey[1]
|
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('client_name', 'tooot')
|
formData.append('client_name', 'tooot')
|
||||||
formData.append('website', 'https://tooot.app')
|
formData.append('website', 'https://tooot.app')
|
||||||
@ -21,20 +44,16 @@ const queryFunction = ({ queryKey }: QueryFunctionContext<QueryKeyApps>) => {
|
|||||||
|
|
||||||
return apiGeneral<Mastodon.Apps>({
|
return apiGeneral<Mastodon.Apps>({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
domain: domain || '',
|
domain: domain,
|
||||||
url: `api/v1/apps`,
|
url: `api/v1/apps`,
|
||||||
body: formData
|
body: formData
|
||||||
}).then(res => res.body)
|
}).then(res => res.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
const useAppsQuery = ({
|
const useAppsMutation = (
|
||||||
options,
|
options: UseMutationOptions<Mastodon.Apps, AxiosError, MutationVarsApps>
|
||||||
...queryKeyParams
|
) => {
|
||||||
}: QueryKeyApps[1] & {
|
return useMutation(mutationFunctionApps, options)
|
||||||
options?: UseQueryOptions<Mastodon.Apps, AxiosError>
|
|
||||||
}) => {
|
|
||||||
const queryKey: QueryKeyApps = ['Apps', { ...queryKeyParams }]
|
|
||||||
return useQuery(queryKey, queryFunction, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { useAppsQuery }
|
export { useAppsQuery, useAppsMutation }
|
||||||
|
Loading…
Reference in New Issue
Block a user