2020-11-21 00:40:55 +01:00
|
|
|
import React, { useCallback, useEffect, useState } from 'react'
|
2020-11-24 00:18:47 +01:00
|
|
|
import { Button, 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'
|
2020-11-21 00:40:55 +01:00
|
|
|
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'
|
2020-11-21 00:40:55 +01:00
|
|
|
import { useNavigation } from '@react-navigation/native'
|
2020-11-24 00:18:47 +01:00
|
|
|
import { useTheme } from 'src/utils/styles/ThemeManager'
|
|
|
|
|
|
|
|
import constants from 'src/utils/styles/constants'
|
2020-11-20 01:41:46 +01:00
|
|
|
|
2020-11-21 13:19:05 +01:00
|
|
|
const Login: React.FC = () => {
|
2020-11-24 00:18:47 +01:00
|
|
|
const { theme } = useTheme()
|
2020-11-21 00:40:55 +01:00
|
|
|
const navigation = useNavigation()
|
|
|
|
const dispatch = useDispatch()
|
2020-11-20 01:41:46 +01:00
|
|
|
const [instance, setInstance] = useState('')
|
2020-11-21 00:40:55 +01:00
|
|
|
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)
|
2020-11-21 00:40:55 +01:00
|
|
|
setApplicationData(undefined)
|
2020-11-20 01:41:46 +01:00
|
|
|
refetch()
|
|
|
|
},
|
|
|
|
1000,
|
|
|
|
{
|
|
|
|
leading: true
|
|
|
|
}
|
|
|
|
),
|
|
|
|
[]
|
|
|
|
)
|
|
|
|
|
2020-11-21 00:40:55 +01:00
|
|
|
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',
|
|
|
|
instanceUrl: instance,
|
|
|
|
endpoint: `apps`,
|
|
|
|
body: formData
|
|
|
|
})
|
|
|
|
if (res.body?.client_id.length > 0) {
|
2020-11-21 00:40:55 +01:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 00:40:55 +01:00
|
|
|
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
|
|
|
}
|
2020-11-21 00:40:55 +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')
|
2020-11-21 00:40:55 +01:00
|
|
|
}
|
|
|
|
})()
|
|
|
|
}, [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,
|
|
|
|
padding: constants.SPACING_M
|
|
|
|
}}
|
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-20 01:41:46 +01:00
|
|
|
placeholder='输入服务器'
|
2020-11-24 00:18:47 +01:00
|
|
|
placeholderTextColor={theme.secondary}
|
|
|
|
returnKeyType='go'
|
2020-11-20 01:41:46 +01:00
|
|
|
/>
|
|
|
|
<Button
|
|
|
|
title='登录'
|
|
|
|
disabled={!data?.uri}
|
2020-11-21 00:40:55 +01:00
|
|
|
onPress={async () => await createApplication()}
|
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: {
|
|
|
|
padding: constants.GLOBAL_PAGE_PADDING
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-11-21 13:19:05 +01:00
|
|
|
export default Login
|