2019-01-14 13:30:14 +01:00
|
|
|
const qvitterStatusType = (status) => {
|
2019-01-13 20:07:55 +01:00
|
|
|
if (status.is_post_verb) {
|
|
|
|
return 'status'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status.retweeted_status) {
|
|
|
|
return 'retweet'
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((typeof status.uri === 'string' && status.uri.match(/(fave|objectType=Favourite)/)) ||
|
|
|
|
(typeof status.text === 'string' && status.text.match(/favorited/))) {
|
|
|
|
return 'favorite'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status.text.match(/deleted notice {{tag/) || status.qvitter_delete_notice) {
|
|
|
|
return 'deletion'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status.text.match(/started following/) || status.activity_type === 'follow') {
|
|
|
|
return 'follow'
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'unknown'
|
|
|
|
}
|
|
|
|
|
2019-01-14 13:30:14 +01:00
|
|
|
export const parseUser = (data) => {
|
|
|
|
const output = {}
|
|
|
|
const masto = data.hasOwnProperty('acct')
|
|
|
|
// case for users in "mentions" property for statuses in MastoAPI
|
|
|
|
const mastoShort = masto && !data.hasOwnProperty('avatar')
|
|
|
|
|
2019-01-17 17:23:14 +01:00
|
|
|
output.id = String(data.id)
|
2019-01-14 13:30:14 +01:00
|
|
|
|
|
|
|
if (masto) {
|
|
|
|
output.screen_name = data.acct
|
|
|
|
|
|
|
|
// There's nothing else to get
|
|
|
|
if (mastoShort) {
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
2019-03-11 22:03:55 +01:00
|
|
|
// output.name = ??? missing
|
2019-01-14 13:30:14 +01:00
|
|
|
output.name_html = data.display_name
|
|
|
|
|
2019-03-11 22:03:55 +01:00
|
|
|
// output.description = ??? missing
|
2019-01-14 13:30:14 +01:00
|
|
|
output.description_html = data.note
|
|
|
|
|
|
|
|
// Utilize avatar_static for gif avatars?
|
|
|
|
output.profile_image_url = data.avatar
|
|
|
|
output.profile_image_url_original = data.avatar
|
|
|
|
|
|
|
|
// Same, utilize header_static?
|
|
|
|
output.cover_photo = data.header
|
|
|
|
|
|
|
|
output.friends_count = data.following_count
|
|
|
|
|
|
|
|
output.bot = data.bot
|
|
|
|
|
|
|
|
output.statusnet_profile_url = data.url
|
|
|
|
|
2019-01-19 02:10:16 +01:00
|
|
|
if (data.pleroma) {
|
2019-03-11 22:08:14 +01:00
|
|
|
const relationship = data.pleroma.relationship
|
|
|
|
|
|
|
|
if (relationship) {
|
2019-03-12 20:49:03 +01:00
|
|
|
output.follows_you = relationship.followed_by
|
|
|
|
output.following = relationship.following
|
|
|
|
output.statusnet_blocking = relationship.blocking
|
|
|
|
output.muted = relationship.muting
|
2019-03-11 22:08:14 +01:00
|
|
|
}
|
2019-01-19 02:10:16 +01:00
|
|
|
}
|
2019-01-17 21:53:05 +01:00
|
|
|
|
2019-03-13 19:08:03 +01:00
|
|
|
// TODO: handle is_local
|
2019-03-13 20:43:48 +01:00
|
|
|
output.is_local = !output.screen_name.includes('@')
|
2019-01-14 13:30:14 +01:00
|
|
|
} else {
|
|
|
|
output.screen_name = data.screen_name
|
|
|
|
|
|
|
|
output.name = data.name
|
|
|
|
output.name_html = data.name_html
|
|
|
|
|
|
|
|
output.description = data.description
|
|
|
|
output.description_html = data.description_html
|
|
|
|
|
|
|
|
output.profile_image_url = data.profile_image_url
|
|
|
|
output.profile_image_url_original = data.profile_image_url_original
|
|
|
|
|
|
|
|
output.cover_photo = data.cover_photo
|
|
|
|
|
|
|
|
output.friends_count = data.friends_count
|
|
|
|
|
2019-03-11 22:03:55 +01:00
|
|
|
// output.bot = ??? missing
|
2019-01-14 13:30:14 +01:00
|
|
|
|
|
|
|
output.statusnet_profile_url = data.statusnet_profile_url
|
2019-01-17 21:53:05 +01:00
|
|
|
|
|
|
|
output.statusnet_blocking = data.statusnet_blocking
|
|
|
|
|
2019-01-14 13:30:14 +01:00
|
|
|
output.is_local = data.is_local
|
2019-02-04 15:03:35 +01:00
|
|
|
output.role = data.role
|
|
|
|
output.show_role = data.show_role
|
2019-01-17 20:11:51 +01:00
|
|
|
|
2019-01-17 21:53:05 +01:00
|
|
|
output.follows_you = data.follows_you
|
|
|
|
|
|
|
|
output.muted = data.muted
|
|
|
|
|
2019-01-17 20:11:51 +01:00
|
|
|
// QVITTER ONLY FOR NOW
|
|
|
|
// Really only applies to logged in user, really.. I THINK
|
|
|
|
output.rights = data.rights
|
|
|
|
output.no_rich_text = data.no_rich_text
|
|
|
|
output.default_scope = data.default_scope
|
2019-02-06 12:21:13 +01:00
|
|
|
output.hide_follows = data.hide_follows
|
2019-01-29 23:11:40 +01:00
|
|
|
output.hide_followers = data.hide_followers
|
2019-01-17 20:11:51 +01:00
|
|
|
output.background_image = data.background_image
|
2019-01-27 15:10:55 +01:00
|
|
|
// on mastoapi this info is contained in a "relationship"
|
|
|
|
output.following = data.following
|
2019-01-27 21:38:33 +01:00
|
|
|
// Websocket token
|
|
|
|
output.token = data.token
|
2019-01-13 20:07:55 +01:00
|
|
|
}
|
2019-01-14 13:30:14 +01:00
|
|
|
|
|
|
|
output.created_at = new Date(data.created_at)
|
|
|
|
output.locked = data.locked
|
|
|
|
output.followers_count = data.followers_count
|
|
|
|
output.statuses_count = data.statuses_count
|
2019-01-31 20:11:28 +01:00
|
|
|
output.friends = []
|
|
|
|
output.followers = []
|
2019-02-11 10:41:17 +01:00
|
|
|
if (data.pleroma) {
|
|
|
|
output.follow_request_count = data.pleroma.follow_request_count
|
|
|
|
}
|
2019-01-14 13:30:14 +01:00
|
|
|
|
|
|
|
return output
|
2019-01-13 20:07:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const parseAttachment = (data) => {
|
2019-01-21 14:28:36 +01:00
|
|
|
const output = {}
|
|
|
|
const masto = !data.hasOwnProperty('oembed')
|
|
|
|
|
|
|
|
if (masto) {
|
|
|
|
// Not exactly same...
|
|
|
|
output.mimetype = data.type
|
|
|
|
output.meta = data.meta // not present in BE yet
|
|
|
|
} else {
|
|
|
|
output.mimetype = data.mimetype
|
2019-03-11 22:03:55 +01:00
|
|
|
// output.meta = ??? missing
|
2019-01-13 20:07:55 +01:00
|
|
|
}
|
2019-01-21 14:28:36 +01:00
|
|
|
|
|
|
|
output.url = data.url
|
|
|
|
output.description = data.description
|
|
|
|
|
|
|
|
return output
|
2019-01-13 20:07:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export const parseStatus = (data) => {
|
|
|
|
const output = {}
|
2019-01-14 20:38:37 +01:00
|
|
|
const masto = data.hasOwnProperty('account')
|
|
|
|
|
2019-01-13 20:07:55 +01:00
|
|
|
if (masto) {
|
|
|
|
output.favorited = data.favourited
|
|
|
|
output.fave_num = data.favourites_count
|
|
|
|
|
|
|
|
output.repeated = data.reblogged
|
|
|
|
output.repeat_num = data.reblogs_count
|
|
|
|
|
|
|
|
output.type = data.reblog ? 'retweet' : 'status'
|
|
|
|
output.nsfw = data.sensitive
|
|
|
|
|
|
|
|
output.statusnet_html = data.content
|
2019-01-14 20:58:23 +01:00
|
|
|
|
|
|
|
// Not exactly the same but works?
|
2019-01-13 20:07:55 +01:00
|
|
|
output.text = data.content
|
|
|
|
|
|
|
|
output.in_reply_to_status_id = data.in_reply_to_id
|
2019-01-17 21:22:51 +01:00
|
|
|
output.in_reply_to_user_id = data.in_reply_to_account_id
|
2019-01-21 19:41:17 +01:00
|
|
|
|
|
|
|
// Missing!! fix in UI?
|
2019-03-11 22:03:55 +01:00
|
|
|
// output.in_reply_to_screen_name = ???
|
2019-01-14 20:58:23 +01:00
|
|
|
|
|
|
|
// Not exactly the same but works
|
|
|
|
output.statusnet_conversation_id = data.id
|
2019-01-17 18:44:37 +01:00
|
|
|
|
|
|
|
if (output.type === 'retweet') {
|
|
|
|
output.retweeted_status = parseStatus(data.reblog)
|
|
|
|
}
|
2019-01-17 21:22:51 +01:00
|
|
|
|
|
|
|
output.summary = data.spoiler_text
|
2019-01-25 11:05:19 +01:00
|
|
|
output.summary_html = data.spoiler_text
|
2019-01-17 21:44:31 +01:00
|
|
|
output.external_url = data.url
|
2019-03-15 03:07:42 +01:00
|
|
|
output.is_local = data.pleroma.local
|
2019-01-13 20:07:55 +01:00
|
|
|
} else {
|
|
|
|
output.favorited = data.favorited
|
|
|
|
output.fave_num = data.fave_num
|
|
|
|
|
|
|
|
output.repeated = data.repeated
|
|
|
|
output.repeat_num = data.repeat_num
|
|
|
|
|
|
|
|
// catchall, temporary
|
|
|
|
// Object.assign(output, data)
|
|
|
|
|
|
|
|
output.type = qvitterStatusType(data)
|
|
|
|
|
|
|
|
if (data.nsfw === undefined) {
|
|
|
|
output.nsfw = isNsfw(data)
|
|
|
|
if (data.retweeted_status) {
|
|
|
|
output.nsfw = data.retweeted_status.nsfw
|
|
|
|
}
|
2019-01-15 16:39:24 +01:00
|
|
|
} else {
|
|
|
|
output.nsfw = data.nsfw
|
2019-01-13 20:07:55 +01:00
|
|
|
}
|
2019-01-15 16:39:24 +01:00
|
|
|
|
2019-01-13 20:07:55 +01:00
|
|
|
output.statusnet_html = data.statusnet_html
|
|
|
|
output.text = data.text
|
|
|
|
|
2019-01-17 21:22:51 +01:00
|
|
|
output.in_reply_to_status_id = data.in_reply_to_status_id
|
|
|
|
output.in_reply_to_user_id = data.in_reply_to_user_id
|
2019-01-21 19:41:17 +01:00
|
|
|
output.in_reply_to_screen_name = data.in_reply_to_screen_name
|
2019-01-17 21:44:31 +01:00
|
|
|
|
2019-01-14 20:58:23 +01:00
|
|
|
output.statusnet_conversation_id = data.statusnet_conversation_id
|
2019-01-17 18:44:37 +01:00
|
|
|
|
|
|
|
if (output.type === 'retweet') {
|
|
|
|
output.retweeted_status = parseStatus(data.retweeted_status)
|
|
|
|
}
|
2019-01-17 21:22:51 +01:00
|
|
|
|
|
|
|
output.summary = data.summary
|
2019-01-25 11:05:19 +01:00
|
|
|
output.summary_html = data.summary_html
|
2019-01-17 21:44:31 +01:00
|
|
|
output.external_url = data.external_url
|
|
|
|
output.is_local = data.is_local
|
2019-01-13 20:07:55 +01:00
|
|
|
}
|
|
|
|
|
2019-01-17 17:23:14 +01:00
|
|
|
output.id = String(data.id)
|
2019-01-13 20:07:55 +01:00
|
|
|
output.visibility = data.visibility
|
2019-01-27 13:56:07 +01:00
|
|
|
output.card = data.card
|
2019-01-13 20:07:55 +01:00
|
|
|
output.created_at = new Date(data.created_at)
|
|
|
|
|
2019-01-22 21:57:51 +01:00
|
|
|
// Converting to string, the right way.
|
|
|
|
output.in_reply_to_status_id = output.in_reply_to_status_id
|
|
|
|
? String(output.in_reply_to_status_id)
|
|
|
|
: null
|
|
|
|
output.in_reply_to_user_id = output.in_reply_to_user_id
|
|
|
|
? String(output.in_reply_to_user_id)
|
|
|
|
: null
|
|
|
|
|
2019-01-13 20:07:55 +01:00
|
|
|
output.user = parseUser(masto ? data.account : data.user)
|
|
|
|
|
2019-01-19 02:10:16 +01:00
|
|
|
output.attentions = ((masto ? data.mentions : data.attentions) || []).map(parseUser)
|
2019-01-13 20:07:55 +01:00
|
|
|
|
|
|
|
output.attachments = ((masto ? data.media_attachments : data.attachments) || [])
|
|
|
|
.map(parseAttachment)
|
|
|
|
|
|
|
|
const retweetedStatus = masto ? data.reblog : data.retweeted_status
|
|
|
|
if (retweetedStatus) {
|
|
|
|
output.retweeted_status = parseStatus(retweetedStatus)
|
|
|
|
}
|
|
|
|
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
2019-03-12 22:16:57 +01:00
|
|
|
export const parseFollow = (data) => {
|
|
|
|
const output = {}
|
|
|
|
output.id = String(data.id)
|
|
|
|
output.visibility = true
|
|
|
|
output.created_at = new Date(data.created_at)
|
|
|
|
|
|
|
|
// Converting to string, the right way.
|
|
|
|
output.user = parseUser(data.account)
|
|
|
|
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
2019-01-14 20:38:37 +01:00
|
|
|
export const parseNotification = (data) => {
|
|
|
|
const mastoDict = {
|
|
|
|
'favourite': 'like',
|
|
|
|
'reblog': 'repeat'
|
|
|
|
}
|
|
|
|
const masto = !data.hasOwnProperty('ntype')
|
|
|
|
const output = {}
|
|
|
|
|
|
|
|
if (masto) {
|
|
|
|
output.type = mastoDict[data.type] || data.type
|
2019-03-15 16:28:33 +01:00
|
|
|
|
2019-01-14 20:38:37 +01:00
|
|
|
output.seen = null // missing
|
2019-03-12 22:16:57 +01:00
|
|
|
output.status = output.type === 'follow'
|
|
|
|
? parseFollow(data)
|
|
|
|
: parseStatus(data.status)
|
2019-03-14 12:55:39 +01:00
|
|
|
if (data.type === 'reblog' || data.type === 'favourite') {
|
2019-03-13 20:34:45 +01:00
|
|
|
output.status.user = parseUser(data.account)
|
|
|
|
output.status.created_at = new Date(data.created_at)
|
|
|
|
}
|
2019-01-17 18:44:37 +01:00
|
|
|
output.action = output.status // not sure
|
2019-01-14 20:38:37 +01:00
|
|
|
output.from_profile = parseUser(data.account)
|
|
|
|
} else {
|
|
|
|
const parsedNotice = parseStatus(data.notice)
|
|
|
|
output.type = data.ntype
|
2019-01-17 18:44:37 +01:00
|
|
|
output.seen = Boolean(data.is_seen)
|
2019-01-14 20:38:37 +01:00
|
|
|
output.status = output.type === 'like'
|
|
|
|
? parseStatus(data.notice.favorited_status)
|
|
|
|
: parsedNotice
|
|
|
|
output.action = parsedNotice
|
|
|
|
output.from_profile = parseUser(data.from_profile)
|
|
|
|
}
|
|
|
|
|
|
|
|
output.created_at = new Date(data.created_at)
|
2019-02-02 16:39:54 +01:00
|
|
|
output.id = data.id
|
2019-01-14 20:38:37 +01:00
|
|
|
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
2019-01-13 20:07:55 +01:00
|
|
|
const isNsfw = (status) => {
|
|
|
|
const nsfwRegex = /#nsfw/i
|
|
|
|
return (status.tags || []).includes('nsfw') || !!status.text.match(nsfwRegex)
|
|
|
|
}
|