diff options
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/api/api.service.js | 85 | ||||
| -rw-r--r-- | src/services/entity_normalizer/entity_normalizer.service.js | 16 | ||||
| -rw-r--r-- | src/services/status_poster/status_poster.service.js | 42 |
3 files changed, 141 insertions, 2 deletions
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index ce60d65a..ffe1bf7b 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1,5 +1,5 @@ import { each, map, concat, last, get } from 'lodash' -import { parseStatus, parseUser, parseNotification, parseAttachment, parseChat, parseLinkHeaderPagination } from '../entity_normalizer/entity_normalizer.service.js' +import { parseStatus, parseSource, parseUser, parseNotification, parseAttachment, parseChat, parseLinkHeaderPagination } from '../entity_normalizer/entity_normalizer.service.js' import { RegistrationError, StatusCodeError } from '../errors/errors' /* eslint-env browser */ @@ -49,6 +49,8 @@ const MASTODON_PUBLIC_TIMELINE = '/api/v1/timelines/public' const MASTODON_USER_HOME_TIMELINE_URL = '/api/v1/timelines/home' const MASTODON_STATUS_URL = id => `/api/v1/statuses/${id}` const MASTODON_STATUS_CONTEXT_URL = id => `/api/v1/statuses/${id}/context` +const MASTODON_STATUS_SOURCE_URL = id => `/api/v1/statuses/${id}/source` +const MASTODON_STATUS_HISTORY_URL = id => `/api/v1/statuses/${id}/history` const MASTODON_USER_URL = '/api/v1/accounts' const MASTODON_USER_LOOKUP_URL = '/api/v1/accounts/lookup' const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships' @@ -514,6 +516,31 @@ const fetchStatus = ({ id, credentials }) => { .then((data) => parseStatus(data)) } +const fetchStatusSource = ({ id, credentials }) => { + const url = MASTODON_STATUS_SOURCE_URL(id) + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => { + if (data.ok) { + return data + } + throw new Error('Error fetching source', data) + }) + .then((data) => data.json()) + .then((data) => parseSource(data)) +} + +const fetchStatusHistory = ({ status, credentials }) => { + const url = MASTODON_STATUS_HISTORY_URL(status.id) + return promisedRequest({ url, credentials }) + .then((data) => { + data.reverse() + return data.map((item) => { + item.originalStatus = status + return parseStatus(item) + }) + }) +} + const tagUser = ({ tag, credentials, user }) => { const screenName = user.screen_name const form = { @@ -817,6 +844,54 @@ const postStatus = ({ .then((data) => data.error ? data : parseStatus(data)) } +const editStatus = ({ + id, + credentials, + status, + spoilerText, + sensitive, + poll, + mediaIds = [], + contentType +}) => { + const form = new FormData() + const pollOptions = poll.options || [] + + form.append('status', status) + if (spoilerText) form.append('spoiler_text', spoilerText) + if (sensitive) form.append('sensitive', sensitive) + if (contentType) form.append('content_type', contentType) + 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) + }) + } + + const putHeaders = authHeaders(credentials) + + return fetch(MASTODON_STATUS_URL(id), { + body: form, + method: 'PUT', + headers: putHeaders + }) + .then((response) => { + return response.json() + }) + .then((data) => data.error ? data : parseStatus(data)) +} + const deleteStatus = ({ id, credentials }) => { return fetch(MASTODON_DELETE_URL(id), { headers: authHeaders(credentials), @@ -1283,7 +1358,8 @@ const MASTODON_STREAMING_EVENTS = new Set([ 'update', 'notification', 'delete', - 'filters_changed' + 'filters_changed', + 'status.update' ]) const PLEROMA_STREAMING_EVENTS = new Set([ @@ -1355,6 +1431,8 @@ export const handleMastoWS = (wsEvent) => { const data = payload ? JSON.parse(payload) : null if (event === 'update') { return { event, status: parseStatus(data) } + } else if (event === 'status.update') { + return { event, status: parseStatus(data) } } else if (event === 'notification') { return { event, notification: parseNotification(data) } } else if (event === 'pleroma:chat_update') { @@ -1489,6 +1567,8 @@ const apiService = { fetchPinnedStatuses, fetchConversation, fetchStatus, + fetchStatusSource, + fetchStatusHistory, fetchFriends, exportFriends, fetchFollowers, @@ -1510,6 +1590,7 @@ const apiService = { bookmarkStatus, unbookmarkStatus, postStatus, + editStatus, deleteStatus, uploadMedia, setMediaDescription, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index e9cbcfe6..f4d1cc29 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -247,6 +247,16 @@ export const parseAttachment = (data) => { return output } +export const parseSource = (data) => { + const output = {} + + output.text = data.text + output.spoiler_text = data.spoiler_text + output.content_type = data.content_type + + return output +} + export const parseStatus = (data) => { const output = {} const masto = Object.prototype.hasOwnProperty.call(data, 'account') @@ -268,6 +278,8 @@ export const parseStatus = (data) => { output.tags = data.tags + output.edited_at = data.edited_at + if (data.pleroma) { const { pleroma } = data output.text = pleroma.content ? data.pleroma.content['text/plain'] : data.content @@ -369,6 +381,10 @@ export const parseStatus = (data) => { output.favoritedBy = [] output.rebloggedBy = [] + if (Object.prototype.hasOwnProperty.call(data, 'originalStatus')) { + Object.assign(output, data.originalStatus) + } + return output } diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js index f09196aa..1eb10bb6 100644 --- a/src/services/status_poster/status_poster.service.js +++ b/src/services/status_poster/status_poster.service.js @@ -47,6 +47,47 @@ const postStatus = ({ }) } +const editStatus = ({ + store, + statusId, + status, + spoilerText, + sensitive, + poll, + media = [], + contentType = 'text/plain' +}) => { + const mediaIds = map(media, 'id') + + return apiService.editStatus({ + id: statusId, + credentials: store.state.users.currentUser.credentials, + status, + spoilerText, + sensitive, + poll, + mediaIds, + contentType + }) + .then((data) => { + if (!data.error) { + store.dispatch('addNewStatuses', { + statuses: [data], + timeline: 'friends', + showImmediately: true, + noIdUpdate: true // To prevent missing notices on next pull. + }) + } + return data + }) + .catch((err) => { + console.error('Error editing status', err) + return { + error: err.message + } + }) +} + const uploadMedia = ({ store, formData }) => { const credentials = store.state.users.currentUser.credentials return apiService.uploadMedia({ credentials, formData }) @@ -59,6 +100,7 @@ const setMediaDescription = ({ store, id, description }) => { const statusPosterService = { postStatus, + editStatus, uploadMedia, setMediaDescription } |
