mirror of
https://github.com/tooot-app/app
synced 2025-02-01 19:16:56 +01:00
Try out new api services
This commit is contained in:
parent
3d481624ad
commit
6c6dc0ce6a
@ -72,6 +72,7 @@
|
|||||||
"react-i18next": "11.14.3",
|
"react-i18next": "11.14.3",
|
||||||
"react-native": "0.66.3",
|
"react-native": "0.66.3",
|
||||||
"react-native-animated-spinkit": "1.5.2",
|
"react-native-animated-spinkit": "1.5.2",
|
||||||
|
"react-native-base64": "^0.2.1",
|
||||||
"react-native-blurhash": "1.1.5",
|
"react-native-blurhash": "1.1.5",
|
||||||
"react-native-fast-image": "8.5.11",
|
"react-native-fast-image": "8.5.11",
|
||||||
"react-native-feather": "1.1.2",
|
"react-native-feather": "1.1.2",
|
||||||
@ -103,6 +104,7 @@
|
|||||||
"@types/react": "17.0.37",
|
"@types/react": "17.0.37",
|
||||||
"@types/react-dom": "17.0.11",
|
"@types/react-dom": "17.0.11",
|
||||||
"@types/react-native": "0.66.6",
|
"@types/react-native": "0.66.6",
|
||||||
|
"@types/react-native-base64": "^0.2.0",
|
||||||
"@types/react-redux": "7.1.20",
|
"@types/react-redux": "7.1.20",
|
||||||
"@types/react-timeago": "4.1.3",
|
"@types/react-timeago": "4.1.3",
|
||||||
"@types/valid-url": "1.0.3",
|
"@types/valid-url": "1.0.3",
|
||||||
|
@ -6,8 +6,7 @@ import * as Sentry from 'sentry-expo'
|
|||||||
const ctx = new chalk.Instance({ level: 3 })
|
const ctx = new chalk.Instance({ level: 3 })
|
||||||
|
|
||||||
export type Params = {
|
export type Params = {
|
||||||
service: 'push' | 'translate'
|
method: 'get' | 'post' | 'put' | 'delete'
|
||||||
method: 'get' | 'post'
|
|
||||||
url: string
|
url: string
|
||||||
params?: {
|
params?: {
|
||||||
[key: string]: string | number | boolean | string[] | number[] | boolean[]
|
[key: string]: string | number | boolean | string[] | number[] | boolean[]
|
||||||
@ -17,10 +16,9 @@ export type Params = {
|
|||||||
sentry?: boolean
|
sentry?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOMAIN = __DEV__ ? 'testapi.tooot.app' : 'api.tooot.app'
|
export const TOOOT_API_DOMAIN = __DEV__ ? 'testapi.tooot.app' : 'testapi.tooot.app'
|
||||||
|
|
||||||
const apiTooot = async <T = unknown>({
|
const apiTooot = async <T = unknown>({
|
||||||
service,
|
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
params,
|
params,
|
||||||
@ -28,8 +26,6 @@ const apiTooot = async <T = unknown>({
|
|||||||
body,
|
body,
|
||||||
sentry = false
|
sentry = false
|
||||||
}: Params): Promise<{ body: T }> => {
|
}: Params): Promise<{ body: T }> => {
|
||||||
const key = Constants.manifest?.extra?.toootApiKey
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
ctx.bgGreen.bold(' API tooot ') +
|
ctx.bgGreen.bold(' API tooot ') +
|
||||||
' ' +
|
' ' +
|
||||||
@ -43,11 +39,10 @@ const apiTooot = async <T = unknown>({
|
|||||||
return axios({
|
return axios({
|
||||||
timeout: method === 'post' ? 1000 * 60 : 1000 * 15,
|
timeout: method === 'post' ? 1000 * 60 : 1000 * 15,
|
||||||
method,
|
method,
|
||||||
baseURL: `https://${DOMAIN}/`,
|
baseURL: `https://${TOOOT_API_DOMAIN}/`,
|
||||||
url: `${service}/${url}`,
|
url: `${url}`,
|
||||||
params,
|
params,
|
||||||
headers: {
|
headers: {
|
||||||
...(key && { 'x-tooot-key': key }),
|
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'User-Agent': `tooot/${Constants.manifest?.version}`,
|
'User-Agent': `tooot/${Constants.manifest?.version}`,
|
||||||
Accept: '*/*',
|
Accept: '*/*',
|
||||||
|
@ -76,7 +76,7 @@ const pushUseConnect = ({ mode, t, instances, dispatch }: Params) => {
|
|||||||
|
|
||||||
const pushEnabled = instances.filter(instance => instance.push.global.value)
|
const pushEnabled = instances.filter(instance => instance.push.global.value)
|
||||||
if (pushEnabled.length) {
|
if (pushEnabled.length) {
|
||||||
connect()
|
// connect()
|
||||||
}
|
}
|
||||||
}, [instances])
|
}, [instances])
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,9 @@ const queryFunction = async ({ queryKey }: { queryKey: QueryKeyTranslate }) => {
|
|||||||
|
|
||||||
const res = await apiTooot<Translations>({
|
const res = await apiTooot<Translations>({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
service: 'translate',
|
url: '/translate',
|
||||||
url: `source/${uriEncoded}/target/${target}`,
|
headers: { original },
|
||||||
headers: { original }
|
body: { source, target, text }
|
||||||
})
|
})
|
||||||
haptics('Light')
|
haptics('Light')
|
||||||
return res.body
|
return res.body
|
||||||
|
@ -1,53 +1,33 @@
|
|||||||
import apiInstance from '@api/instance'
|
import apiInstance from '@api/instance'
|
||||||
import apiTooot from '@api/tooot'
|
import apiTooot, { TOOOT_API_DOMAIN } from '@api/tooot'
|
||||||
import i18n from '@root/i18n/i18n'
|
import i18n from '@root/i18n/i18n'
|
||||||
import { RootState } from '@root/store'
|
import { RootState } from '@root/store'
|
||||||
import { getInstance, Instance } from '@utils/slices/instancesSlice'
|
import { getInstance, Instance } from '@utils/slices/instancesSlice'
|
||||||
import * as Notifications from 'expo-notifications'
|
import * as Notifications from 'expo-notifications'
|
||||||
|
import * as Random from 'expo-random'
|
||||||
import { Platform } from 'react-native'
|
import { Platform } from 'react-native'
|
||||||
|
import base64 from 'react-native-base64'
|
||||||
import androidDefaults from './androidDefaults'
|
import androidDefaults from './androidDefaults'
|
||||||
|
|
||||||
const register1 = async ({
|
const subscribe = async ({
|
||||||
expoToken,
|
expoToken,
|
||||||
instanceUrl,
|
instanceUrl,
|
||||||
accountId,
|
accountId,
|
||||||
accountFull
|
accountFull,
|
||||||
|
serverKey,
|
||||||
|
auth
|
||||||
}: {
|
}: {
|
||||||
expoToken: string
|
expoToken: string
|
||||||
instanceUrl: string
|
instanceUrl: string
|
||||||
accountId: Mastodon.Account['id']
|
accountId: Mastodon.Account['id']
|
||||||
accountFull: string
|
accountFull: string
|
||||||
}) => {
|
serverKey: string
|
||||||
return apiTooot<{
|
auth: string | null
|
||||||
endpoint: string
|
|
||||||
keys: { public: string; private: string; auth: string }
|
|
||||||
}>({
|
|
||||||
method: 'post',
|
|
||||||
service: 'push',
|
|
||||||
url: 'register1',
|
|
||||||
body: { expoToken, instanceUrl, accountId, accountFull },
|
|
||||||
sentry: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const register2 = async ({
|
|
||||||
expoToken,
|
|
||||||
serverKey,
|
|
||||||
instanceUrl,
|
|
||||||
accountId,
|
|
||||||
removeKeys
|
|
||||||
}: {
|
|
||||||
expoToken: string
|
|
||||||
serverKey: Mastodon.PushSubscription['server_key']
|
|
||||||
instanceUrl: string
|
|
||||||
accountId: Mastodon.Account['id']
|
|
||||||
removeKeys: boolean
|
|
||||||
}) => {
|
}) => {
|
||||||
return apiTooot({
|
return apiTooot({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
service: 'push',
|
url: `/push/subscribe/${expoToken}/${instanceUrl}/${accountId}`,
|
||||||
url: 'register2',
|
body: { accountFull, serverKey, auth },
|
||||||
body: { expoToken, instanceUrl, accountId, serverKey, removeKeys },
|
|
||||||
sentry: true
|
sentry: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -55,7 +35,7 @@ const register2 = async ({
|
|||||||
const pushRegister = async (
|
const pushRegister = async (
|
||||||
state: RootState,
|
state: RootState,
|
||||||
expoToken: string
|
expoToken: string
|
||||||
): Promise<Instance['push']['keys']> => {
|
): Promise<Instance['push']['keys']['auth']> => {
|
||||||
const instance = getInstance(state)
|
const instance = getInstance(state)
|
||||||
const instanceUrl = instance?.url
|
const instanceUrl = instance?.url
|
||||||
const instanceUri = instance?.uri
|
const instanceUri = instance?.uri
|
||||||
@ -68,18 +48,18 @@ const pushRegister = async (
|
|||||||
|
|
||||||
const accountId = instanceAccount.id
|
const accountId = instanceAccount.id
|
||||||
const accountFull = `@${instanceAccount.acct}@${instanceUri}`
|
const accountFull = `@${instanceAccount.acct}@${instanceUri}`
|
||||||
const serverRes = await register1({
|
|
||||||
expoToken,
|
const endpoint = `https://${TOOOT_API_DOMAIN}/push/send/${expoToken}/${instanceUrl}/${accountId}`
|
||||||
instanceUrl,
|
const auth = base64.encodeFromByteArray(Random.getRandomBytes(16))
|
||||||
accountId,
|
|
||||||
accountFull
|
|
||||||
})
|
|
||||||
|
|
||||||
const alerts = instancePush.alerts
|
const alerts = instancePush.alerts
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('subscription[endpoint]', serverRes.body.endpoint)
|
formData.append('subscription[endpoint]', endpoint)
|
||||||
formData.append('subscription[keys][p256dh]', serverRes.body.keys.public)
|
formData.append(
|
||||||
formData.append('subscription[keys][auth]', serverRes.body.keys.auth)
|
'subscription[keys][p256dh]',
|
||||||
|
'BO3P7Fe/FxPNijeXayVYViCoLicnnACc+a55wzcS0qIjYU++dtAl2XltgEfU5qPuXrFg5rnxBzbwQG4cAmdNLK4='
|
||||||
|
)
|
||||||
|
formData.append('subscription[keys][auth]', auth)
|
||||||
Object.keys(alerts).map(key =>
|
Object.keys(alerts).map(key =>
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
formData.append(`data[alerts][${key}]`, alerts[key].value.toString())
|
formData.append(`data[alerts][${key}]`, alerts[key].value.toString())
|
||||||
@ -91,12 +71,13 @@ const pushRegister = async (
|
|||||||
body: formData
|
body: formData
|
||||||
})
|
})
|
||||||
|
|
||||||
await register2({
|
await subscribe({
|
||||||
expoToken,
|
expoToken,
|
||||||
serverKey: res.body.server_key,
|
|
||||||
instanceUrl,
|
instanceUrl,
|
||||||
accountId,
|
accountId,
|
||||||
removeKeys: instancePush.decode.value === false
|
accountFull,
|
||||||
|
serverKey: res.body.server_key,
|
||||||
|
auth
|
||||||
})
|
})
|
||||||
|
|
||||||
if (Platform.OS === 'android') {
|
if (Platform.OS === 'android') {
|
||||||
@ -142,7 +123,7 @@ const pushRegister = async (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve(serverRes.body.keys)
|
return Promise.resolve(auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default pushRegister
|
export default pushRegister
|
||||||
|
@ -20,14 +20,8 @@ const pushUnregister = async (state: RootState, expoToken: string) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await apiTooot<{ endpoint: string; publicKey: string; auth: string }>({
|
await apiTooot<{ endpoint: string; publicKey: string; auth: string }>({
|
||||||
method: 'post',
|
method: 'delete',
|
||||||
service: 'push',
|
url: `/push/unsubscribe/${expoToken}/${instance.url}/${instance.account.id}`,
|
||||||
url: 'unregister',
|
|
||||||
body: {
|
|
||||||
expoToken,
|
|
||||||
instanceUrl: instance.url,
|
|
||||||
accountId: instance.account.id
|
|
||||||
},
|
|
||||||
sentry: true
|
sentry: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ export const updateInstancePush = createAsyncThunk(
|
|||||||
async (
|
async (
|
||||||
disable: boolean,
|
disable: boolean,
|
||||||
{ getState }
|
{ getState }
|
||||||
): Promise<Instance['push']['keys'] | undefined> => {
|
): Promise<Instance['push']['keys']['auth'] | undefined> => {
|
||||||
const state = getState() as RootState
|
const state = getState() as RootState
|
||||||
const expoToken = (
|
const expoToken = (
|
||||||
await Notifications.getExpoPushTokenAsync({
|
await Notifications.getExpoPushTokenAsync({
|
||||||
|
@ -26,14 +26,10 @@ export const updateInstancePushDecode = createAsyncThunk(
|
|||||||
).data
|
).data
|
||||||
|
|
||||||
await apiTooot({
|
await apiTooot({
|
||||||
method: 'post',
|
method: 'put',
|
||||||
service: 'push',
|
url: `/push/update-decode/${expoToken}/${instance.url}/${instance.account.id}`,
|
||||||
url: 'update-decode',
|
|
||||||
body: {
|
body: {
|
||||||
expoToken,
|
auth: disable ? null : instance.push.keys.auth
|
||||||
instanceUrl: instance.url,
|
|
||||||
accountId: instance.account.id,
|
|
||||||
...(disable && { keys: instance.push.keys })
|
|
||||||
},
|
},
|
||||||
sentry: true
|
sentry: true
|
||||||
})
|
})
|
||||||
|
@ -39,65 +39,37 @@ export type Instance = {
|
|||||||
poll: boolean
|
poll: boolean
|
||||||
follow_request: boolean
|
follow_request: boolean
|
||||||
}
|
}
|
||||||
push:
|
push: {
|
||||||
| {
|
global: { loading: boolean; value: boolean }
|
||||||
global: { loading: boolean; value: boolean }
|
decode: { loading: boolean; value: boolean }
|
||||||
decode: { loading: boolean; value: true }
|
alerts: {
|
||||||
alerts: {
|
follow: {
|
||||||
follow: {
|
loading: boolean
|
||||||
loading: boolean
|
value: Mastodon.PushSubscription['alerts']['follow']
|
||||||
value: Mastodon.PushSubscription['alerts']['follow']
|
|
||||||
}
|
|
||||||
favourite: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['favourite']
|
|
||||||
}
|
|
||||||
reblog: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['reblog']
|
|
||||||
}
|
|
||||||
mention: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['mention']
|
|
||||||
}
|
|
||||||
poll: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['poll']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keys: {
|
|
||||||
auth: string
|
|
||||||
public: string
|
|
||||||
private: string
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| {
|
favourite: {
|
||||||
global: { loading: boolean; value: boolean }
|
loading: boolean
|
||||||
decode: { loading: boolean; value: false }
|
value: Mastodon.PushSubscription['alerts']['favourite']
|
||||||
alerts: {
|
|
||||||
follow: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['follow']
|
|
||||||
}
|
|
||||||
favourite: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['favourite']
|
|
||||||
}
|
|
||||||
reblog: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['reblog']
|
|
||||||
}
|
|
||||||
mention: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['mention']
|
|
||||||
}
|
|
||||||
poll: {
|
|
||||||
loading: boolean
|
|
||||||
value: Mastodon.PushSubscription['alerts']['poll']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keys: undefined
|
|
||||||
}
|
}
|
||||||
|
reblog: {
|
||||||
|
loading: boolean
|
||||||
|
value: Mastodon.PushSubscription['alerts']['reblog']
|
||||||
|
}
|
||||||
|
mention: {
|
||||||
|
loading: boolean
|
||||||
|
value: Mastodon.PushSubscription['alerts']['mention']
|
||||||
|
}
|
||||||
|
poll: {
|
||||||
|
loading: boolean
|
||||||
|
value: Mastodon.PushSubscription['alerts']['poll']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys: {
|
||||||
|
auth?: string
|
||||||
|
public?: string // legacy
|
||||||
|
private?: string // legacy
|
||||||
|
}
|
||||||
|
}
|
||||||
drafts: ComposeStateDraft[]
|
drafts: ComposeStateDraft[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +245,7 @@ const instancesSlice = createSlice({
|
|||||||
const activeIndex = findInstanceActive(state.instances)
|
const activeIndex = findInstanceActive(state.instances)
|
||||||
state.instances[activeIndex].push.global.loading = false
|
state.instances[activeIndex].push.global.loading = false
|
||||||
state.instances[activeIndex].push.global.value = action.meta.arg
|
state.instances[activeIndex].push.global.value = action.meta.arg
|
||||||
state.instances[activeIndex].push.keys = action.payload
|
state.instances[activeIndex].push.keys = { auth: action.payload }
|
||||||
})
|
})
|
||||||
.addCase(updateInstancePush.rejected, state => {
|
.addCase(updateInstancePush.rejected, state => {
|
||||||
const activeIndex = findInstanceActive(state.instances)
|
const activeIndex = findInstanceActive(state.instances)
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -2190,6 +2190,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-native-base64@^0.2.0":
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-native-base64/-/react-native-base64-0.2.0.tgz#c934e7c3cd549d4613bbfa7929a6845ab07a20af"
|
||||||
|
integrity sha512-5kUtS7Kf8Xl4zEwbqLITEuQReQTby4UOGfnsEeBFJEVmUfT+ygOv/Qmv0v6El0iV1eDhXS+/0i7CGR9d3/nRSA==
|
||||||
|
|
||||||
"@types/react-native@0.66.6":
|
"@types/react-native@0.66.6":
|
||||||
version "0.66.6"
|
version "0.66.6"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.66.6.tgz#08f5b93cca9a50b7d19f353ff2a1ebe1a7c24a79"
|
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.66.6.tgz#08f5b93cca9a50b7d19f353ff2a1ebe1a7c24a79"
|
||||||
@ -6310,6 +6315,11 @@ react-native-animated-spinkit@1.5.2:
|
|||||||
resolved "https://registry.yarnpkg.com/react-native-animated-spinkit/-/react-native-animated-spinkit-1.5.2.tgz#b1c00ecbadf48634273e6a843f8dfbcb7c006186"
|
resolved "https://registry.yarnpkg.com/react-native-animated-spinkit/-/react-native-animated-spinkit-1.5.2.tgz#b1c00ecbadf48634273e6a843f8dfbcb7c006186"
|
||||||
integrity sha512-YCQGR3HzEQvyaAnepiyf/hv88Sta3UIZ2CFZPtFqwu+VbFJfMgjJZniOx4157TuR5AAYajEJP9Fgy+JLIU3jzQ==
|
integrity sha512-YCQGR3HzEQvyaAnepiyf/hv88Sta3UIZ2CFZPtFqwu+VbFJfMgjJZniOx4157TuR5AAYajEJP9Fgy+JLIU3jzQ==
|
||||||
|
|
||||||
|
react-native-base64@^0.2.1:
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-native-base64/-/react-native-base64-0.2.1.tgz#3d0e73a649c4c0129f7b7695d3912456aebae847"
|
||||||
|
integrity sha512-eHgt/MA8y5ZF0aHfZ1aTPcIkDWxza9AaEk4GcpIX+ZYfZ04RcaNahO+527KR7J44/mD3efYfM23O2C1N44ByWA==
|
||||||
|
|
||||||
react-native-blurhash@1.1.5:
|
react-native-blurhash@1.1.5:
|
||||||
version "1.1.5"
|
version "1.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-blurhash/-/react-native-blurhash-1.1.5.tgz#27545afb126347059a3a9324f5c3640a94b1ec53"
|
resolved "https://registry.yarnpkg.com/react-native-blurhash/-/react-native-blurhash-1.1.5.tgz#27545afb126347059a3a9324f5c3640a94b1ec53"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user