aboutsummaryrefslogtreecommitdiff
path: root/src/services
diff options
context:
space:
mode:
authorSean King <seanking2919@protonmail.com>2022-06-07 21:31:48 -0600
committerSean King <seanking2919@protonmail.com>2022-06-07 21:31:48 -0600
commit1a333aabba759fb68449ead9c47e986f456e8c8c (patch)
tree1fecfe37781465be576766fb6733bfdc01ed7262 /src/services
parent0aa334515bd67ca69e84177c22273592f694fc28 (diff)
Add edit status functionality
Diffstat (limited to 'src/services')
-rw-r--r--src/services/api/api.service.js88
-rw-r--r--src/services/entity_normalizer/entity_normalizer.service.js12
-rw-r--r--src/services/status_poster/status_poster.service.js42
3 files changed, 140 insertions, 2 deletions
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index ca84ba2c..f0ef4576 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 */
@@ -47,6 +47,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_RELATIONSHIPS_URL = '/api/v1/accounts/relationships'
const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses`
@@ -410,6 +412,32 @@ const fetchStatus = ({ id, credentials }) => {
.then((data) => parseStatus(data))
}
+const fetchStatusSource = ({ id, credentials }) => {
+ let 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 = ({ id, credentials }) => {
+ let url = MASTODON_STATUS_HISTORY_URL(id)
+ return fetch(url, { headers: authHeaders(credentials) })
+ .then((data) => {
+ if (data.ok) {
+ return data
+ }
+ throw new Error('Error fetching history', data)
+ })
+ .then((data) => data.json())
+ .then((data) => parseStatus(data))
+}
+
const tagUser = ({ tag, credentials, user }) => {
const screenName = user.screen_name
const form = {
@@ -701,6 +729,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)
+ })
+ }
+
+ let 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),
@@ -1105,9 +1181,12 @@ const MASTODON_STREAMING_EVENTS = new Set([
'update',
'notification',
'delete',
- 'filters_changed'
+ 'filters_changed',
+ 'status.update'
])
+// If Mastodon is doing a different streaming event,
+// please let us know, Gargron.
const PLEROMA_STREAMING_EVENTS = new Set([
'pleroma:chat_update'
])
@@ -1177,6 +1256,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') {
@@ -1279,6 +1360,8 @@ const apiService = {
fetchPinnedStatuses,
fetchConversation,
fetchStatus,
+ fetchStatusSource,
+ fetchStatusHistory,
fetchFriends,
exportFriends,
fetchFollowers,
@@ -1299,6 +1382,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 f219c161..82c19655 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -244,6 +244,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 = data.hasOwnProperty('account')
@@ -265,6 +275,8 @@ export const parseStatus = (data) => {
output.tags = data.tags
+ output.is_edited = data.edited_at !== null
+
if (data.pleroma) {
const { pleroma } = data
output.text = pleroma.content ? data.pleroma.content['text/plain'] : data.content
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
}