diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.js b/src/components/who_to_follow_panel/who_to_follow_panel.js
index 5e204001ae..a56a27eafa 100644
--- a/src/components/who_to_follow_panel/who_to_follow_panel.js
+++ b/src/components/who_to_follow_panel/who_to_follow_panel.js
@@ -1,12 +1,12 @@
import apiService from '../../services/api/api.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
-import _ from 'lodash'
+import { shuffle } from 'lodash'
function showWhoToFollow (panel, reply) {
- _.shuffle(reply)
+ const shuffled = shuffle(reply)
panel.usersToFollow.forEach((toFollow, index) => {
- let user = reply[index]
+ let user = shuffled[index]
let img = user.avatar || '/images/avi.png'
let name = user.acct
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 6008287f5e..2c6887bc56 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -327,6 +327,7 @@
"block": "Block",
"blocked": "Blocked!",
"deny": "Deny",
+ "favorites": "Favorites",
"follow": "Follow",
"follow_sent": "Request sent!",
"follow_progress": "Requesting…",
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 249eab6965..0887bb5908 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -279,6 +279,7 @@
"user_card": {
"block": "Заблокировать",
"blocked": "Заблокирован",
+ "favorites": "Понравившиеся",
"follow": "Читать",
"follow_sent": "Запрос отправлен!",
"follow_progress": "Запрашиваем…",
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index f92239a968..20a8d2eb43 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,8 +1,8 @@
-import { includes, remove, slice, sortBy, toInteger, each, find, flatten, maxBy, minBy, merge, last, isArray } from 'lodash'
+import { remove, slice, each, find, maxBy, minBy, merge, last, isArray } from 'lodash'
import apiService from '../services/api/api.service.js'
// import parse from '../services/status_parser/status_parser.js'
-const emptyTl = (userId = 0) => ({
+const emptyTl = () => ({
statuses: [],
statusesObject: {},
faves: [],
@@ -14,8 +14,8 @@ const emptyTl = (userId = 0) => ({
loading: false,
followers: [],
friends: [],
- flushMarker: 0,
- userId
+ userId: 0,
+ flushMarker: 0
})
export const defaultState = {
@@ -36,6 +36,7 @@ export const defaultState = {
mentions: emptyTl(),
public: emptyTl(),
user: emptyTl(),
+ favorites: emptyTl(),
publicAndExternal: emptyTl(),
friends: emptyTl(),
tag: emptyTl(),
@@ -43,20 +44,7 @@ export const defaultState = {
}
}
-const isNsfw = (status) => {
- const nsfwRegex = /#nsfw/i
- return includes(status.tags, 'nsfw') || !!status.text.match(nsfwRegex)
-}
-
export const prepareStatus = (status) => {
- // Parse nsfw tags
- if (status.nsfw === undefined) {
- status.nsfw = isNsfw(status)
- if (status.retweeted_status) {
- status.nsfw = status.retweeted_status.nsfw
- }
- }
-
// Set deleted flag
status.deleted = false
@@ -75,35 +63,6 @@ const visibleNotificationTypes = (rootState) => {
].filter(_ => _)
}
-export const statusType = (status) => {
- 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'
-}
-
-export const findMaxId = (...args) => {
- return (maxBy(flatten(args), 'id') || {}).id
-}
-
const mergeOrAdd = (arr, obj, item) => {
const oldItem = obj[item.id]
@@ -122,9 +81,25 @@ const mergeOrAdd = (arr, obj, item) => {
}
}
+const sortById = (a, b) => {
+ const seqA = Number(a.id)
+ const seqB = Number(b.id)
+ const isSeqA = !Number.isNaN(seqA)
+ const isSeqB = !Number.isNaN(seqB)
+ if (isSeqA && isSeqB) {
+ return seqA > seqB ? -1 : 1
+ } else if (isSeqA && !isSeqB) {
+ return 1
+ } else if (!isSeqA && isSeqB) {
+ return -1
+ } else {
+ return a.id > b.id ? -1 : 1
+ }
+}
+
const sortTimeline = (timeline) => {
- timeline.visibleStatuses = sortBy(timeline.visibleStatuses, ({id}) => -id)
- timeline.statuses = sortBy(timeline.statuses, ({id}) => -id)
+ timeline.visibleStatuses = timeline.visibleStatuses.sort(sortById)
+ timeline.statuses = timeline.statuses.sort(sortById)
timeline.minVisibleId = (last(timeline.visibleStatuses) || {}).id
return timeline
}
@@ -153,13 +128,13 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
return
}
- const addStatus = (status, showImmediately, addToTimeline = true) => {
- const result = mergeOrAdd(allStatuses, allStatusesObject, status)
- status = result.item
+ const addStatus = (data, showImmediately, addToTimeline = true) => {
+ const result = mergeOrAdd(allStatuses, allStatusesObject, data)
+ const status = result.item
if (result.new) {
// We are mentioned in a post
- if (statusType(status) === 'status' && find(status.attentions, { id: user.id })) {
+ if (status.type === 'status' && find(status.attentions, { id: user.id })) {
const mentions = state.timelines.mentions
// Add the mention to the mentions timeline
@@ -200,7 +175,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
}
const favoriteStatus = (favorite, counter) => {
- const status = find(allStatuses, { id: toInteger(favorite.in_reply_to_status_id) })
+ const status = find(allStatuses, { id: favorite.in_reply_to_status_id })
if (status) {
// This is our favorite, so the relevant bit.
if (favorite.user.id === user.id) {
@@ -263,6 +238,9 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
remove(timelineObject.visibleStatuses, { uri })
}
},
+ 'follow': (follow) => {
+ // NOOP, it is known status but we don't do anything about it for now
+ },
'default': (unknown) => {
console.log('unknown status type')
console.log(unknown)
@@ -270,12 +248,12 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
}
each(statuses, (status) => {
- const type = statusType(status)
+ const type = status.type
const processor = processors[type] || processors['default']
processor(status)
})
- // Keep the visible statuses sorted
+ // Keep the visible statuses sorted
if (timeline) {
sortTimeline(timelineObject)
if ((older || timelineObject.minVisibleId <= 0) && statuses.length > 0) {
@@ -288,42 +266,36 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
const allStatuses = state.allStatuses
const allStatusesObject = state.allStatusesObject
each(notifications, (notification) => {
- const result = mergeOrAdd(allStatuses, allStatusesObject, notification.notice)
- const action = result.item
+ notification.action = mergeOrAdd(allStatuses, allStatusesObject, notification.action).item
+ notification.status = notification.status && mergeOrAdd(allStatuses, allStatusesObject, notification.status).item
+
// Only add a new notification if we don't have one for the same action
- if (!find(state.notifications.data, (oldNotification) => oldNotification.action.id === action.id)) {
- state.notifications.maxId = Math.max(notification.id, state.notifications.maxId)
- state.notifications.minId = Math.min(notification.id, state.notifications.minId)
+ if (!state.notifications.idStore.hasOwnProperty(notification.id)) {
+ state.notifications.maxId = notification.id > state.notifications.maxId
+ ? notification.id
+ : state.notifications.maxId
+ state.notifications.minId = notification.id < state.notifications.minId
+ ? notification.id
+ : state.notifications.minId
- const fresh = !notification.is_seen
- const status = notification.ntype === 'like'
- ? action.favorited_status
- : action
-
- const result = {
- type: notification.ntype,
- status,
- action,
- seen: !fresh
- }
-
- state.notifications.data.push(result)
- state.notifications.idStore[notification.id] = result
+ state.notifications.data.push(notification)
+ state.notifications.idStore[notification.id] = notification
if ('Notification' in window && window.Notification.permission === 'granted') {
+ const notifObj = {}
+ const action = notification.action
const title = action.user.name
- const result = {}
- result.icon = action.user.profile_image_url
- result.body = action.text // there's a problem that it doesn't put a space before links tho
+ notifObj.icon = action.user.profile_image_url
+ notifObj.body = action.text // there's a problem that it doesn't put a space before links tho
// Shows first attached non-nsfw image, if any. Should add configuration for this somehow...
if (action.attachments && action.attachments.length > 0 && !action.nsfw &&
action.attachments[0].mimetype.startsWith('image/')) {
- result.image = action.attachments[0].url
+ notifObj.image = action.attachments[0].url
}
- if (fresh && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.ntype)) {
- let notification = new window.Notification(title, result)
+ if (notification.fresh && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.ntype)) {
+ let notification = new window.Notification(title, notifObj)
// Chrome is known for not closing notifications automatically
// according to MDN, anyway.
setTimeout(notification.close.bind(notification), 5000)
@@ -346,7 +318,7 @@ export const mutations = {
each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status })
},
clearTimeline (state, { timeline }) {
- state.timelines[timeline] = emptyTl(state.timelines[timeline].userId)
+ state.timelines[timeline] = emptyTl()
},
setFavorited (state, { status, value }) {
const newStatus = state.allStatusesObject[status.id]
diff --git a/src/modules/users.js b/src/modules/users.js
index adbd37dd4b..d83f0dd898 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -68,6 +68,7 @@ export const mutations = {
},
setUserForNotification (state, notification) {
notification.action.user = state.usersObject[notification.action.user.id]
+ notification.from_profile = state.usersObject[notification.action.user.id]
},
setColor (state, { user: { id }, highlighted }) {
const user = state.usersObject[id]
@@ -149,8 +150,8 @@ const users = {
})
},
addNewNotifications (store, { notifications }) {
- const users = compact(map(notifications, 'from_profile'))
- const notificationIds = compact(notifications.map(_ => String(_.id)))
+ const users = map(notifications, 'from_profile')
+ const notificationIds = notifications.map(_ => _.id)
store.commit('addNewUsers', users)
const notificationsObject = store.rootState.statuses.notifications.idStore
@@ -206,39 +207,38 @@ const users = {
const commit = store.commit
commit('beginLogin')
store.rootState.api.backendInteractor.verifyCredentials(accessToken)
- .then((response) => {
- if (response.ok) {
- response.json()
- .then((user) => {
- // user.credentials = userCredentials
- user.credentials = accessToken
- commit('setCurrentUser', user)
- commit('addNewUsers', [user])
+ .then((data) => {
+ if (!data.error) {
+ const user = data
+ // user.credentials = userCredentials
+ user.credentials = accessToken
+ commit('setCurrentUser', user)
+ commit('addNewUsers', [user])
- getNotificationPermission()
- .then(permission => commit('setNotificationPermission', permission))
+ getNotificationPermission()
+ .then(permission => commit('setNotificationPermission', permission))
- // Set our new backend interactor
- commit('setBackendInteractor', backendInteractorService(accessToken))
+ // Set our new backend interactor
+ commit('setBackendInteractor', backendInteractorService(accessToken))
- if (user.token) {
- store.dispatch('initializeSocket', user.token)
- }
+ if (user.token) {
+ store.dispatch('initializeSocket', user.token)
+ }
- // Start getting fresh tweets.
- store.dispatch('startFetching', 'friends')
+ // Start getting fresh tweets.
+ store.dispatch('startFetching', 'friends')
- // Get user mutes and follower info
- store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => {
- each(mutedUsers, (user) => { user.muted = true })
- store.commit('addNewUsers', mutedUsers)
- })
+ // Get user mutes and follower info
+ store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => {
+ each(mutedUsers, (user) => { user.muted = true })
+ store.commit('addNewUsers', mutedUsers)
+ })
- // Fetch our friends
- store.rootState.api.backendInteractor.fetchFriends({ id: user.id })
- .then((friends) => commit('addNewUsers', friends))
- })
+ // Fetch our friends
+ store.rootState.api.backendInteractor.fetchFriends({ id: user.id })
+ .then((friends) => commit('addNewUsers', friends))
} else {
+ const response = data.error
// Authentication failed
commit('endLogin')
if (response.status === 401) {
@@ -250,11 +250,11 @@ const users = {
commit('endLogin')
resolve()
})
- .catch((error) => {
- console.log(error)
- commit('endLogin')
- reject('Failed to connect to server, try again')
- })
+ .catch((error) => {
+ console.log(error)
+ commit('endLogin')
+ reject('Failed to connect to server, try again')
+ })
})
}
}
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 4ee95bd10e..776d8daef1 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -41,7 +41,10 @@ const APPROVE_USER_URL = '/api/pleroma/friendships/approve'
const DENY_USER_URL = '/api/pleroma/friendships/deny'
const SUGGESTIONS_URL = '/api/v1/suggestions'
+const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
+
import { each, map } from 'lodash'
+import { parseStatus, parseUser, parseNotification } from '../entity_normalizer/entity_normalizer.service.js'
import 'whatwg-fetch'
const oldfetch = window.fetch
@@ -70,6 +73,7 @@ const updateAvatar = ({credentials, params}) => {
form.append(key, value)
}
})
+
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST',
@@ -87,6 +91,7 @@ const updateBg = ({credentials, params}) => {
form.append(key, value)
}
})
+
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST',
@@ -110,6 +115,7 @@ const updateBanner = ({credentials, params}) => {
form.append(key, value)
}
})
+
return fetch(url, {
headers: authHeaders(credentials),
method: 'POST',
@@ -123,13 +129,14 @@ const updateBanner = ({credentials, params}) => {
// location
// description
const updateProfile = ({credentials, params}) => {
+ // Always include these fields, because they might be empty or false
+ const fields = ['description', 'locked', 'no_rich_text', 'hide_network']
let url = PROFILE_UPDATE_URL
const form = new FormData()
each(params, (value, key) => {
- /* Always include description, no_rich_text and locked, because it might be empty or false */
- if (key === 'description' || key === 'locked' || key === 'no_rich_text' || value) {
+ if (fields.includes(key) || value) {
form.append(key, value)
}
})
@@ -237,24 +244,28 @@ const fetchUser = ({id, credentials}) => {
let url = `${USER_URL}?user_id=${id}`
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => data.json())
+ .then((data) => parseUser(data))
}
const fetchFriends = ({id, credentials}) => {
let url = `${FRIENDS_URL}?user_id=${id}`
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => data.json())
+ .then((data) => data.map(parseUser))
}
const fetchFollowers = ({id, credentials}) => {
let url = `${FOLLOWERS_URL}?user_id=${id}`
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => data.json())
+ .then((data) => data.map(parseUser))
}
const fetchAllFollowing = ({username, credentials}) => {
const url = `${ALL_FOLLOWING_URL}/${username}.json`
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => data.json())
+ .then((data) => data.map(parseUser))
}
const fetchFollowRequests = ({credentials}) => {
@@ -266,13 +277,27 @@ const fetchFollowRequests = ({credentials}) => {
const fetchConversation = ({id, credentials}) => {
let url = `${CONVERSATION_URL}/${id}.json?count=100`
return fetch(url, { headers: authHeaders(credentials) })
+ .then((data) => {
+ if (data.ok) {
+ return data
+ }
+ throw new Error('Error fetching timeline', data)
+ })
.then((data) => data.json())
+ .then((data) => data.map(parseStatus))
}
const fetchStatus = ({id, credentials}) => {
let url = `${STATUS_URL}/${id}.json`
return fetch(url, { headers: authHeaders(credentials) })
+ .then((data) => {
+ if (data.ok) {
+ return data
+ }
+ throw new Error('Error fetching timeline', data)
+ })
.then((data) => data.json())
+ .then((data) => parseStatus(data))
}
const setUserMute = ({id, credentials, muted = true}) => {
@@ -300,13 +325,14 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
notifications: QVITTER_USER_NOTIFICATIONS_URL,
'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
user: QVITTER_USER_TIMELINE_URL,
+ favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
tag: TAG_TIMELINE_URL
}
+ const isNotifications = timeline === 'notifications'
+ const params = []
let url = timelineUrls[timeline]
- let params = []
-
if (since) {
params.push(['since_id', since])
}
@@ -330,9 +356,10 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
if (data.ok) {
return data
}
- throw new Error('Error fetching timeline')
+ throw new Error('Error fetching timeline', data)
})
.then((data) => data.json())
+ .then((data) => data.map(isNotifications ? parseNotification : parseStatus))
}
const verifyCredentials = (user) => {
@@ -340,6 +367,16 @@ const verifyCredentials = (user) => {
method: 'POST',
headers: authHeaders(user)
})
+ .then((response) => {
+ if (response.ok) {
+ return response.json()
+ } else {
+ return {
+ error: response
+ }
+ }
+ })
+ .then((data) => data.error ? data : parseUser(data))
}
const favorite = ({ id, credentials }) => {
@@ -391,6 +428,16 @@ const postStatus = ({credentials, status, spoilerText, visibility, sensitive, me
method: 'POST',
headers: authHeaders(credentials)
})
+ .then((response) => {
+ if (response.ok) {
+ return response.json()
+ } else {
+ return {
+ error: response
+ }
+ }
+ })
+ .then((data) => data.error ? data : parseStatus(data))
}
const deleteStatus = ({ id, credentials }) => {
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
new file mode 100644
index 0000000000..becbab154d
--- /dev/null
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -0,0 +1,273 @@
+const qvitterStatusType = (status) => {
+ 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'
+}
+
+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')
+
+ output.id = String(data.id)
+
+ if (masto) {
+ output.screen_name = data.acct
+
+ // There's nothing else to get
+ if (mastoShort) {
+ return output
+ }
+
+ output.name = null // missing
+ output.name_html = data.display_name
+
+ output.description = null // missing
+ 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
+
+ if (data.pleroma) {
+ const pleroma = data.pleroma
+ output.follows_you = pleroma.follows_you
+ output.statusnet_blocking = pleroma.statusnet_blocking
+ output.muted = pleroma.muted
+ }
+
+ // Missing, trying to recover
+ output.is_local = !output.screen_name.includes('@')
+ } 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
+
+ output.bot = null // missing
+
+ output.statusnet_profile_url = data.statusnet_profile_url
+
+ output.statusnet_blocking = data.statusnet_blocking
+
+ output.is_local = data.is_local
+
+ output.follows_you = data.follows_you
+
+ output.muted = data.muted
+
+ // 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
+ output.hide_network = data.hide_network
+ output.background_image = data.background_image
+ }
+
+ output.created_at = new Date(data.created_at)
+ output.locked = data.locked
+ output.followers_count = data.followers_count
+ output.statuses_count = data.statuses_count
+
+ return output
+}
+
+const parseAttachment = (data) => {
+ 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
+ output.meta = null // missing
+ }
+
+ output.url = data.url
+ output.description = data.description
+
+ return output
+}
+
+export const parseStatus = (data) => {
+ const output = {}
+ const masto = data.hasOwnProperty('account')
+
+ 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
+
+ // Not exactly the same but works?
+ output.text = data.content
+
+ output.in_reply_to_status_id = data.in_reply_to_id
+ output.in_reply_to_user_id = data.in_reply_to_account_id
+
+ // Missing!! fix in UI?
+ output.in_reply_to_screen_name = null
+
+ // Not exactly the same but works
+ output.statusnet_conversation_id = data.id
+
+ if (output.type === 'retweet') {
+ output.retweeted_status = parseStatus(data.reblog)
+ }
+
+ output.summary = data.spoiler_text
+ output.summary_html = data.spoiler_text
+ output.external_url = data.url
+
+ // FIXME missing!!
+ output.is_local = false
+ } 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
+ }
+ } else {
+ output.nsfw = data.nsfw
+ }
+
+ output.statusnet_html = data.statusnet_html
+ output.text = data.text
+
+ output.in_reply_to_status_id = data.in_reply_to_status_id
+ output.in_reply_to_user_id = data.in_reply_to_user_id
+ output.in_reply_to_screen_name = data.in_reply_to_screen_name
+
+ output.statusnet_conversation_id = data.statusnet_conversation_id
+
+ if (output.type === 'retweet') {
+ output.retweeted_status = parseStatus(data.retweeted_status)
+ }
+
+ output.summary = data.summary
+ output.summary_html = data.summary_html
+ output.external_url = data.external_url
+ output.is_local = data.is_local
+ }
+
+ output.id = String(data.id)
+ output.visibility = data.visibility
+ output.created_at = new Date(data.created_at)
+
+ // 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
+
+ output.user = parseUser(masto ? data.account : data.user)
+
+ output.attentions = ((masto ? data.mentions : data.attentions) || []).map(parseUser)
+
+ 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
+}
+
+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
+ output.seen = null // missing
+ output.status = parseStatus(data.status)
+ output.action = output.status // not sure
+ output.from_profile = parseUser(data.account)
+ } else {
+ const parsedNotice = parseStatus(data.notice)
+ output.type = data.ntype
+ output.seen = Boolean(data.is_seen)
+ 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)
+ output.id = String(data.id)
+
+ return output
+}
+
+const isNsfw = (status) => {
+ const nsfwRegex = /#nsfw/i
+ return (status.tags || []).includes('nsfw') || !!status.text.match(nsfwRegex)
+}
diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js
index f5ac0d4766..cd8f3f9efd 100644
--- a/src/services/notification_utils/notification_utils.js
+++ b/src/services/notification_utils/notification_utils.js
@@ -9,9 +9,25 @@ export const visibleTypes = store => ([
store.state.config.notificationVisibility.follows && 'follow'
].filter(_ => _))
+const sortById = (a, b) => {
+ const seqA = Number(a.action.id)
+ const seqB = Number(b.action.id)
+ const isSeqA = !Number.isNaN(seqA)
+ const isSeqB = !Number.isNaN(seqB)
+ if (isSeqA && isSeqB) {
+ return seqA > seqB ? -1 : 1
+ } else if (isSeqA && !isSeqB) {
+ return 1
+ } else if (!isSeqA && isSeqB) {
+ return -1
+ } else {
+ return a.action.id > b.action.id ? -1 : 1
+ }
+}
+
export const visibleNotificationsFromStore = store => {
- // Don't know why, but sortBy([seen, -action.id]) doesn't work.
- let sortedNotifications = sortBy(notificationsFromStore(store), ({action}) => -action.id)
+ // map is just to clone the array since sort mutates it and it causes some issues
+ let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById)
sortedNotifications = sortBy(sortedNotifications, 'seen')
return sortedNotifications.filter((notification) => visibleTypes(store).includes(notification.type))
}
diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js
index 1e20d336e3..f1932bb613 100644
--- a/src/services/status_poster/status_poster.service.js
+++ b/src/services/status_poster/status_poster.service.js
@@ -5,7 +5,6 @@ const postStatus = ({ store, status, spoilerText, visibility, sensitive, media =
const mediaIds = map(media, 'id')
return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType, noAttachmentLinks: store.state.instance.noAttachmentLinks})
- .then((data) => data.json())
.then((data) => {
if (!data.error) {
store.dispatch('addNewStatuses', {
diff --git a/static/config.json b/static/config.json
index cc72900a8f..24e26696fa 100644
--- a/static/config.json
+++ b/static/config.json
@@ -18,5 +18,6 @@
"hideUserStats": false,
"loginMethod": "password",
"webPushNotifications": false,
- "noAttachmentLinks": false
+ "noAttachmentLinks": false,
+ "nsfwCensorImage": ""
}
diff --git a/test/fixtures/mastoapi.json b/test/fixtures/mastoapi.json
new file mode 100644
index 0000000000..858d7a0d32
--- /dev/null
+++ b/test/fixtures/mastoapi.json
@@ -0,0 +1,1582 @@
+[{
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@sampo god i wish i was there",
+ "created_at": "2019-01-17T16:29:23.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10423476",
+ "in_reply_to_account_id": "14660",
+ "in_reply_to_id": "10423197",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "sampo@pleroma.soykaf.com",
+ "id": "14660",
+ "url": "https://pleroma.soykaf.com/users/sampo",
+ "username": "sampo"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639",
+ "url": "https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@feldJotaro - YES YES YES YES YES-sq…",
+ "created_at": "2019-01-17T16:29:12.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10423465",
+ "in_reply_to_account_id": "982",
+ "in_reply_to_id": "10423446",
+ "language": null,
+ "media_attachments": [{
+ "description": "Jotaro - YES YES YES YES YES-sq_Fm7qfRQk.webm",
+ "id": "1104859167",
+ "preview_url": "https://shigusegubu.club/media/4596ab2f-28e6-4f26-83db-0f26f29848cd/Jotaro - YES YES YES YES YES-sq_Fm7qfRQk.webm",
+ "remote_url": "https://shigusegubu.club/media/4596ab2f-28e6-4f26-83db-0f26f29848cd/Jotaro - YES YES YES YES YES-sq_Fm7qfRQk.webm",
+ "text_url": "https://shigusegubu.club/media/4596ab2f-28e6-4f26-83db-0f26f29848cd/Jotaro - YES YES YES YES YES-sq_Fm7qfRQk.webm",
+ "type": "video",
+ "url": "https://shigusegubu.club/media/4596ab2f-28e6-4f26-83db-0f26f29848cd/Jotaro - YES YES YES YES YES-sq_Fm7qfRQk.webm"
+ }],
+ "mentions": [{
+ "acct": "feld@bikeshed.party",
+ "id": "982",
+ "url": "https://bikeshed.party/users/feld",
+ "username": "feld"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 1,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/6634d32b-96a8-4852-a3db-ac8730715779",
+ "url": "https://shigusegubu.club/objects/6634d32b-96a8-4852-a3db-ac8730715779",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "heh
scrot_17-01-19_18-16-40.png",
+ "created_at": "2019-01-17T16:28:49.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10423449",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": "scrot_17-01-19_18-16-40.png",
+ "id": "-804793492",
+ "preview_url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png",
+ "remote_url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png",
+ "text_url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png",
+ "type": "image",
+ "url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png"
+ }],
+ "mentions": [{
+ "acct": "sampo@pleroma.soykaf.com",
+ "id": "14660",
+ "url": "https://pleroma.soykaf.com/users/sampo",
+ "username": "sampo"
+ }],
+ "muted": false,
+ "reblog": {
+ "account": {
+ "acct": "sampo@pleroma.soykaf.com",
+ "avatar": "https://pleroma.soykaf.com/media/f820f4cb-0fc8-4e4d-9521-c896ad2f93b5/c6e8d2e6d471616b82031e8348782e057aee7f1ed3214fe1522415e65694aa07.png",
+ "avatar_static": "https://pleroma.soykaf.com/media/f820f4cb-0fc8-4e4d-9521-c896ad2f93b5/c6e8d2e6d471616b82031e8348782e057aee7f1ed3214fe1522415e65694aa07.png",
+ "bot": false,
+ "created_at": "2018-04-02T21:19:46.000Z",
+ "display_name": "sampo",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 23,
+ "following_count": 7,
+ "header": "https://pleroma.soykaf.com/media/23c3c6e1-863f-4aa2-9711-ab25bfeadd10/6aa0c00c79010d9a735c3e25d7e53da5a9fb4231720b4bd5b6904cd963b4c1cd.png",
+ "header_static": "https://pleroma.soykaf.com/media/23c3c6e1-863f-4aa2-9711-ab25bfeadd10/6aa0c00c79010d9a735c3e25d7e53da5a9fb4231720b4bd5b6904cd963b4c1cd.png",
+ "id": "14660",
+ "locked": false,
+ "note": "welcome to binlan 🇫🇮 prööh",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 17647,
+ "url": "https://pleroma.soykaf.com/users/sampo",
+ "username": "sampo"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "heh
scrot_17-01-19_18-16-40.png",
+ "created_at": "2019-01-17T16:20:06.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 7,
+ "id": "10423197",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": "scrot_17-01-19_18-16-40.png",
+ "id": "-804793492",
+ "preview_url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png",
+ "remote_url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png",
+ "text_url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png",
+ "type": "image",
+ "url": "https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png"
+ }],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 2,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b",
+ "url": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b",
+ "visibility": "public"
+ },
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b",
+ "url": "https://pleroma.soykaf.com/objects/bf7e43d4-5048-4176-8519-58e3e1014f8b",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@feldUhh No.avi-Xrne2-gOoqU.webm",
+ "created_at": "2019-01-17T16:27:29.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10423391",
+ "in_reply_to_account_id": "982",
+ "in_reply_to_id": "10423380",
+ "language": null,
+ "media_attachments": [{
+ "description": "Uhh No.avi-Xrne2-gOoqU.webm",
+ "id": "483179103",
+ "preview_url": "https://shigusegubu.club/media/65de40a9-a99b-4207-97d0-40dd836532db/Uhh No.avi-Xrne2-gOoqU.webm",
+ "remote_url": "https://shigusegubu.club/media/65de40a9-a99b-4207-97d0-40dd836532db/Uhh No.avi-Xrne2-gOoqU.webm",
+ "text_url": "https://shigusegubu.club/media/65de40a9-a99b-4207-97d0-40dd836532db/Uhh No.avi-Xrne2-gOoqU.webm",
+ "type": "video",
+ "url": "https://shigusegubu.club/media/65de40a9-a99b-4207-97d0-40dd836532db/Uhh No.avi-Xrne2-gOoqU.webm"
+ }],
+ "mentions": [{
+ "acct": "feld@bikeshed.party",
+ "id": "982",
+ "url": "https://bikeshed.party/users/feld",
+ "username": "feld"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/0f963ca1-a263-41ca-a43c-b5d26d0a08e9",
+ "url": "https://shigusegubu.club/objects/0f963ca1-a263-41ca-a43c-b5d26d0a08e9",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@fedebot lewd",
+ "created_at": "2019-01-17T16:17:46.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10423144",
+ "in_reply_to_account_id": "16633",
+ "in_reply_to_id": "10423114",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "fedebot@social.super-niche.club",
+ "id": "16633",
+ "url": "https://social.super-niche.club/user/31",
+ "username": "fedebot"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/3f809bd8-656f-4a29-81d4-80eed6916eb0",
+ "url": "https://shigusegubu.club/objects/3f809bd8-656f-4a29-81d4-80eed6916eb0",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "#
animeirl https://social.super-niche.club/attachment/368974",
+ "created_at": "2019-01-17T14:20:42.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10419966",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": null,
+ "id": "1373175917",
+ "preview_url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg",
+ "remote_url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg",
+ "text_url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg",
+ "type": "image",
+ "url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg"
+ }],
+ "mentions": [{
+ "acct": "fedebot@social.super-niche.club",
+ "id": "16633",
+ "url": "https://social.super-niche.club/user/31",
+ "username": "fedebot"
+ }],
+ "muted": false,
+ "reblog": {
+ "account": {
+ "acct": "fedebot@social.super-niche.club",
+ "avatar": "https://social.super-niche.club/avatar/31-300-20180411174535.jpeg",
+ "avatar_static": "https://social.super-niche.club/avatar/31-300-20180411174535.jpeg",
+ "bot": false,
+ "created_at": "2018-04-11T21:08:46.000Z",
+ "display_name": "Federation Bot",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 6,
+ "following_count": 135,
+ "header": "https://shigusegubu.club/images/banner.png",
+ "header_static": "https://shigusegubu.club/images/banner.png",
+ "id": "16633",
+ "locked": false,
+ "note": "",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 6335,
+ "url": "https://social.super-niche.club/user/31",
+ "username": "fedebot"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "#
animeirl https://social.super-niche.club/attachment/368974",
+ "created_at": "2019-01-17T14:11:08.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 4,
+ "id": "10419912",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": null,
+ "id": "1373175917",
+ "preview_url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg",
+ "remote_url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg",
+ "text_url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg",
+ "type": "image",
+ "url": "https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg"
+ }],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 3,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [{
+ "name": "animeirl",
+ "url": "/tag/animeirl"
+ }],
+ "uri": "tag:social.super-niche.club,2019-01-17:noticeId=2353002:objectType=note",
+ "url": "https://social.super-niche.club/notice/2353002",
+ "visibility": "public"
+ },
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [{
+ "name": "animeirl",
+ "url": "/tag/animeirl"
+ }],
+ "uri": "tag:social.super-niche.club,2019-01-17:noticeId=2353002:objectType=note",
+ "url": "tag:social.super-niche.club,2019-01-17:noticeId=2353002:objectType=note",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "ruin a distro in 3 words
image.png",
+ "created_at": "2019-01-17T14:13:36.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10419787",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": "image.png",
+ "id": "-948580066",
+ "preview_url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png",
+ "remote_url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png",
+ "text_url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png",
+ "type": "image",
+ "url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png"
+ }],
+ "mentions": [{
+ "acct": "ivesen@miniwa.moe",
+ "id": "39686",
+ "url": "https://miniwa.moe/users/ivesen",
+ "username": "ivesen"
+ }],
+ "muted": false,
+ "reblog": {
+ "account": {
+ "acct": "ivesen@miniwa.moe",
+ "avatar": "https://miniwa.moe/media/745353b1-89b0-4597-bd76-3ed6ec122c03/504e655c84a6a6d61d34f8daaf3baa6627088f73427763a044729dbf85cff4b8.png",
+ "avatar_static": "https://miniwa.moe/media/745353b1-89b0-4597-bd76-3ed6ec122c03/504e655c84a6a6d61d34f8daaf3baa6627088f73427763a044729dbf85cff4b8.png",
+ "bot": false,
+ "created_at": "2018-09-08T17:55:27.000Z",
+ "display_name": "tsumiki :bun:",
+ "emojis": [{
+ "shortcode": "bun",
+ "static_url": "https://miniwa.moe/emoji/custom/bun.png",
+ "url": "https://miniwa.moe/emoji/custom/bun.png",
+ "visible_in_picker": false
+ }],
+ "fields": [],
+ "followers_count": 8,
+ "following_count": 3,
+ "header": "https://miniwa.moe/media/bff7489f-22bb-4170-a68b-ba0e1c52116e/cf69fbec904a109f8c41b97ec03bfa7dbe49992fd7d61528a933740789b55eb1.gif",
+ "header_static": "https://miniwa.moe/media/bff7489f-22bb-4170-a68b-ba0e1c52116e/cf69fbec904a109f8c41b97ec03bfa7dbe49992fd7d61528a933740789b55eb1.gif",
+ "id": "39686",
+ "locked": false,
+ "note": "native resident of the black lizard planet trying to understand hoomanslocated near niflheimr xmpp: ivesen@xmpp.xyz | matrix: no | email: anything you could imagine @ ivesen.moe",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 13174,
+ "url": "https://miniwa.moe/users/ivesen",
+ "username": "ivesen"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "ruin a distro in 3 words
image.png",
+ "created_at": "2019-01-17T13:41:35.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 3,
+ "id": "10418865",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": "image.png",
+ "id": "-948580066",
+ "preview_url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png",
+ "remote_url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png",
+ "text_url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png",
+ "type": "image",
+ "url": "https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png"
+ }],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 6,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab",
+ "url": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab",
+ "visibility": "public"
+ },
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab",
+ "url": "https://miniwa.moe/objects/448e2944-0ecd-457f-92c3-cb454f2b0fab",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@eal thanks, alex jacobson :denton:",
+ "created_at": "2019-01-17T14:12:42.000Z",
+ "emojis": [{
+ "shortcode": "denton",
+ "static_url": "https://shigusegubu.club/emoji/sgsgb/denton.png",
+ "url": "https://shigusegubu.club/emoji/sgsgb/denton.png",
+ "visible_in_picker": false
+ }],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10419752",
+ "in_reply_to_account_id": "570",
+ "in_reply_to_id": "10419729",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "eal@social.sakamoto.gq",
+ "id": "570",
+ "url": "https://social.sakamoto.gq/users/eal",
+ "username": "eal"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/38b1bc44-15d8-40dd-b1aa-937e0ff4a86d",
+ "url": "https://shigusegubu.club/objects/38b1bc44-15d8-40dd-b1aa-937e0ff4a86d",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@pony yeah",
+ "created_at": "2019-01-17T14:11:01.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10419697",
+ "in_reply_to_account_id": "4395",
+ "in_reply_to_id": "10419694",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "pony@blovice.bahnhof.cz",
+ "id": "4395",
+ "url": "https://blovice.bahnhof.cz/users/pony",
+ "username": "pony"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/fbff5da4-a517-42a9-bca9-17cae8cf2542",
+ "url": "https://shigusegubu.club/objects/fbff5da4-a517-42a9-bca9-17cae8cf2542",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "i probably shouldn't be watchng 4-hour stream vods of joel playing doom",
+ "created_at": "2019-01-17T14:10:34.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10419684",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/4007d659-27c6-4577-be10-fd134f5e4e7e",
+ "url": "https://shigusegubu.club/objects/4007d659-27c6-4577-be10-fd134f5e4e7e",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "i got out of bed.",
+ "created_at": "2019-01-17T14:10:18.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10419671",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/59912d51-1cc6-4dc7-828c-f167e6c8b391",
+ "url": "https://shigusegubu.club/objects/59912d51-1cc6-4dc7-828c-f167e6c8b391",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "New day!",
+ "created_at": "2019-01-17T13:25:56.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 2,
+ "id": "10418390",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 1,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/62690bce-3f49-4047-9c8e-8941f2f79e10",
+ "url": "https://shigusegubu.club/objects/62690bce-3f49-4047-9c8e-8941f2f79e10",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@lanodan you either use nvidia-blob or don't use nvidia. Unless it's a very VERY old GPU.",
+ "created_at": "2019-01-16T22:21:10.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10395196",
+ "in_reply_to_account_id": "27194",
+ "in_reply_to_id": "10394997",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "lanodan@queer.hacktivis.me",
+ "id": "27194",
+ "url": "https://queer.hacktivis.me/users/lanodan",
+ "username": "lanodan"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/818f3dd0-2ff8-4def-a170-e4d4c405f387",
+ "url": "https://shigusegubu.club/objects/818f3dd0-2ff8-4def-a170-e4d4c405f387",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@lain 1. 🔪
2. trigger trypophobia
3. sprinkle with spices
4. pee on it
5. pat pat
6. blanket time
7. bring in the cocaine
8. ?????????????
9. ???? hitler ???????
10. ???????????
11. ???? Adobe After Effects ????
12. !!!!!!!!!!!!!!BREAK IT!!!!!!!!!!!
13. !!!kindar suprize!!
14. (time skip for two hours, realisation that using cocaine was a bad idea)
15. (still not over from cocaine)
16. куличики! Плов, огурцы, это еще что бля
17. fuck it, play it cool, just put meat on the mounds
18. note to self: never use cocaine in culinary ever again",
+ "created_at": "2019-01-16T22:20:50.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10395183",
+ "in_reply_to_account_id": "58",
+ "in_reply_to_id": "10394990",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "lain@pleroma.soykaf.com",
+ "id": "58",
+ "url": "https://pleroma.soykaf.com/users/lain",
+ "username": "lain"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/0783a193-c097-488d-8944-47df9372cd6e",
+ "url": "https://shigusegubu.club/objects/0783a193-c097-488d-8944-47df9372cd6e",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@cathode me too",
+ "created_at": "2019-01-16T22:09:28.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10394697",
+ "in_reply_to_account_id": "55339",
+ "in_reply_to_id": "10394677",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "cathode@pleroma.site",
+ "id": "55339",
+ "url": "https://pleroma.site/users/cathode",
+ "username": "cathode"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/145d5252-7b8e-467d-9f36-1db0818f452f",
+ "url": "https://shigusegubu.club/objects/145d5252-7b8e-467d-9f36-1db0818f452f",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "I love pleroma and lain",
+ "created_at": "2019-01-16T22:09:24.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10394690",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "cathode@pleroma.site",
+ "id": "55339",
+ "url": "https://pleroma.site/users/cathode",
+ "username": "cathode"
+ }],
+ "muted": false,
+ "reblog": {
+ "account": {
+ "acct": "cathode@pleroma.site",
+ "avatar": "https://pleroma.site/media/cc874883-fafb-4f25-80f2-e16677e83621/c50a4ea55a99fdf3b69bf66ce2768bc2c48c6135332914bb49445aab1211d794.gif",
+ "avatar_static": "https://pleroma.site/media/cc874883-fafb-4f25-80f2-e16677e83621/c50a4ea55a99fdf3b69bf66ce2768bc2c48c6135332914bb49445aab1211d794.gif",
+ "bot": false,
+ "created_at": "2018-12-14T21:47:14.000Z",
+ "display_name": "gay hug bug loves you",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 0,
+ "following_count": 0,
+ "header": "https://pleroma.site/media/8170fac2-fc17-4b9c-8624-52491d56f769/8cb558d3960254180b10860012a519253baaa1db88a0476da02be6a558015b34.jpg",
+ "header_static": "https://pleroma.site/media/8170fac2-fc17-4b9c-8624-52491d56f769/8cb558d3960254180b10860012a519253baaa1db88a0476da02be6a558015b34.jpg",
+ "id": "55339",
+ "locked": false,
+ "note": "he/him but you can call me anything really
welcome to my profile :333
https://cathode.neocities.org/",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 16,
+ "url": "https://pleroma.site/users/cathode",
+ "username": "cathode"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "I love pleroma and lain",
+ "created_at": "2019-01-16T22:08:50.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 4,
+ "id": "10394677",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 2,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a",
+ "url": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a",
+ "visibility": "public"
+ },
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a",
+ "url": "https://pleroma.site/objects/3076c055-0e34-4cf9-86ca-2d148b9b694a",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@lain that trick he does in the very beginning with that smile oh my god",
+ "created_at": "2019-01-16T22:08:15.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 2,
+ "id": "10394647",
+ "in_reply_to_account_id": "58",
+ "in_reply_to_id": "10394582",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "lain@pleroma.soykaf.com",
+ "id": "58",
+ "url": "https://pleroma.soykaf.com/users/lain",
+ "username": "lain"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/d4eb7c46-02f9-4b1f-83af-926cefa21f33",
+ "url": "https://shigusegubu.club/objects/d4eb7c46-02f9-4b1f-83af-926cefa21f33",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": ".",
+ "created_at": "2019-01-16T22:08:01.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 0,
+ "id": "10394636",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": null,
+ "id": "-1089888084",
+ "preview_url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm",
+ "remote_url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm",
+ "text_url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm",
+ "type": "video",
+ "url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm"
+ }],
+ "mentions": [{
+ "acct": "lain@pleroma.soykaf.com",
+ "id": "58",
+ "url": "https://pleroma.soykaf.com/users/lain",
+ "username": "lain"
+ }],
+ "muted": false,
+ "reblog": {
+ "account": {
+ "acct": "lain@pleroma.soykaf.com",
+ "avatar": "https://pleroma.soykaf.com/media/57abd080-73da-4541-92c7-506d0008bce3/04c76c19e87b23f759fac1118db5e5c4fe0b0ba8d67942a9a8f4e88108543abd.jpeg",
+ "avatar_static": "https://pleroma.soykaf.com/media/57abd080-73da-4541-92c7-506d0008bce3/04c76c19e87b23f759fac1118db5e5c4fe0b0ba8d67942a9a8f4e88108543abd.jpeg",
+ "bot": false,
+ "created_at": "2017-12-17T22:26:31.000Z",
+ "display_name": "you're looking at an ace",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 29,
+ "following_count": 1389,
+ "header": "https://pleroma.soykaf.com/images/banner.png",
+ "header_static": "https://pleroma.soykaf.com/images/banner.png",
+ "id": "58",
+ "locked": false,
+ "note": "blushy-crushy fediverse idol + pleroma dev.
let's be friends
ぷれろまの生徒会長。謎の外人。日本語OK.
公主病.
I invented the internet.
xmpp: lain@trashserver.net
matrix: lambadalambda@matrix.heldscal.la
pgp: 58B48DE582EE103C964735A1F9C6698E14CCE33C",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 35042,
+ "url": "https://pleroma.soykaf.com/users/lain",
+ "username": "lain"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": ".",
+ "created_at": "2019-01-16T22:06:35.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 2,
+ "id": "10394582",
+ "in_reply_to_account_id": null,
+ "in_reply_to_id": null,
+ "language": null,
+ "media_attachments": [{
+ "description": null,
+ "id": "-1089888084",
+ "preview_url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm",
+ "remote_url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm",
+ "text_url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm",
+ "type": "video",
+ "url": "https://pleroma.soykaf.com/media/d985e90d-b079-4f6a-a5bc-9b5e26b1fa5a/Tusky_1547676391813_2VJ7ITWJ3T.webm"
+ }],
+ "mentions": [],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 1,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733",
+ "url": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733",
+ "visibility": "public"
+ },
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733",
+ "url": "https://pleroma.soykaf.com/objects/338b6bd2-3c2d-40fe-93a3-28b688782733",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@proxeus good song",
+ "created_at": "2019-01-16T22:04:23.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10394506",
+ "in_reply_to_account_id": "17544",
+ "in_reply_to_id": "10393849",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "proxeus@iscute.moe",
+ "id": "17544",
+ "url": "https://iscute.moe/users/proxeus",
+ "username": "proxeus"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/f472f4ed-8b0b-492f-9d53-d69eda79629d",
+ "url": "https://shigusegubu.club/objects/f472f4ed-8b0b-492f-9d53-d69eda79629d",
+ "visibility": "public"
+}, {
+ "account": {
+ "acct": "hj",
+ "avatar": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "avatar_static": "https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png",
+ "bot": false,
+ "created_at": "2017-12-17T21:54:14.000Z",
+ "display_name": "whatever whatever whatever witch",
+ "emojis": [],
+ "fields": [],
+ "followers_count": 705,
+ "following_count": 326,
+ "header": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "header_static": "https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png",
+ "id": "1",
+ "locked": false,
+ "note": "Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it's truly private matter and you're instance's admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.",
+ "pleroma": {
+ "confirmation_pending": false,
+ "tags": null
+ },
+ "source": {
+ "note": "",
+ "privacy": "public",
+ "sensitive": false
+ },
+ "statuses_count": 41775,
+ "url": "https://shigusegubu.club/users/hj",
+ "username": "hj"
+ },
+ "application": {
+ "name": "Web",
+ "website": null
+ },
+ "content": "
@cdmnky olivia been repeating \"hey i moved\" post like once every day or so",
+ "created_at": "2019-01-16T21:56:05.000Z",
+ "emojis": [],
+ "favourited": false,
+ "favourites_count": 1,
+ "id": "10393859",
+ "in_reply_to_account_id": "60913",
+ "in_reply_to_id": "10393808",
+ "language": null,
+ "media_attachments": [],
+ "mentions": [{
+ "acct": "cdmnky",
+ "id": "60913",
+ "url": "https://shigusegubu.club/users/cdmnky",
+ "username": "cdmnky"
+ }],
+ "muted": false,
+ "reblog": null,
+ "reblogged": false,
+ "reblogs_count": 0,
+ "replies_count": 0,
+ "sensitive": false,
+ "spoiler_text": "",
+ "tags": [],
+ "uri": "https://shigusegubu.club/objects/d6fb4fd2-1f6a-4446-a1a6-5edd34050096",
+ "url": "https://shigusegubu.club/objects/d6fb4fd2-1f6a-4446-a1a6-5edd34050096",
+ "visibility": "public"
+}]
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
index 7d403312a1..33628b9b28 100644
--- a/test/unit/specs/modules/statuses.spec.js
+++ b/test/unit/specs/modules/statuses.spec.js
@@ -1,76 +1,31 @@
import { cloneDeep } from 'lodash'
-import { defaultState, mutations, findMaxId, prepareStatus, statusType } from '../../../../src/modules/statuses.js'
+import { defaultState, mutations, prepareStatus } from '../../../../src/modules/statuses.js'
// eslint-disable-next-line camelcase
-const makeMockStatus = ({id, text, is_post_verb = true}) => {
+const makeMockStatus = ({id, text, type = 'status'}) => {
return {
id,
- user: {id: 0},
+ user: {id: '0'},
name: 'status',
text: text || `Text number ${id}`,
fave_num: 0,
uri: '',
- is_post_verb,
+ type,
attentions: []
}
}
-describe('Statuses.statusType', () => {
- it('identifies favorites', () => {
- const fav = {
- uri: 'tag:soykaf.com,2016-08-21:fave:2558:note:339495:2016-08-21T16:54:04+00:00'
- }
-
- const mastoFav = {
- uri: 'tag:mastodon.social,2016-11-27:objectId=73903:objectType=Favourite'
- }
-
- expect(statusType(fav)).to.eql('favorite')
- expect(statusType(mastoFav)).to.eql('favorite')
- })
-})
-
describe('Statuses.prepareStatus', () => {
- it('sets nsfw for statuses with the #nsfw tag', () => {
- const safe = makeMockStatus({id: 1, text: 'Hello oniichan'})
- const nsfw = makeMockStatus({id: 1, text: 'Hello oniichan #nsfw'})
-
- expect(prepareStatus(safe).nsfw).to.eq(false)
- expect(prepareStatus(nsfw).nsfw).to.eq(true)
- })
-
- it('leaves existing nsfw settings alone', () => {
- const nsfw = makeMockStatus({id: 1, text: 'Hello oniichan #nsfw'})
- nsfw.nsfw = false
-
- expect(prepareStatus(nsfw).nsfw).to.eq(false)
- })
-
it('sets deleted flag to false', () => {
- const aStatus = makeMockStatus({id: 1, text: 'Hello oniichan'})
+ const aStatus = makeMockStatus({id: '1', text: 'Hello oniichan'})
expect(prepareStatus(aStatus).deleted).to.eq(false)
})
})
-describe('Statuses.findMaxId', () => {
- it('returns the largest id in any of the given arrays', () => {
- const statusesOne = [{ id: 100 }, { id: 2 }]
- const statusesTwo = [{ id: 3 }]
-
- const maxId = findMaxId(statusesOne, statusesTwo)
- expect(maxId).to.eq(100)
- })
-
- it('returns undefined for empty arrays', () => {
- const maxId = findMaxId([], [])
- expect(maxId).to.eq(undefined)
- })
-})
-
describe('The Statuses module', () => {
it('adds the status to allStatuses and to the given timeline', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
+ const status = makeMockStatus({id: '1'})
mutations.addNewStatuses(state, { statuses: [status], timeline: 'public' })
@@ -82,7 +37,7 @@ describe('The Statuses module', () => {
it('counts the status as new if it has not been seen on this timeline', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
+ const status = makeMockStatus({id: '1'})
mutations.addNewStatuses(state, { statuses: [status], timeline: 'public' })
mutations.addNewStatuses(state, { statuses: [status], timeline: 'friends' })
@@ -100,7 +55,7 @@ describe('The Statuses module', () => {
it('add the statuses to allStatuses if no timeline is given', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
+ const status = makeMockStatus({id: '1'})
mutations.addNewStatuses(state, { statuses: [status] })
@@ -112,7 +67,7 @@ describe('The Statuses module', () => {
it('adds the status to allStatuses and to the given timeline, directly visible', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
+ const status = makeMockStatus({id: '1'})
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
@@ -124,10 +79,10 @@ describe('The Statuses module', () => {
it('removes statuses by tag on deletion', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
- const otherStatus = makeMockStatus({id: 3})
+ const status = makeMockStatus({id: '1'})
+ const otherStatus = makeMockStatus({id: '3'})
status.uri = 'xxx'
- const deletion = makeMockStatus({id: 2, is_post_verb: false})
+ const deletion = makeMockStatus({id: '2', type: 'deletion'})
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
deletion.uri = 'xxx'
@@ -137,36 +92,36 @@ describe('The Statuses module', () => {
expect(state.allStatuses).to.eql([otherStatus])
expect(state.timelines.public.statuses).to.eql([otherStatus])
expect(state.timelines.public.visibleStatuses).to.eql([otherStatus])
- expect(state.timelines.public.maxId).to.eql(3)
+ expect(state.timelines.public.maxId).to.eql('3')
})
it('does not update the maxId when the noIdUpdate flag is set', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
- const secondStatus = makeMockStatus({id: 2})
+ const status = makeMockStatus({id: '1'})
+ const secondStatus = makeMockStatus({id: '2'})
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
- expect(state.timelines.public.maxId).to.eql(1)
+ expect(state.timelines.public.maxId).to.eql('1')
mutations.addNewStatuses(state, { statuses: [secondStatus], showImmediately: true, timeline: 'public', noIdUpdate: true })
expect(state.timelines.public.statuses).to.eql([secondStatus, status])
expect(state.timelines.public.visibleStatuses).to.eql([secondStatus, status])
- expect(state.timelines.public.maxId).to.eql(1)
+ expect(state.timelines.public.maxId).to.eql('1')
})
it('keeps a descending by id order in timeline.visibleStatuses and timeline.statuses', () => {
const state = cloneDeep(defaultState)
- const nonVisibleStatus = makeMockStatus({id: 1})
- const status = makeMockStatus({id: 3})
- const statusTwo = makeMockStatus({id: 2})
- const statusThree = makeMockStatus({id: 4})
+ const nonVisibleStatus = makeMockStatus({id: '1'})
+ const status = makeMockStatus({id: '3'})
+ const statusTwo = makeMockStatus({id: '2'})
+ const statusThree = makeMockStatus({id: '4'})
mutations.addNewStatuses(state, { statuses: [nonVisibleStatus], showImmediately: false, timeline: 'public' })
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
mutations.addNewStatuses(state, { statuses: [statusTwo], showImmediately: true, timeline: 'public' })
- expect(state.timelines.public.minVisibleId).to.equal(2)
+ expect(state.timelines.public.minVisibleId).to.equal('2')
mutations.addNewStatuses(state, { statuses: [statusThree], showImmediately: true, timeline: 'public' })
@@ -176,9 +131,9 @@ describe('The Statuses module', () => {
it('splits retweets from their status and links them', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
- const retweet = makeMockStatus({id: 2, is_post_verb: false})
- const modStatus = makeMockStatus({id: 1, text: 'something else'})
+ const status = makeMockStatus({id: '1'})
+ const retweet = makeMockStatus({id: '2', type: 'retweet'})
+ const modStatus = makeMockStatus({id: '1', text: 'something else'})
retweet.retweeted_status = status
@@ -187,22 +142,22 @@ describe('The Statuses module', () => {
expect(state.timelines.public.visibleStatuses).to.have.length(1)
expect(state.timelines.public.statuses).to.have.length(1)
expect(state.allStatuses).to.have.length(2)
- expect(state.allStatuses[0].id).to.equal(1)
- expect(state.allStatuses[1].id).to.equal(2)
+ expect(state.allStatuses[0].id).to.equal('1')
+ expect(state.allStatuses[1].id).to.equal('2')
// It refers to the modified status.
mutations.addNewStatuses(state, { statuses: [modStatus], timeline: 'public' })
expect(state.allStatuses).to.have.length(2)
- expect(state.allStatuses[0].id).to.equal(1)
+ expect(state.allStatuses[0].id).to.equal('1')
expect(state.allStatuses[0].text).to.equal(modStatus.text)
- expect(state.allStatuses[1].id).to.equal(2)
+ expect(state.allStatuses[1].id).to.equal('2')
expect(retweet.retweeted_status.text).to.eql(modStatus.text)
})
it('replaces existing statuses with the same id', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
- const modStatus = makeMockStatus({id: 1, text: 'something else'})
+ const status = makeMockStatus({id: '1'})
+ const modStatus = makeMockStatus({id: '1', text: 'something else'})
// Add original status
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
@@ -218,9 +173,9 @@ describe('The Statuses module', () => {
it('replaces existing statuses with the same id, coming from a retweet', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
- const modStatus = makeMockStatus({id: 1, text: 'something else'})
- const retweet = makeMockStatus({id: 2, is_post_verb: false})
+ const status = makeMockStatus({id: '1'})
+ const modStatus = makeMockStatus({id: '1', text: 'something else'})
+ const retweet = makeMockStatus({id: '2', type: 'retweet'})
retweet.retweeted_status = modStatus
// Add original status
@@ -239,15 +194,15 @@ describe('The Statuses module', () => {
it('handles favorite actions', () => {
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
+ const status = makeMockStatus({id: '1'})
const favorite = {
- id: 2,
- is_post_verb: false,
+ id: '2',
+ type: 'favorite',
in_reply_to_status_id: '1', // The API uses strings here...
uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
text: 'a favorited something by b',
- user: { id: 99 }
+ user: { id: '99' }
}
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
@@ -266,12 +221,12 @@ describe('The Statuses module', () => {
// If something is favorited by the current user, it also sets the 'favorited' property but does not increment counter to avoid over-counting. Counter is incremented (updated, really) via response to the favorite request.
const user = {
- id: 1
+ id: '1'
}
const ownFavorite = {
- id: 3,
- is_post_verb: false,
+ id: '3',
+ type: 'favorite',
in_reply_to_status_id: '1', // The API uses strings here...
uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
text: 'a favorited something by b',
@@ -287,16 +242,16 @@ describe('The Statuses module', () => {
describe('notifications', () => {
it('removes a notification when the notice gets removed', () => {
- const user = { id: 1 }
+ const user = { id: '1' }
const state = cloneDeep(defaultState)
- const status = makeMockStatus({id: 1})
- const otherStatus = makeMockStatus({id: 3})
- const mentionedStatus = makeMockStatus({id: 2})
+ const status = makeMockStatus({id: '1'})
+ const otherStatus = makeMockStatus({id: '3'})
+ const mentionedStatus = makeMockStatus({id: '2'})
mentionedStatus.attentions = [user]
mentionedStatus.uri = 'xxx'
otherStatus.attentions = [user]
- const deletion = makeMockStatus({id: 4, is_post_verb: false})
+ const deletion = makeMockStatus({id: '4', type: 'deletion'})
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
deletion.uri = 'xxx'
@@ -305,10 +260,12 @@ describe('The Statuses module', () => {
state,
{
notifications: [{
- ntype: 'mention',
+ from_profile: { id: '2' },
+ id: '998',
+ type: 'mention',
status: otherStatus,
- notice: otherStatus,
- is_seen: false
+ action: otherStatus,
+ seen: false
}]
})
@@ -317,10 +274,12 @@ describe('The Statuses module', () => {
state,
{
notifications: [{
- ntype: 'mention',
+ from_profile: { id: '2' },
+ id: '999',
+ type: 'mention',
status: mentionedStatus,
- notice: mentionedStatus,
- is_seen: false
+ action: mentionedStatus,
+ seen: false
}]
})
diff --git a/test/unit/specs/modules/users.spec.js b/test/unit/specs/modules/users.spec.js
index af60c9b399..b0f3c51eeb 100644
--- a/test/unit/specs/modules/users.spec.js
+++ b/test/unit/specs/modules/users.spec.js
@@ -6,8 +6,8 @@ describe('The users module', () => {
describe('mutations', () => {
it('adds new users to the set, merging in new information for old users', () => {
const state = cloneDeep(defaultState)
- const user = { id: 1, name: 'Guy' }
- const modUser = { id: 1, name: 'Dude' }
+ const user = { id: '1', name: 'Guy' }
+ const modUser = { id: '1', name: 'Dude' }
mutations.addNewUsers(state, [user])
expect(state.users).to.have.length(1)
@@ -21,7 +21,7 @@ describe('The users module', () => {
it('sets a mute bit on users', () => {
const state = cloneDeep(defaultState)
- const user = { id: 1, name: 'Guy' }
+ const user = { id: '1', name: 'Guy' }
mutations.addNewUsers(state, [user])
mutations.setMuted(state, {user, muted: true})
@@ -38,11 +38,11 @@ describe('The users module', () => {
it('returns user with matching screen_name', () => {
const state = {
users: [
- { screen_name: 'Guy', id: 1 }
+ { screen_name: 'Guy', id: '1' }
]
}
const name = 'Guy'
- const expected = { screen_name: 'Guy', id: 1 }
+ const expected = { screen_name: 'Guy', id: '1' }
expect(getters.userByName(state)(name)).to.eql(expected)
})
})
@@ -51,11 +51,11 @@ describe('The users module', () => {
it('returns user with matching id', () => {
const state = {
users: [
- { screen_name: 'Guy', id: 1 }
+ { screen_name: 'Guy', id: '1' }
]
}
- const id = 1
- const expected = { screen_name: 'Guy', id: 1 }
+ const id = '1'
+ const expected = { screen_name: 'Guy', id: '1' }
expect(getters.userById(state)(id)).to.eql(expected)
})
})
diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
new file mode 100644
index 0000000000..703fecf1c8
--- /dev/null
+++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
@@ -0,0 +1,270 @@
+import { parseStatus, parseUser, parseNotification } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
+import mastoapidata from '../../../../fixtures/mastoapi.json'
+import qvitterapidata from '../../../../fixtures/statuses.json'
+
+const makeMockStatusQvitter = (overrides = {}) => {
+ return Object.assign({
+ activity_type: 'post',
+ attachments: [],
+ attentions: [],
+ created_at: 'Tue Jan 15 13:57:56 +0000 2019',
+ external_url: 'https://ap.example/whatever',
+ fave_num: 1,
+ favorited: false,
+ id: '10335970',
+ in_reply_to_ostatus_uri: null,
+ in_reply_to_profileurl: null,
+ in_reply_to_screen_name: null,
+ in_reply_to_status_id: null,
+ in_reply_to_user_id: null,
+ is_local: false,
+ is_post_verb: true,
+ possibly_sensitive: false,
+ repeat_num: 0,
+ repeated: false,
+ statusnet_conversation_id: '16300488',
+ statusnet_html: '
haha benis
',
+ summary: null,
+ tags: [],
+ text: 'haha benis',
+ uri: 'https://ap.example/whatever',
+ user: makeMockUserQvitter(),
+ visibility: 'public'
+ }, overrides)
+}
+
+const makeMockUserQvitter = (overrides = {}) => {
+ return Object.assign({
+ background_image: null,
+ cover_photo: '',
+ created_at: 'Mon Jan 14 13:56:51 +0000 2019',
+ default_scope: 'public',
+ description: 'ebin',
+ description_html: '
ebin
',
+ favourites_count: 0,
+ fields: [],
+ followers_count: 1,
+ following: true,
+ follows_you: true,
+ friends_count: 1,
+ id: '60717',
+ is_local: false,
+ locked: false,
+ name: 'Spurdo :ebin:',
+ name_html: 'Spurdo
',
+ no_rich_text: false,
+ pleroma: { confirmation_pending: false, tags: [] },
+ profile_image_url: 'https://ap.example/whatever',
+ profile_image_url_https: 'https://ap.example/whatever',
+ profile_image_url_original: 'https://ap.example/whatever',
+ profile_image_url_profile_size: 'https://ap.example/whatever',
+ rights: { delete_others_notice: false },
+ screen_name: 'spurdo@ap.example',
+ statuses_count: 46,
+ statusnet_blocking: false,
+ statusnet_profile_url: ''
+ }, overrides)
+}
+
+const makeMockUserMasto = (overrides = {}) => {
+ return Object.assign({
+ acct: 'hj',
+ avatar:
+ 'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
+ avatar_static:
+ 'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
+ bot: false,
+ created_at: '2017-12-17T21:54:14.000Z',
+ display_name: 'whatever whatever whatever witch',
+ emojis: [],
+ fields: [],
+ followers_count: 705,
+ following_count: 326,
+ header:
+ 'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
+ header_static:
+ 'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
+ id: '1',
+ locked: false,
+ note:
+ 'Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is
@hj:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it\'s truly private matter and you\'re instance\'s admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.',
+ pleroma: { confirmation_pending: false, tags: null },
+ source: { note: '', privacy: 'public', sensitive: false },
+ statuses_count: 41775,
+ url: 'https://shigusegubu.club/users/hj',
+ username: 'hj'
+ }, overrides)
+}
+
+const makeMockStatusMasto = (overrides = {}) => {
+ return Object.assign({
+ account: makeMockUserMasto(),
+ application: { name: 'Web', website: null },
+ content:
+ '
@sampo god i wish i was there',
+ created_at: '2019-01-17T16:29:23.000Z',
+ emojis: [],
+ favourited: false,
+ favourites_count: 1,
+ id: '10423476',
+ in_reply_to_account_id: '14660',
+ in_reply_to_id: '10423197',
+ language: null,
+ media_attachments: [],
+ mentions: [
+ {
+ acct: 'sampo@pleroma.soykaf.com',
+ id: '14660',
+ url: 'https://pleroma.soykaf.com/users/sampo',
+ username: 'sampo'
+ }
+ ],
+ muted: false,
+ reblog: null,
+ reblogged: false,
+ reblogs_count: 0,
+ replies_count: 0,
+ sensitive: false,
+ spoiler_text: '',
+ tags: [],
+ uri: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
+ url: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
+ visibility: 'public'
+ }, overrides)
+}
+
+const makeMockNotificationQvitter = (overrides = {}) => {
+ return Object.assign({
+ notice: makeMockStatusQvitter(),
+ ntype: 'follow',
+ from_profile: makeMockUserQvitter(),
+ is_seen: 0,
+ id: 123
+ }, overrides)
+}
+
+parseNotification
+parseUser
+parseStatus
+makeMockStatusQvitter
+makeMockUserQvitter
+
+describe('API Entities normalizer', () => {
+ describe('parseStatus', () => {
+ describe('QVitter preprocessing', () => {
+ it('doesn\'t blow up', () => {
+ const parsed = qvitterapidata.map(parseStatus)
+ expect(parsed.length).to.eq(qvitterapidata.length)
+ })
+
+ it('identifies favorites', () => {
+ const fav = {
+ uri: 'tag:soykaf.com,2016-08-21:fave:2558:note:339495:2016-08-21T16:54:04+00:00',
+ is_post_verb: false
+ }
+
+ const mastoFav = {
+ uri: 'tag:mastodon.social,2016-11-27:objectId=73903:objectType=Favourite',
+ is_post_verb: false
+ }
+
+ expect(parseStatus(makeMockStatusQvitter(fav))).to.have.property('type', 'favorite')
+ expect(parseStatus(makeMockStatusQvitter(mastoFav))).to.have.property('type', 'favorite')
+ })
+
+ it('processes repeats correctly', () => {
+ const post = makeMockStatusQvitter({ retweeted_status: null, id: 'deadbeef' })
+ const repeat = makeMockStatusQvitter({ retweeted_status: post, is_post_verb: false, id: 'foobar' })
+
+ const parsedPost = parseStatus(post)
+ const parsedRepeat = parseStatus(repeat)
+
+ expect(parsedPost).to.have.property('type', 'status')
+ expect(parsedRepeat).to.have.property('type', 'retweet')
+ expect(parsedRepeat).to.have.property('retweeted_status')
+ expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef')
+ })
+
+ it('sets nsfw for statuses with the #nsfw tag', () => {
+ const safe = makeMockStatusQvitter({id: '1', text: 'Hello oniichan'})
+ const nsfw = makeMockStatusQvitter({id: '1', text: 'Hello oniichan #nsfw'})
+
+ expect(parseStatus(safe).nsfw).to.eq(false)
+ expect(parseStatus(nsfw).nsfw).to.eq(true)
+ })
+
+ it('leaves existing nsfw settings alone', () => {
+ const nsfw = makeMockStatusQvitter({id: '1', text: 'Hello oniichan #nsfw', nsfw: false})
+
+ expect(parseStatus(nsfw).nsfw).to.eq(false)
+ })
+ })
+
+ describe('Mastoapi preprocessing and converting', () => {
+ it('doesn\'t blow up', () => {
+ const parsed = mastoapidata.map(parseStatus)
+ expect(parsed.length).to.eq(mastoapidata.length)
+ })
+
+ it('processes repeats correctly', () => {
+ const post = makeMockStatusMasto({ reblog: null, id: 'deadbeef' })
+ const repeat = makeMockStatusMasto({ reblog: post, id: 'foobar' })
+
+ const parsedPost = parseStatus(post)
+ const parsedRepeat = parseStatus(repeat)
+
+ expect(parsedPost).to.have.property('type', 'status')
+ expect(parsedRepeat).to.have.property('type', 'retweet')
+ expect(parsedRepeat).to.have.property('retweeted_status')
+ expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef')
+ })
+ })
+ })
+
+ // Statuses generally already contain some info regarding users and there's nearly 1:1 mapping, so very little to test
+ describe('parseUsers (MastoAPI)', () => {
+ it('sets correct is_local for users depending on their screen_name', () => {
+ const local = makeMockUserMasto({ acct: 'foo' })
+ const remote = makeMockUserMasto({ acct: 'foo@bar.baz' })
+
+ expect(parseUser(local)).to.have.property('is_local', true)
+ expect(parseUser(remote)).to.have.property('is_local', false)
+ })
+ })
+
+ // We currently use QvitterAPI notifications only, and especially due to MastoAPI lacking is_seen, support for MastoAPI
+ // is more of an afterthought
+ describe('parseNotifications (QvitterAPI)', () => {
+ it('correctly normalizes data to FE\'s format', () => {
+ const notif = makeMockNotificationQvitter({
+ id: 123,
+ notice: makeMockStatusQvitter({ id: 444 }),
+ from_profile: makeMockUserQvitter({ id: 'spurdo' })
+ })
+ expect(parseNotification(notif)).to.have.property('id', '123')
+ expect(parseNotification(notif)).to.have.property('seen', false)
+ expect(parseNotification(notif)).to.have.deep.property('status.id', '444')
+ expect(parseNotification(notif)).to.have.deep.property('action.id', '444')
+ expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo')
+ })
+
+ it('correctly normalizes favorite notifications', () => {
+ const notif = makeMockNotificationQvitter({
+ id: 123,
+ ntype: 'like',
+ notice: makeMockStatusQvitter({
+ id: 444,
+ favorited_status: makeMockStatusQvitter({ id: 4412 })
+ }),
+ is_seen: 1,
+ from_profile: makeMockUserQvitter({ id: 'spurdo' })
+ })
+ expect(parseNotification(notif)).to.have.property('id', '123')
+ expect(parseNotification(notif)).to.have.property('type', 'like')
+ expect(parseNotification(notif)).to.have.property('seen', true)
+ expect(parseNotification(notif)).to.have.deep.property('status.id', '4412')
+ expect(parseNotification(notif)).to.have.deep.property('action.id', '444')
+ expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo')
+ })
+ })
+})
diff --git a/test/unit/specs/services/notification_utils/notification_utils.spec.js b/test/unit/specs/services/notification_utils/notification_utils.spec.js
index c44b8c9e0d..e945459edd 100644
--- a/test/unit/specs/services/notification_utils/notification_utils.spec.js
+++ b/test/unit/specs/services/notification_utils/notification_utils.spec.js
@@ -9,15 +9,15 @@ describe('NotificationUtils', () => {
notifications: {
data: [
{
- action: { id: 1 },
+ action: { id: '1' },
type: 'like'
},
{
- action: { id: 2 },
+ action: { id: '2' },
type: 'mention'
},
{
- action: { id: 3 },
+ action: { id: '3' },
type: 'repeat'
}
]
@@ -34,11 +34,11 @@ describe('NotificationUtils', () => {
}
const expected = [
{
- action: { id: 3 },
+ action: { id: '3' },
type: 'repeat'
},
{
- action: { id: 1 },
+ action: { id: '1' },
type: 'like'
}
]
@@ -54,12 +54,12 @@ describe('NotificationUtils', () => {
notifications: {
data: [
{
- action: { id: 1 },
+ action: { id: '1' },
type: 'like',
seen: false
},
{
- action: { id: 2 },
+ action: { id: '2' },
type: 'mention',
seen: true
}
@@ -77,7 +77,7 @@ describe('NotificationUtils', () => {
}
const expected = [
{
- action: { id: 1 },
+ action: { id: '1' },
type: 'like',
seen: false
}