tooot/src/screens/Me/Root/Login.tsx

169 lines
4.5 KiB
TypeScript
Raw Normal View History

import React, { useCallback, useEffect, useState } from 'react'
2020-12-03 22:03:06 +01:00
import { StyleSheet, Text, TextInput, View } from 'react-native'
2020-11-20 01:41:46 +01:00
import { useQuery } from 'react-query'
import { debounce } from 'lodash'
2020-11-21 13:19:05 +01:00
import { instanceFetch } from 'src/utils/fetches/instanceFetch'
2020-11-20 01:41:46 +01:00
import client from 'src/api/client'
import * as AuthSession from 'expo-auth-session'
import { useDispatch } from 'react-redux'
2020-11-21 13:19:05 +01:00
import { updateLocal } from 'src/utils/slices/instancesSlice'
import { useNavigation } from '@react-navigation/native'
2020-11-24 00:18:47 +01:00
import { useTheme } from 'src/utils/styles/ThemeManager'
2020-11-30 00:24:53 +01:00
import { useTranslation } from 'react-i18next'
import { StyleConstants } from 'src/utils/styles/constants'
2020-12-03 22:03:06 +01:00
import Button from 'src/components/Button'
2020-11-20 01:41:46 +01:00
2020-11-21 13:19:05 +01:00
const Login: React.FC = () => {
2020-11-30 00:24:53 +01:00
const { t } = useTranslation('meRoot')
2020-11-24 00:18:47 +01:00
const { theme } = useTheme()
const navigation = useNavigation()
const dispatch = useDispatch()
2020-11-20 01:41:46 +01:00
const [instance, setInstance] = useState('')
const [applicationData, setApplicationData] = useState<{
clientId: string
clientSecret: string
}>()
2020-11-20 01:41:46 +01:00
const { isSuccess, refetch, data } = useQuery(
['Instance', { instance }],
instanceFetch,
{
enabled: false,
retry: false
}
)
const onChangeText = useCallback(
debounce(
text => {
setInstance(text)
setApplicationData(undefined)
2020-11-20 01:41:46 +01:00
refetch()
},
1000,
{
leading: true
}
),
[]
)
const createApplication = async () => {
if (applicationData) {
return Promise.resolve()
}
2020-11-20 01:41:46 +01:00
const formData = new FormData()
formData.append('client_name', 'test_dudu')
formData.append('redirect_uris', 'exp://127.0.0.1:19000')
formData.append('scopes', 'read write follow push')
const res = await client({
method: 'post',
instance: 'remote',
instanceDomain: instance,
url: `apps`,
2020-11-20 01:41:46 +01:00
body: formData
})
if (res.body?.client_id.length > 0) {
setApplicationData({
clientId: res.body.client_id,
clientSecret: res.body.client_secret
})
return Promise.resolve()
2020-11-20 01:41:46 +01:00
} else {
return Promise.reject()
}
}
const [request, response, promptAsync] = AuthSession.useAuthRequest(
{
clientId: applicationData?.clientId!,
clientSecret: applicationData?.clientSecret,
scopes: ['read', 'write', 'follow', 'push'],
redirectUri: 'exp://127.0.0.1:19000'
},
{
authorizationEndpoint: `https://${instance}/oauth/authorize`
2020-11-20 01:41:46 +01:00
}
)
useEffect(() => {
;(async () => {
if (request?.clientId) {
await promptAsync()
}
})()
}, [request])
useEffect(() => {
;(async () => {
if (response?.type === 'success') {
const { accessToken } = await AuthSession.exchangeCodeAsync(
{
clientId: applicationData?.clientId!,
clientSecret: applicationData?.clientSecret,
scopes: ['read', 'write', 'follow', 'push'],
redirectUri: 'exp://127.0.0.1:19000',
code: response.params.code,
extraParams: {
grant_type: 'authorization_code'
}
},
{
tokenEndpoint: `https://${instance}/oauth/token`
}
)
dispatch(updateLocal({ url: instance, token: accessToken }))
2020-11-24 00:18:47 +01:00
navigation.navigate('Screen-Local-Root')
}
})()
}, [response])
2020-11-20 01:41:46 +01:00
return (
2020-11-24 00:18:47 +01:00
<View style={styles.base}>
2020-11-20 01:41:46 +01:00
<TextInput
2020-11-24 00:18:47 +01:00
style={{
height: 50,
color: theme.primary,
borderColor: theme.border,
borderWidth: 1,
2020-11-30 00:24:53 +01:00
padding: StyleConstants.Spacing.M
2020-11-24 00:18:47 +01:00
}}
2020-11-20 01:41:46 +01:00
onChangeText={onChangeText}
autoCapitalize='none'
autoCorrect={false}
2020-11-24 00:18:47 +01:00
autoFocus
2020-11-20 01:41:46 +01:00
clearButtonMode='unless-editing'
keyboardType='url'
textContentType='URL'
2020-11-24 00:18:47 +01:00
onSubmitEditing={async () =>
isSuccess && data && data.uri && (await createApplication())
}
2020-11-30 00:24:53 +01:00
placeholder={t('content.login.server.placeholder')}
2020-11-24 00:18:47 +01:00
placeholderTextColor={theme.secondary}
returnKeyType='go'
2020-11-20 01:41:46 +01:00
/>
<Button
onPress={async () => await createApplication()}
2020-12-03 22:03:06 +01:00
text={t('content.login.button')}
disabled={!data?.uri}
2020-11-20 01:41:46 +01:00
/>
{isSuccess && data && data.uri && (
<View>
2020-11-24 00:18:47 +01:00
<Text style={{ color: theme.primary }}>{data.title}</Text>
2020-11-20 01:41:46 +01:00
</View>
)}
</View>
)
}
2020-11-24 00:18:47 +01:00
const styles = StyleSheet.create({
base: {
2020-11-30 00:24:53 +01:00
padding: StyleConstants.Spacing.Global.PagePadding
2020-11-24 00:18:47 +01:00
}
})
2020-11-21 13:19:05 +01:00
export default Login