diff --git a/src/screens/Compose/EditAttachment.tsx b/src/screens/Compose/EditAttachment.tsx index 6e10574a..c7a9b096 100644 --- a/src/screens/Compose/EditAttachment.tsx +++ b/src/screens/Compose/EditAttachment.tsx @@ -48,22 +48,13 @@ const ComposeEditAttachment: React.FC< } setIsSubmitting(true) - const formData = new FormData() - if (theAttachment.description) { - formData.append('description', theAttachment.description) - } - if (theAttachment.meta?.focus?.x !== 0 || theAttachment.meta.focus.y !== 0) { - formData.append( - 'focus', - `${theAttachment.meta?.focus?.x || 0},${-theAttachment.meta?.focus?.y || 0}` - ) - } + const body = { description: theAttachment.description } theAttachment?.id && apiInstance({ method: 'put', url: `media/${theAttachment.id}`, - body: formData + body }) .then(() => { haptics('Success') diff --git a/src/screens/Tabs/Me/Push.tsx b/src/screens/Tabs/Me/Push.tsx index 158c0ad1..bdb0d2a3 100644 --- a/src/screens/Tabs/Me/Push.tsx +++ b/src/screens/Tabs/Me/Push.tsx @@ -75,19 +75,21 @@ const TabMePush: React.FC = () => { { const alerts = { ...push?.alerts, [alert]: !push?.alerts[alert] } - const formData = new FormData() + const body: { data: { alerts: { [key: string]: boolean } } } = { + data: { alerts: {} } + } for (const [key, value] of Object.entries(alerts)) { - formData.append(`data[alerts][${key}]`, value.toString()) + body.data.alerts[key] = value } await apiInstance({ method: 'put', url: 'push/subscription', - body: formData + body }) setAccountStorage([{ key: 'push', value: { ...push, alerts } }]) @@ -103,19 +105,21 @@ const TabMePush: React.FC = () => { { const alerts = { ...push?.alerts, [type]: !push?.alerts[type] } - const formData = new FormData() + const body: { data: { alerts: { [key: string]: boolean } } } = { + data: { alerts: {} } + } for (const [key, value] of Object.entries(alerts)) { - formData.append(`data[alerts][${key}]`, value.toString()) + body.data.alerts[key] = value } await apiInstance({ method: 'put', url: 'push/subscription', - body: formData + body }) setAccountStorage([{ key: 'push', value: { ...push, alerts } }]) @@ -190,21 +194,25 @@ const TabMePush: React.FC = () => { const endpoint = `https://${TOOOT_API_DOMAIN}/push/send/${pushPath}/${randomPath}` - const formData = new FormData() - formData.append('subscription[endpoint]', endpoint) - formData.append( - 'subscription[keys][p256dh]', - 'BMn2PLpZrMefG981elzG6SB1EY9gU7QZwmtZ/a/J2vUeWG+zXgeskMPwHh4T/bxsD4l7/8QT94F57CbZqYRRfJo=' - ) - formData.append('subscription[keys][auth]', authKey) + const body: { subscription: any; alerts: { [key: string]: boolean } } = { + subscription: { + endpoint, + keys: { + p256dh: + 'BMn2PLpZrMefG981elzG6SB1EY9gU7QZwmtZ/a/J2vUeWG+zXgeskMPwHh4T/bxsD4l7/8QT94F57CbZqYRRfJo=', + auth: authKey + } + }, + alerts: {} + } for (const [key, value] of Object.entries(push.alerts)) { - formData.append(`data[alerts][${key}]`, value.toString()) + body.alerts[key] = value } const res = await apiInstance({ method: 'post', url: 'push/subscription', - body: formData + body }) if (!res.body.server_key?.length) { diff --git a/src/screens/Tabs/Shared/Report.tsx b/src/screens/Tabs/Shared/Report.tsx index 30438fbb..78c7f1ed 100644 --- a/src/screens/Tabs/Shared/Report.tsx +++ b/src/screens/Tabs/Shared/Report.tsx @@ -53,22 +53,29 @@ const TabSharedReport: React.FC> content={t('screenTabs:shared.report.report')} destructive onPress={async () => { - const body = new FormData() + const body: { + status_ids?: string[] + account_id?: string + comment?: string + forward?: boolean + category?: string + rule_ids?: string[] + } = {} if (status) { if (status._remote) { const fetchedStatus = await searchLocalStatus(status.uri) if (fetchedStatus) { - body.append('status_ids[]', fetchedStatus.id) + body.status_ids = [fetchedStatus.id] } } else { - body.append('status_ids[]', status.id) + body.status_ids = [status.id] } } - body.append('account_id', account.id) - comment.length && body.append('comment', comment) - body.append('forward', forward.toString()) - body.append('category', categories.find(category => category.selected)?.type || 'other') - rules.filter(rule => rule.selected).forEach(rule => body.append('rule_ids[]', rule.id)) + body.account_id = account.id + comment.length && (body.comment = comment) + body.forward = forward + body.category = categories.find(category => category.selected)?.type || 'other' + body.rule_ids = rules.filter(rule => rule.selected).map(rule => rule.id) apiInstance({ method: 'post', url: 'reports', body }) .then(() => { diff --git a/src/utils/api/general.ts b/src/utils/api/general.ts index 6994c42b..b1ef9780 100644 --- a/src/utils/api/general.ts +++ b/src/utils/api/general.ts @@ -1,5 +1,5 @@ import axios from 'axios' -import { ctx, handleError, PagedResponse, parseHeaderLinks, processBody, userAgent } from './helpers' +import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers' export type Params = { method: 'get' | 'post' | 'put' | 'delete' @@ -41,9 +41,10 @@ const apiGeneral = async ({ headers: { Accept: 'application/json', ...userAgent, - ...headers + ...headers, + ...(body && body instanceof FormData && { 'Content-Type': 'multipart/form-data' }) }, - data: processBody(body) + data: body }) .then(response => ({ body: response.data, links: parseHeaderLinks(response.headers.link) })) .catch(handleError()) diff --git a/src/utils/api/helpers/index.ts b/src/utils/api/helpers/index.ts index 596410ae..8edcb267 100644 --- a/src/utils/api/helpers/index.ts +++ b/src/utils/api/helpers/index.ts @@ -102,20 +102,4 @@ export type PagedResponse = { } } -export const processBody = (body?: FormData | Object): FormData | Object | undefined => { - if (!body) return - - if (body instanceof FormData) { - if ((body as FormData & { _parts: [][] })._parts?.length) { - return body - } else { - return - } - } - - if (Object.keys(body).length) { - return body - } -} - export { ctx, handleError, userAgent } diff --git a/src/utils/api/instance.ts b/src/utils/api/instance.ts index f66c729d..ea435c4d 100644 --- a/src/utils/api/instance.ts +++ b/src/utils/api/instance.ts @@ -1,14 +1,7 @@ import { getAccountDetails } from '@utils/storage/actions' import { StorageGlobal } from '@utils/storage/global' import axios, { AxiosRequestConfig } from 'axios' -import { - ctx, - handleError, - PagedResponse, - parseHeaderLinks, - processBody, - userAgent -} from './helpers' +import { ctx, handleError, PagedResponse, parseHeaderLinks, userAgent } from './helpers' export type Params = { account?: StorageGlobal['account.active'] @@ -50,7 +43,7 @@ const apiInstance = async ({ method + ctx.blue(' -> ') + `/${url}` + (params ? ctx.blue(' -> ') : ''), params ? params : '' ) - + console.log('body', body) return axios({ timeout: method === 'post' ? 1000 * 60 : 1000 * 15, method, @@ -61,9 +54,10 @@ const apiInstance = async ({ Accept: 'application/json', ...userAgent, ...headers, - Authorization: `Bearer ${accountDetails['auth.token']}` + Authorization: `Bearer ${accountDetails['auth.token']}`, + ...(body && body instanceof FormData && { 'Content-Type': 'multipart/form-data' }) }, - data: processBody(body), + data: body, ...extras }) .then(response => ({ body: response.data, links: parseHeaderLinks(response.headers.link) })) diff --git a/src/utils/api/tooot.ts b/src/utils/api/tooot.ts index b50e2efb..a0dee195 100644 --- a/src/utils/api/tooot.ts +++ b/src/utils/api/tooot.ts @@ -1,6 +1,6 @@ import { mapEnvironment } from '@utils/helpers/checkEnvironment' import axios from 'axios' -import { ctx, handleError, processBody, userAgent } from './helpers' +import { ctx, handleError, userAgent } from './helpers' export type Params = { method: 'get' | 'post' | 'put' | 'delete' @@ -46,7 +46,7 @@ const apiTooot = async ({ ...userAgent, ...headers }, - data: processBody(body) + data: body }) .then(response => { return Promise.resolve({ diff --git a/src/utils/queryHooks/lists.ts b/src/utils/queryHooks/lists.ts index c38da5e4..50443d01 100644 --- a/src/utils/queryHooks/lists.ts +++ b/src/utils/queryHooks/lists.ts @@ -44,11 +44,11 @@ type MutationVarsLists = } const mutationFunction = async (params: MutationVarsLists) => { - const body = new FormData() + const body: { title?: string; replies_policy?: string } = {} switch (params.type) { case 'add': - body.append('title', params.payload.title) - body.append('replies_policy', params.payload.replies_policy) + body.title = params.payload.title + body.replies_policy = params.payload.replies_policy return apiInstance({ method: 'post', @@ -56,8 +56,8 @@ const mutationFunction = async (params: MutationVarsLists) => { body }).then(res => res.body) case 'edit': - body.append('title', params.payload.title) - body.append('replies_policy', params.payload.replies_policy) + body.title = params.payload.title + body.replies_policy = params.payload.replies_policy return apiInstance({ method: 'put', @@ -117,9 +117,9 @@ type AccountsMutationVarsLists = { } const accountsMutationFunction = async (params: AccountsMutationVarsLists) => { - const body = new FormData() + const body: { account_ids?: string[] } = {} for (const account of params.payload.accounts) { - body.append('account_ids[]', account) + body.account_ids = [account] } return apiInstance<{}>({ method: params.type === 'add' ? 'post' : 'delete', diff --git a/src/utils/queryHooks/profile.ts b/src/utils/queryHooks/profile.ts index 20225bd6..cb798f80 100644 --- a/src/utils/queryHooks/profile.ts +++ b/src/utils/queryHooks/profile.ts @@ -64,16 +64,19 @@ type MutationVarsProfile = MutationVarsProfileBase & { const mutationFunction = async ({ type, data }: MutationVarsProfile) => { const formData = new FormData() + if (type === 'fields_attributes') { - if (!data.length) { - formData.append('fields_attributes[]', '') - } else { - const tempData = data as { name: string; value: string }[] - tempData.forEach((d, index) => { - formData.append(`fields_attributes[${index}][name]`, d.name) - formData.append(`fields_attributes[${index}][value]`, d.value) - }) + const body: { fields_attributes: { name: string; value: string }[] } = { + fields_attributes: [] } + if (data.length) { + body.fields_attributes = data as { name: string; value: string }[] + } + return apiInstance({ + method: 'patch', + url: 'accounts/update_credentials', + body + }) } else if (type === 'avatar' || type === 'header') { formData.append(type, { uri: data, @@ -84,7 +87,6 @@ const mutationFunction = async ({ type, data }: MutationVarsProfile) => { // @ts-ignore formData.append(type, data) } - return apiInstance({ method: 'patch', url: 'accounts/update_credentials', diff --git a/src/utils/queryHooks/relationship.ts b/src/utils/queryHooks/relationship.ts index 14798cde..4c811ce3 100644 --- a/src/utils/queryHooks/relationship.ts +++ b/src/utils/queryHooks/relationship.ts @@ -74,16 +74,14 @@ const mutationFunction = async (params: MutationVarsRelationship) => { url: `follow_requests/${params.id}/${params.payload.action}` }).then(res => res.body) case 'outgoing': - const formData = new FormData() - typeof params.payload.reblogs === 'boolean' && - formData.append('reblogs', params.payload.reblogs.toString()) - typeof params.payload.notify === 'boolean' && - formData.append('notify', params.payload.notify.toString()) + const body: { reblogs?: boolean; notify?: boolean } = {} + typeof params.payload.reblogs === 'boolean' && (body.reblogs = params.payload.reblogs) + typeof params.payload.notify === 'boolean' && (body.notify = params.payload.notify) return apiInstance({ method: 'post', url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${params.payload.action}`, - body: formData + body }).then(res => res.body) } } diff --git a/src/utils/queryHooks/timeline.ts b/src/utils/queryHooks/timeline.ts index 4792b6f4..c4dfb5a4 100644 --- a/src/utils/queryHooks/timeline.ts +++ b/src/utils/queryHooks/timeline.ts @@ -355,21 +355,19 @@ const mutationFunction = async (params: MutationVarsTimeline) => { case 'updateStatusProperty': switch (params.payload.type) { case 'poll': - const formData = new FormData() - params.payload.action === 'vote' && - params.payload.options?.forEach((option, index) => { - if (option) { - formData.append('choices[]', index.toString()) - } - }) - return apiInstance({ method: params.payload.action === 'vote' ? 'post' : 'get', url: params.payload.action === 'vote' ? `polls/${params.status.poll?.id}/votes` : `polls/${params.status.poll?.id}`, - ...(params.payload.action === 'vote' && { body: formData }) + ...(params.payload.action === 'vote' && { + body: { + choices: params.payload.options + .map((option, index) => (option ? index.toString() : undefined)) + .filter(o => o) + } + }) }) default: let tootId = params.status.id @@ -381,16 +379,14 @@ const mutationFunction = async (params: MutationVarsTimeline) => { return Promise.reject('Fetching for remote toot failed') } } - const body = new FormData() - if (params.payload.type === 'reblogged') { - body.append('visibility', params.payload.visibility) - } return apiInstance({ method: 'post', url: `statuses/${tootId}/${params.payload.to ? '' : 'un'}${ MapPropertyToUrl[params.payload.type] }`, - ...(params.payload.type === 'reblogged' && { body }) + ...(params.payload.type === 'reblogged' && { + body: { visibility: params.payload.visibility } + }) }) } case 'updateAccountProperty': diff --git a/src/utils/storage/actions.ts b/src/utils/storage/actions.ts index d25dd945..fbdf29ea 100644 --- a/src/utils/storage/actions.ts +++ b/src/utils/storage/actions.ts @@ -291,11 +291,12 @@ export const removeAccount = async (account: string, warning: boolean = true) => revokeDetails.client_secret && revokeDetails.token ) { - const body = new FormData() - body.append('client_id', revokeDetails.client_id) - body.append('client_secret', revokeDetails.client_secret) - body.append('token', revokeDetails.token) - apiGeneral({ method: 'post', domain: revokeDetails.domain, url: '/oauth/revoke', body }) + apiGeneral({ + method: 'post', + domain: revokeDetails.domain, + url: '/oauth/revoke', + body: revokeDetails + }) } const currAccounts: NonNullable =