diff options
Diffstat (limited to 'src/services/api/api.service.js')
| -rw-r--r-- | src/services/api/api.service.js | 328 |
1 files changed, 222 insertions, 106 deletions
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 05d968f7..083d4f4f 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1,5 +1,9 @@ +import { each, map, concat, last } from 'lodash' +import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js' +import 'whatwg-fetch' +import { RegistrationError, StatusCodeError } from '../errors/errors' + /* eslint-env browser */ -const BG_UPDATE_URL = '/api/qvitter/update_background_image.json' const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' const BLOCKS_IMPORT_URL = '/api/pleroma/blocks_import' @@ -25,7 +29,6 @@ const MFA_DISABLE_OTP_URL = '/api/pleroma/profile/mfa/totp' const MASTODON_LOGIN_URL = '/api/v1/accounts/verify_credentials' const MASTODON_REGISTRATION_URL = '/api/v1/accounts' -const GET_BACKGROUND_HACK = '/api/account/verify_credentials.json' const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites' const MASTODON_USER_NOTIFICATIONS_URL = '/api/v1/notifications' const MASTODON_FAVORITE_URL = id => `/api/v1/statuses/${id}/favourite` @@ -52,19 +55,22 @@ const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block` const MASTODON_UNBLOCK_USER_URL = id => `/api/v1/accounts/${id}/unblock` const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute` const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute` +const MASTODON_SUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/subscribe` +const MASTODON_UNSUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/unsubscribe` const MASTODON_POST_STATUS_URL = '/api/v1/statuses' const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media' +const MASTODON_VOTE_URL = id => `/api/v1/polls/${id}/votes` +const MASTODON_POLL_URL = id => `/api/v1/polls/${id}` const MASTODON_STATUS_FAVORITEDBY_URL = id => `/api/v1/statuses/${id}/favourited_by` const MASTODON_STATUS_REBLOGGEDBY_URL = id => `/api/v1/statuses/${id}/reblogged_by` const MASTODON_PROFILE_UPDATE_URL = '/api/v1/accounts/update_credentials' const MASTODON_REPORT_USER_URL = '/api/v1/reports' const MASTODON_PIN_OWN_STATUS = id => `/api/v1/statuses/${id}/pin` const MASTODON_UNPIN_OWN_STATUS = id => `/api/v1/statuses/${id}/unpin` - -import { each, map, concat, last } from 'lodash' -import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js' -import 'whatwg-fetch' -import { StatusCodeError } from '../errors/errors' +const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute` +const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute` +const MASTODON_SEARCH_2 = `/api/v2/search` +const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' const oldfetch = window.fetch @@ -76,7 +82,7 @@ let fetch = (url, options) => { return oldfetch(fullUrl, options) } -const promisedRequest = ({ method, url, payload, credentials, headers = {} }) => { +const promisedRequest = ({ method, url, params, payload, credentials, headers = {} }) => { const options = { method, headers: { @@ -85,6 +91,11 @@ const promisedRequest = ({ method, url, payload, credentials, headers = {} }) => ...headers } } + if (params) { + url += '?' + Object.entries(params) + .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)) + .join('&') + } if (payload) { options.body = JSON.stringify(payload) } @@ -106,7 +117,7 @@ const promisedRequest = ({ method, url, payload, credentials, headers = {} }) => }) } -const updateNotificationSettings = ({credentials, settings}) => { +const updateNotificationSettings = ({ credentials, settings }) => { const form = new FormData() each(settings, (value, key) => { @@ -117,60 +128,50 @@ const updateNotificationSettings = ({credentials, settings}) => { headers: authHeaders(credentials), method: 'PUT', body: form - }) - .then((data) => data.json()) + }).then((data) => data.json()) } -const updateAvatar = ({credentials, avatar}) => { +const updateAvatar = ({ credentials, avatar }) => { const form = new FormData() form.append('avatar', avatar) return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), method: 'PATCH', body: form - }) - .then((data) => data.json()) - .then((data) => parseUser(data)) + }).then((data) => data.json()) + .then((data) => parseUser(data)) } -const updateBg = ({credentials, params}) => { - let url = BG_UPDATE_URL - +const updateBg = ({ credentials, background }) => { const form = new FormData() - - each(params, (value, key) => { - if (value) { - form.append(key, value) - } - }) - - return fetch(url, { + form.append('pleroma_background_image', background) + return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), - method: 'POST', + method: 'PATCH', body: form - }).then((data) => data.json()) + }) + .then((data) => data.json()) + .then((data) => parseUser(data)) } -const updateBanner = ({credentials, banner}) => { +const updateBanner = ({ credentials, banner }) => { const form = new FormData() form.append('header', banner) return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), method: 'PATCH', body: form - }) - .then((data) => data.json()) - .then((data) => parseUser(data)) + }).then((data) => data.json()) + .then((data) => parseUser(data)) } -const updateProfile = ({credentials, params}) => { +const updateProfile = ({ credentials, params }) => { return promisedRequest({ url: MASTODON_PROFILE_UPDATE_URL, method: 'PATCH', payload: params, credentials - }) - .then((data) => parseUser(data)) + }).then((data) => parseUser(data)) } // Params needed: @@ -200,12 +201,11 @@ const register = ({ params, credentials }) => { ...rest }) }) - .then((response) => [response.ok, response]) - .then(([ok, response]) => { - if (ok) { + .then((response) => { + if (response.ok) { return response.json() } else { - return response.json().then((error) => { throw new Error(error) }) + return response.json().then((error) => { throw new RegistrationError(error) }) } }) } @@ -220,7 +220,7 @@ const authHeaders = (accessToken) => { } } -const externalProfile = ({profileUrl, credentials}) => { +const externalProfile = ({ profileUrl, credentials }) => { let url = `${EXTERNAL_PROFILE_URL}?profileurl=${profileUrl}` return fetch(url, { headers: authHeaders(credentials), @@ -228,7 +228,7 @@ const externalProfile = ({profileUrl, credentials}) => { }).then((data) => data.json()) } -const followUser = ({id, credentials}) => { +const followUser = ({ id, credentials }) => { let url = MASTODON_FOLLOW_URL(id) return fetch(url, { headers: authHeaders(credentials), @@ -236,7 +236,7 @@ const followUser = ({id, credentials}) => { }).then((data) => data.json()) } -const unfollowUser = ({id, credentials}) => { +const unfollowUser = ({ id, credentials }) => { let url = MASTODON_UNFOLLOW_URL(id) return fetch(url, { headers: authHeaders(credentials), @@ -254,21 +254,31 @@ const unpinOwnStatus = ({ id, credentials }) => { .then((data) => parseStatus(data)) } -const blockUser = ({id, credentials}) => { +const muteConversation = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_MUTE_CONVERSATION(id), credentials, method: 'POST' }) + .then((data) => parseStatus(data)) +} + +const unmuteConversation = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_UNMUTE_CONVERSATION(id), credentials, method: 'POST' }) + .then((data) => parseStatus(data)) +} + +const blockUser = ({ id, credentials }) => { return fetch(MASTODON_BLOCK_USER_URL(id), { headers: authHeaders(credentials), method: 'POST' }).then((data) => data.json()) } -const unblockUser = ({id, credentials}) => { +const unblockUser = ({ id, credentials }) => { return fetch(MASTODON_UNBLOCK_USER_URL(id), { headers: authHeaders(credentials), method: 'POST' }).then((data) => data.json()) } -const approveUser = ({id, credentials}) => { +const approveUser = ({ id, credentials }) => { let url = `${APPROVE_USER_URL}?user_id=${id}` return fetch(url, { headers: authHeaders(credentials), @@ -276,7 +286,7 @@ const approveUser = ({id, credentials}) => { }).then((data) => data.json()) } -const denyUser = ({id, credentials}) => { +const denyUser = ({ id, credentials }) => { let url = `${DENY_USER_URL}?user_id=${id}` return fetch(url, { headers: authHeaders(credentials), @@ -284,13 +294,13 @@ const denyUser = ({id, credentials}) => { }).then((data) => data.json()) } -const fetchUser = ({id, credentials}) => { +const fetchUser = ({ id, credentials }) => { let url = `${MASTODON_USER_URL}/${id}` return promisedRequest({ url, credentials }) .then((data) => parseUser(data)) } -const fetchUserRelationship = ({id, credentials}) => { +const fetchUserRelationship = ({ id, credentials }) => { let url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}` return fetch(url, { headers: authHeaders(credentials) }) .then((response) => { @@ -304,7 +314,7 @@ const fetchUserRelationship = ({id, credentials}) => { }) } -const fetchFriends = ({id, maxId, sinceId, limit = 20, credentials}) => { +const fetchFriends = ({ id, maxId, sinceId, limit = 20, credentials }) => { let url = MASTODON_FOLLOWING_URL(id) const args = [ maxId && `max_id=${maxId}`, @@ -318,14 +328,14 @@ const fetchFriends = ({id, maxId, sinceId, limit = 20, credentials}) => { .then((data) => data.map(parseUser)) } -const exportFriends = ({id, credentials}) => { +const exportFriends = ({ id, credentials }) => { return new Promise(async (resolve, reject) => { try { let friends = [] let more = true while (more) { const maxId = friends.length > 0 ? last(friends).id : undefined - const users = await fetchFriends({id, maxId, credentials}) + const users = await fetchFriends({ id, maxId, credentials }) friends = concat(friends, users) if (users.length === 0) { more = false @@ -338,7 +348,7 @@ const exportFriends = ({id, credentials}) => { }) } -const fetchFollowers = ({id, maxId, sinceId, limit = 20, credentials}) => { +const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => { let url = MASTODON_FOLLOWERS_URL(id) const args = [ maxId && `max_id=${maxId}`, @@ -352,13 +362,13 @@ const fetchFollowers = ({id, maxId, sinceId, limit = 20, credentials}) => { .then((data) => data.map(parseUser)) } -const fetchFollowRequests = ({credentials}) => { +const fetchFollowRequests = ({ credentials }) => { const url = FOLLOW_REQUESTS_URL return fetch(url, { headers: authHeaders(credentials) }) .then((data) => data.json()) } -const fetchConversation = ({id, credentials}) => { +const fetchConversation = ({ id, credentials }) => { let urlContext = MASTODON_STATUS_CONTEXT_URL(id) return fetch(urlContext, { headers: authHeaders(credentials) }) .then((data) => { @@ -368,13 +378,13 @@ const fetchConversation = ({id, credentials}) => { throw new Error('Error fetching timeline', data) }) .then((data) => data.json()) - .then(({ancestors, descendants}) => ({ + .then(({ ancestors, descendants }) => ({ ancestors: ancestors.map(parseStatus), descendants: descendants.map(parseStatus) })) } -const fetchStatus = ({id, credentials}) => { +const fetchStatus = ({ id, credentials }) => { let url = MASTODON_STATUS_URL(id) return fetch(url, { headers: authHeaders(credentials) }) .then((data) => { @@ -387,7 +397,7 @@ const fetchStatus = ({id, credentials}) => { .then((data) => parseStatus(data)) } -const tagUser = ({tag, credentials, ...options}) => { +const tagUser = ({ tag, credentials, ...options }) => { const screenName = options.screen_name const form = { nicknames: [screenName], @@ -404,7 +414,7 @@ const tagUser = ({tag, credentials, ...options}) => { }) } -const untagUser = ({tag, credentials, ...options}) => { +const untagUser = ({ tag, credentials, ...options }) => { const screenName = options.screen_name const body = { nicknames: [screenName], @@ -421,7 +431,7 @@ const untagUser = ({tag, credentials, ...options}) => { }) } -const addRight = ({right, credentials, ...user}) => { +const addRight = ({ right, credentials, ...user }) => { const screenName = user.screen_name return fetch(PERMISSION_GROUP_URL(screenName, right), { @@ -431,7 +441,7 @@ const addRight = ({right, credentials, ...user}) => { }) } -const deleteRight = ({right, credentials, ...user}) => { +const deleteRight = ({ right, credentials, ...user }) => { const screenName = user.screen_name return fetch(PERMISSION_GROUP_URL(screenName, right), { @@ -441,7 +451,7 @@ const deleteRight = ({right, credentials, ...user}) => { }) } -const setActivationStatus = ({status, credentials, ...user}) => { +const setActivationStatus = ({ status, credentials, ...user }) => { const screenName = user.screen_name const body = { status: status @@ -457,7 +467,7 @@ const setActivationStatus = ({status, credentials, ...user}) => { }) } -const deleteUser = ({credentials, ...user}) => { +const deleteUser = ({ credentials, ...user }) => { const screenName = user.screen_name const headers = authHeaders(credentials) @@ -467,7 +477,15 @@ const deleteUser = ({credentials, ...user}) => { }) } -const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false, tag = false, withMuted = false}) => { +const fetchTimeline = ({ + timeline, + credentials, + since = false, + until = false, + userId = false, + tag = false, + withMuted = false +}) => { const timelineUrls = { public: MASTODON_PUBLIC_TIMELINE, friends: MASTODON_USER_HOME_TIMELINE_URL, @@ -544,26 +562,6 @@ const verifyCredentials = (user) => { } }) .then((data) => data.error ? data : parseUser(data)) - .then((mastoUser) => { - // REMOVE WHEN BE SUPPORTS background_image - return fetch(GET_BACKGROUND_HACK, { - method: 'POST', - headers: authHeaders(user) - }) - .then((response) => { - if (response.ok) { - return response.json() - } else { - return {} - } - }) - /* eslint-disable camelcase */ - .then(({ background_image }) => ({ - ...mastoUser, - background_image - })) - /* eslint-enable camelcase */ - }) } const favorite = ({ id, credentials }) => { @@ -586,8 +584,19 @@ const unretweet = ({ id, credentials }) => { .then((data) => parseStatus(data)) } -const postStatus = ({credentials, status, spoilerText, visibility, sensitive, mediaIds = [], inReplyToStatusId, contentType}) => { +const postStatus = ({ + credentials, + status, + spoilerText, + visibility, + sensitive, + poll, + mediaIds = [], + inReplyToStatusId, + contentType +}) => { const form = new FormData() + const pollOptions = poll.options || [] form.append('status', status) form.append('source', 'Pleroma FE') @@ -598,6 +607,19 @@ const postStatus = ({credentials, status, spoilerText, visibility, sensitive, me mediaIds.forEach(val => { form.append('media_ids[]', val) }) + if (pollOptions.some(option => option !== '')) { + const normalizedPoll = { + expires_in: poll.expiresIn, + multiple: poll.multiple + } + Object.keys(normalizedPoll).forEach(key => { + form.append(`poll[${key}]`, normalizedPoll[key]) + }) + + pollOptions.forEach(option => { + form.append('poll[options][]', option) + }) + } if (inReplyToStatusId) { form.append('in_reply_to_id', inReplyToStatusId) } @@ -626,7 +648,7 @@ const deleteStatus = ({ id, credentials }) => { }) } -const uploadMedia = ({formData, credentials}) => { +const uploadMedia = ({ formData, credentials }) => { return fetch(MASTODON_MEDIA_UPLOAD_URL, { body: formData, method: 'POST', @@ -636,7 +658,7 @@ const uploadMedia = ({formData, credentials}) => { .then((data) => parseAttachment(data)) } -const importBlocks = ({file, credentials}) => { +const importBlocks = ({ file, credentials }) => { const formData = new FormData() formData.append('list', file) return fetch(BLOCKS_IMPORT_URL, { @@ -647,7 +669,7 @@ const importBlocks = ({file, credentials}) => { .then((response) => response.ok) } -const importFollows = ({file, credentials}) => { +const importFollows = ({ file, credentials }) => { const formData = new FormData() formData.append('list', file) return fetch(FOLLOW_IMPORT_URL, { @@ -658,7 +680,7 @@ const importFollows = ({file, credentials}) => { .then((response) => response.ok) } -const deleteAccount = ({credentials, password}) => { +const deleteAccount = ({ credentials, password }) => { const form = new FormData() form.append('password', password) @@ -671,7 +693,7 @@ const deleteAccount = ({credentials, password}) => { .then((response) => response.json()) } -const changePassword = ({credentials, password, newPassword, newPasswordConfirmation}) => { +const changePassword = ({ credentials, password, newPassword, newPasswordConfirmation }) => { const form = new FormData() form.append('password', password) @@ -686,14 +708,14 @@ const changePassword = ({credentials, password, newPassword, newPasswordConfirma .then((response) => response.json()) } -const settingsMFA = ({credentials}) => { +const settingsMFA = ({ credentials }) => { return fetch(MFA_SETTINGS_URL, { headers: authHeaders(credentials), method: 'GET' }).then((data) => data.json()) } -const mfaDisableOTP = ({credentials, password}) => { +const mfaDisableOTP = ({ credentials, password }) => { const form = new FormData() form.append('password', password) @@ -706,7 +728,7 @@ const mfaDisableOTP = ({credentials, password}) => { .then((response) => response.json()) } -const mfaConfirmOTP = ({credentials, password, token}) => { +const mfaConfirmOTP = ({ credentials, password, token }) => { const form = new FormData() form.append('password', password) @@ -718,38 +740,46 @@ const mfaConfirmOTP = ({credentials, password, token}) => { method: 'POST' }).then((data) => data.json()) } -const mfaSetupOTP = ({credentials}) => { +const mfaSetupOTP = ({ credentials }) => { return fetch(MFA_SETUP_OTP_URL, { headers: authHeaders(credentials), method: 'GET' }).then((data) => data.json()) } -const generateMfaBackupCodes = ({credentials}) => { +const generateMfaBackupCodes = ({ credentials }) => { return fetch(MFA_BACKUP_CODES_URL, { headers: authHeaders(credentials), method: 'GET' }).then((data) => data.json()) } -const fetchMutes = ({credentials}) => { +const fetchMutes = ({ credentials }) => { return promisedRequest({ url: MASTODON_USER_MUTES_URL, credentials }) .then((users) => users.map(parseUser)) } -const muteUser = ({id, credentials}) => { +const muteUser = ({ id, credentials }) => { return promisedRequest({ url: MASTODON_MUTE_USER_URL(id), credentials, method: 'POST' }) } -const unmuteUser = ({id, credentials}) => { +const unmuteUser = ({ id, credentials }) => { return promisedRequest({ url: MASTODON_UNMUTE_USER_URL(id), credentials, method: 'POST' }) } -const fetchBlocks = ({credentials}) => { +const subscribeUser = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_SUBSCRIBE_USER(id), credentials, method: 'POST' }) +} + +const unsubscribeUser = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_UNSUBSCRIBE_USER(id), credentials, method: 'POST' }) +} + +const fetchBlocks = ({ credentials }) => { return promisedRequest({ url: MASTODON_USER_BLOCKS_URL, credentials }) .then((users) => users.map(parseUser)) } -const fetchOAuthTokens = ({credentials}) => { +const fetchOAuthTokens = ({ credentials }) => { const url = '/api/oauth_tokens.json' return fetch(url, { @@ -762,7 +792,7 @@ const fetchOAuthTokens = ({credentials}) => { }) } -const revokeOAuthToken = ({id, credentials}) => { +const revokeOAuthToken = ({ id, credentials }) => { const url = `/api/oauth_tokens/${id}` return fetch(url, { @@ -771,13 +801,13 @@ const revokeOAuthToken = ({id, credentials}) => { }) } -const suggestions = ({credentials}) => { +const suggestions = ({ credentials }) => { return fetch(SUGGESTIONS_URL, { headers: authHeaders(credentials) }).then((data) => data.json()) } -const markNotificationsAsSeen = ({id, credentials}) => { +const markNotificationsAsSeen = ({ id, credentials }) => { const body = new FormData() body.append('latest_id', id) @@ -789,15 +819,39 @@ const markNotificationsAsSeen = ({id, credentials}) => { }).then((data) => data.json()) } -const fetchFavoritedByUsers = ({id}) => { +const vote = ({ pollId, choices, credentials }) => { + const form = new FormData() + form.append('choices', choices) + + return promisedRequest({ + url: MASTODON_VOTE_URL(encodeURIComponent(pollId)), + method: 'POST', + credentials, + payload: { + choices: choices + } + }) +} + +const fetchPoll = ({ pollId, credentials }) => { + return promisedRequest( + { + url: MASTODON_POLL_URL(encodeURIComponent(pollId)), + method: 'GET', + credentials + } + ) +} + +const fetchFavoritedByUsers = ({ id }) => { return promisedRequest({ url: MASTODON_STATUS_FAVORITEDBY_URL(id) }).then((users) => users.map(parseUser)) } -const fetchRebloggedByUsers = ({id}) => { +const fetchRebloggedByUsers = ({ id }) => { return promisedRequest({ url: MASTODON_STATUS_REBLOGGEDBY_URL(id) }).then((users) => users.map(parseUser)) } -const reportUser = ({credentials, userId, statusIds, comment, forward}) => { +const reportUser = ({ credentials, userId, statusIds, comment, forward }) => { return promisedRequest({ url: MASTODON_REPORT_USER_URL, method: 'POST', @@ -811,6 +865,60 @@ const reportUser = ({credentials, userId, statusIds, comment, forward}) => { }) } +const searchUsers = ({ credentials, query }) => { + return promisedRequest({ + url: MASTODON_USER_SEARCH_URL, + params: { + q: query, + resolve: true + }, + credentials + }) + .then((data) => data.map(parseUser)) +} + +const search2 = ({ credentials, q, resolve, limit, offset, following }) => { + let url = MASTODON_SEARCH_2 + let params = [] + + if (q) { + params.push(['q', encodeURIComponent(q)]) + } + + if (resolve) { + params.push(['resolve', resolve]) + } + + if (limit) { + params.push(['limit', limit]) + } + + if (offset) { + params.push(['offset', offset]) + } + + if (following) { + params.push(['following', true]) + } + + let queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') + url += `?${queryString}` + + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => { + if (data.ok) { + return data + } + throw new Error('Error fetching search result', data) + }) + .then((data) => { return data.json() }) + .then((data) => { + data.accounts = data.accounts.slice(0, limit).map(u => parseUser(u)) + data.statuses = data.statuses.slice(0, limit).map(s => parseStatus(s)) + return data + }) +} + const apiService = { verifyCredentials, fetchTimeline, @@ -824,6 +932,8 @@ const apiService = { unfollowUser, pinOwnStatus, unpinOwnStatus, + muteConversation, + unmuteConversation, blockUser, unblockUser, fetchUser, @@ -838,6 +948,8 @@ const apiService = { fetchMutes, muteUser, unmuteUser, + subscribeUser, + unsubscribeUser, fetchBlocks, fetchOAuthTokens, revokeOAuthToken, @@ -868,10 +980,14 @@ const apiService = { denyUser, suggestions, markNotificationsAsSeen, + vote, + fetchPoll, fetchFavoritedByUsers, fetchRebloggedByUsers, reportUser, - updateNotificationSettings + updateNotificationSettings, + search2, + searchUsers } export default apiService |
