diff options
| author | Shpuld Shpludson <shp@cock.li> | 2020-08-27 14:45:03 +0000 |
|---|---|---|
| committer | Shpuld Shpludson <shp@cock.li> | 2020-08-27 14:45:03 +0000 |
| commit | e768ec1fca2f7580d111b0878a9695b0c8b9dbb1 (patch) | |
| tree | 668ebbcd6818b3c7ad70a372c9f77fa9cffb6a3f /src/services/api/api.service.js | |
| parent | 5d49edc823ba2ea3e34d4fd6c5efcc84ef9712f7 (diff) | |
| parent | d09f43ba7a179cdca9a2d808631f8ba213dd7710 (diff) | |
Merge branch '2.1.0-rc0' into 'master'
2.1.0 into master
See merge request pleroma/pleroma-fe!1217
Diffstat (limited to 'src/services/api/api.service.js')
| -rw-r--r-- | src/services/api/api.service.js | 219 |
1 files changed, 171 insertions, 48 deletions
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 9d1ce393..da519001 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1,6 +1,5 @@ import { each, map, concat, last, get } from 'lodash' -import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js' -import 'whatwg-fetch' +import { parseStatus, parseUser, parseNotification, parseAttachment, parseChat, parseLinkHeaderPagination } from '../entity_normalizer/entity_normalizer.service.js' import { RegistrationError, StatusCodeError } from '../errors/errors' /* eslint-env browser */ @@ -51,6 +50,7 @@ const MASTODON_USER_URL = '/api/v1/accounts' const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships' const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses` const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}` +const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks' const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/' const MASTODON_USER_MUTES_URL = '/api/v1/mutes/' const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block` @@ -59,6 +59,8 @@ 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_BOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/bookmark` +const MASTODON_UNBOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/unbookmark` 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` @@ -75,9 +77,15 @@ const MASTODON_SEARCH_2 = `/api/v2/search` const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks' const MASTODON_STREAMING = '/api/v1/streaming' +const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers' const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions` const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}` const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}` +const PLEROMA_CHATS_URL = `/api/v1/pleroma/chats` +const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}` +const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages` +const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read` +const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}` const oldfetch = window.fetch @@ -138,20 +146,11 @@ const updateNotificationSettings = ({ credentials, settings }) => { }).then((data) => data.json()) } -const updateAvatar = ({ credentials, avatar }) => { +const updateProfileImages = ({ credentials, avatar = null, banner = null, background = null }) => { 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)) -} - -const updateBg = ({ credentials, background }) => { - const form = new FormData() - form.append('pleroma_background_image', background) + if (avatar !== null) form.append('avatar', avatar) + if (banner !== null) form.append('header', banner) + if (background !== null) form.append('pleroma_background_image', background) return fetch(MASTODON_PROFILE_UPDATE_URL, { headers: authHeaders(credentials), method: 'PATCH', @@ -161,17 +160,6 @@ const updateBg = ({ credentials, background }) => { .then((data) => parseUser(data)) } -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)) -} - const updateProfile = ({ credentials, params }) => { return promisedRequest({ url: MASTODON_PROFILE_UPDATE_URL, @@ -324,7 +312,8 @@ const fetchFriends = ({ id, maxId, sinceId, limit = 20, credentials }) => { const args = [ maxId && `max_id=${maxId}`, sinceId && `since_id=${sinceId}`, - limit && `limit=${limit}` + limit && `limit=${limit}`, + `with_relationships=true` ].filter(_ => _).join('&') url = url + (args ? '?' + args : '') @@ -358,7 +347,8 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => { const args = [ maxId && `max_id=${maxId}`, sinceId && `since_id=${sinceId}`, - limit && `limit=${limit}` + limit && `limit=${limit}`, + `with_relationships=true` ].filter(_ => _).join('&') url += args ? '?' + args : '' @@ -497,7 +487,7 @@ const fetchTimeline = ({ userId = false, tag = false, withMuted = false, - withMove = false + replyVisibility = 'all' }) => { const timelineUrls = { public: MASTODON_PUBLIC_TIMELINE, @@ -508,7 +498,8 @@ const fetchTimeline = ({ user: MASTODON_USER_TIMELINE_URL, media: MASTODON_USER_TIMELINE_URL, favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, - tag: MASTODON_TAG_TIMELINE_URL + tag: MASTODON_TAG_TIMELINE_URL, + bookmarks: MASTODON_BOOKMARK_TIMELINE_URL } const isNotifications = timeline === 'notifications' const params = [] @@ -537,27 +528,33 @@ const fetchTimeline = ({ if (timeline === 'public' || timeline === 'publicAndExternal') { params.push(['only_media', false]) } - if (timeline === 'notifications') { - params.push(['with_move', withMove]) + if (timeline !== 'favorites' && timeline !== 'bookmarks') { + params.push(['with_muted', withMuted]) + } + if (replyVisibility !== 'all') { + params.push(['reply_visibility', replyVisibility]) } params.push(['limit', 20]) - params.push(['with_muted', withMuted]) const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') url += `?${queryString}` let status = '' let statusText = '' + let pagination = {} return fetch(url, { headers: authHeaders(credentials) }) .then((data) => { status = data.status statusText = data.statusText + pagination = parseLinkHeaderPagination(data.headers.get('Link'), { + flakeId: timeline !== 'bookmarks' && timeline !== 'notifications' + }) return data }) .then((data) => data.json()) .then((data) => { if (!data.error) { - return data.map(isNotifications ? parseNotification : parseStatus) + return { data: data.map(isNotifications ? parseNotification : parseStatus), pagination } } else { data.status = status data.statusText = statusText @@ -608,6 +605,22 @@ const unretweet = ({ id, credentials }) => { .then((data) => parseStatus(data)) } +const bookmarkStatus = ({ id, credentials }) => { + return promisedRequest({ + url: MASTODON_BOOKMARK_STATUS_URL(id), + headers: authHeaders(credentials), + method: 'POST' + }) +} + +const unbookmarkStatus = ({ id, credentials }) => { + return promisedRequest({ + url: MASTODON_UNBOOKMARK_STATUS_URL(id), + headers: authHeaders(credentials), + method: 'POST' + }) +} + const postStatus = ({ credentials, status, @@ -617,7 +630,9 @@ const postStatus = ({ poll, mediaIds = [], inReplyToStatusId, - contentType + contentType, + preview, + idempotencyKey }) => { const form = new FormData() const pollOptions = poll.options || [] @@ -647,20 +662,22 @@ const postStatus = ({ if (inReplyToStatusId) { form.append('in_reply_to_id', inReplyToStatusId) } + if (preview) { + form.append('preview', 'true') + } + + let postHeaders = authHeaders(credentials) + if (idempotencyKey) { + postHeaders['idempotency-key'] = idempotencyKey + } return fetch(MASTODON_POST_STATUS_URL, { body: form, method: 'POST', - headers: authHeaders(credentials) + headers: postHeaders }) .then((response) => { - if (response.ok) { - return response.json() - } else { - return { - error: response - } - } + return response.json() }) .then((data) => data.error ? data : parseStatus(data)) } @@ -682,6 +699,17 @@ const uploadMedia = ({ formData, credentials }) => { .then((data) => parseAttachment(data)) } +const setMediaDescription = ({ id, description, credentials }) => { + return promisedRequest({ + url: `${MASTODON_MEDIA_UPLOAD_URL}/${id}`, + method: 'PUT', + headers: authHeaders(credentials), + payload: { + description + } + }).then((data) => parseAttachment(data)) +} + const importBlocks = ({ file, credentials }) => { const formData = new FormData() formData.append('list', file) @@ -975,6 +1003,8 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => { params.push(['following', true]) } + params.push(['with_relationships', true]) + let queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') url += `?${queryString}` @@ -993,6 +1023,10 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => { }) } +const fetchKnownDomains = ({ credentials }) => { + return promisedRequest({ url: MASTODON_KNOWN_DOMAIN_LIST_URL, credentials }) +} + const fetchDomainMutes = ({ credentials }) => { return promisedRequest({ url: MASTODON_DOMAIN_BLOCKS_URL, credentials }) } @@ -1044,6 +1078,10 @@ const MASTODON_STREAMING_EVENTS = new Set([ 'filters_changed' ]) +const PLEROMA_STREAMING_EVENTS = new Set([ + 'pleroma:chat_update' +]) + // A thin wrapper around WebSocket API that allows adding a pre-processor to it // Uses EventTarget and a CustomEvent to proxy events export const ProcessedWS = ({ @@ -1100,7 +1138,7 @@ export const handleMastoWS = (wsEvent) => { if (!data) return const parsedEvent = JSON.parse(data) const { event, payload } = parsedEvent - if (MASTODON_STREAMING_EVENTS.has(event)) { + if (MASTODON_STREAMING_EVENTS.has(event) || PLEROMA_STREAMING_EVENTS.has(event)) { // MastoBE and PleromaBE both send payload for delete as a PLAIN string if (event === 'delete') { return { event, id: payload } @@ -1110,6 +1148,8 @@ export const handleMastoWS = (wsEvent) => { return { event, status: parseStatus(data) } } else if (event === 'notification') { return { event, notification: parseNotification(data) } + } else if (event === 'pleroma:chat_update') { + return { event, chatUpdate: parseChat(data) } } } else { console.warn('Unknown event', wsEvent) @@ -1117,6 +1157,81 @@ export const handleMastoWS = (wsEvent) => { } } +export const WSConnectionStatus = Object.freeze({ + 'JOINED': 1, + 'CLOSED': 2, + 'ERROR': 3 +}) + +const chats = ({ credentials }) => { + return fetch(PLEROMA_CHATS_URL, { headers: authHeaders(credentials) }) + .then((data) => data.json()) + .then((data) => { + return { chats: data.map(parseChat).filter(c => c) } + }) +} + +const getOrCreateChat = ({ accountId, credentials }) => { + return promisedRequest({ + url: PLEROMA_CHAT_URL(accountId), + method: 'POST', + credentials + }) +} + +const chatMessages = ({ id, credentials, maxId, sinceId, limit = 20 }) => { + let url = PLEROMA_CHAT_MESSAGES_URL(id) + const args = [ + maxId && `max_id=${maxId}`, + sinceId && `since_id=${sinceId}`, + limit && `limit=${limit}` + ].filter(_ => _).join('&') + + url = url + (args ? '?' + args : '') + + return promisedRequest({ + url, + method: 'GET', + credentials + }) +} + +const sendChatMessage = ({ id, content, mediaId = null, credentials }) => { + const payload = { + 'content': content + } + + if (mediaId) { + payload['media_id'] = mediaId + } + + return promisedRequest({ + url: PLEROMA_CHAT_MESSAGES_URL(id), + method: 'POST', + payload: payload, + credentials + }) +} + +const readChat = ({ id, lastReadId, credentials }) => { + return promisedRequest({ + url: PLEROMA_CHAT_READ_URL(id), + method: 'POST', + payload: { + 'last_read_id': lastReadId + }, + credentials + }) +} + +const deleteChatMessage = ({ chatId, messageId, credentials }) => { + return promisedRequest({ + url: PLEROMA_DELETE_CHAT_MESSAGE_URL(chatId, messageId), + method: 'DELETE', + credentials + }) +} + const apiService = { verifyCredentials, fetchTimeline, @@ -1140,9 +1255,12 @@ const apiService = { unfavorite, retweet, unretweet, + bookmarkStatus, + unbookmarkStatus, postStatus, deleteStatus, uploadMedia, + setMediaDescription, fetchMutes, muteUser, unmuteUser, @@ -1160,10 +1278,8 @@ const apiService = { deactivateUser, register, getCaptcha, - updateAvatar, - updateBg, + updateProfileImages, updateProfile, - updateBanner, importBlocks, importFollows, deleteAccount, @@ -1191,9 +1307,16 @@ const apiService = { updateNotificationSettings, search2, searchUsers, + fetchKnownDomains, fetchDomainMutes, muteDomain, - unmuteDomain + unmuteDomain, + chats, + getOrCreateChat, + chatMessages, + sendChatMessage, + readChat, + deleteChatMessage } export default apiService |
