commit: 3a3cf1d48a67c82bb2c94cafb0150b1fa8e4de1a
parent: 7651290e2be72ed35d7582757251eb151fdce953
Author: HJ <spam@hjkos.com>
Date: Tue, 22 Jan 2019 17:46:08 +0000
Merge branch 'favorites' into 'develop'
Add Favorites TL to user profile, add some initial support for MastoAPI
Closes #265 and #262
See merge request pleroma/pleroma-fe!462
Diffstat:
19 files changed, 2361 insertions(+), 252 deletions(-)
diff --git a/src/components/conversation-page/conversation-page.js b/src/components/conversation-page/conversation-page.js
@@ -1,5 +1,5 @@
import Conversation from '../conversation/conversation.vue'
-import { find, toInteger } from 'lodash'
+import { find } from 'lodash'
const conversationPage = {
components: {
@@ -7,7 +7,7 @@ const conversationPage = {
},
computed: {
statusoid () {
- const id = toInteger(this.$route.params.id)
+ const id = this.$route.params.id
const statuses = this.$store.state.statuses.allStatuses
const status = find(statuses, {id})
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
@@ -1,9 +1,8 @@
import { reduce, filter, sortBy } from 'lodash'
-import { statusType } from '../../modules/statuses.js'
import Status from '../status/status.vue'
const sortAndFilterConversation = (conversation) => {
- conversation = filter(conversation, (status) => statusType(status) !== 'retweet')
+ conversation = filter(conversation, (status) => status.type !== 'retweet')
return sortBy(conversation, 'id')
}
@@ -18,10 +17,12 @@ const conversation = {
'collapsable'
],
computed: {
- status () { return this.statusoid },
+ status () {
+ return this.statusoid
+ },
conversation () {
if (!this.status) {
- return false
+ return []
}
const conversationId = this.status.statusnet_conversation_id
@@ -32,7 +33,9 @@ const conversation = {
replies () {
let i = 1
return reduce(this.conversation, (result, {id, in_reply_to_status_id}) => {
- const irid = Number(in_reply_to_status_id)
+ /* eslint-disable camelcase */
+ const irid = in_reply_to_status_id
+ /* eslint-enable camelcase */
if (irid) {
result[irid] = result[irid] || []
result[irid].push({
@@ -69,7 +72,6 @@ const conversation = {
}
},
getReplies (id) {
- id = Number(id)
return this.replies[id] || []
},
focused (id) {
@@ -80,7 +82,7 @@ const conversation = {
}
},
setHighlight (id) {
- this.highlight = Number(id)
+ this.highlight = id
}
}
}
diff --git a/src/components/status/status.js b/src/components/status/status.js
@@ -129,7 +129,7 @@ const Status = {
if (this.status.user.id === this.$store.state.users.currentUser.id) {
return false
}
- if (this.status.activity_type === 'repeat') {
+ if (this.status.type === 'retweet') {
return false
}
var checkFollowing = this.$store.state.config.replyVisibility === 'following'
@@ -258,7 +258,7 @@ const Status = {
},
replyEnter (id, event) {
this.showPreview = true
- const targetId = Number(id)
+ const targetId = id
const statuses = this.$store.state.statuses.allStatuses
if (!this.preview) {
@@ -283,7 +283,6 @@ const Status = {
},
watch: {
'highlight': function (id) {
- id = Number(id)
if (this.status.id === id) {
let rect = this.$el.getBoundingClientRect()
if (rect.top < 100) {
diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx
@@ -6,18 +6,26 @@ export default Vue.component('tab-switcher', {
name: 'TabSwitcher',
data () {
return {
- active: 0
+ active: this.$slots.default.findIndex(_ => _.tag)
}
},
methods: {
- activateTab(index) {
- return () => this.active = index;
+ activateTab (index) {
+ return () => {
+ this.active = index
+ }
}
},
- render(h) {
+ beforeUpdate () {
+ const currentSlot = this.$slots.default[this.active]
+ if (!currentSlot.tag) {
+ this.active = this.$slots.default.findIndex(_ => _.tag)
+ }
+ },
+ render (h) {
const tabs = this.$slots.default
- .filter(slot => slot.data)
.map((slot, index) => {
+ if (!slot.tag) return
const classesTab = ['tab']
const classesWrapper = ['tab-wrapper']
@@ -25,20 +33,24 @@ export default Vue.component('tab-switcher', {
classesTab.push('active')
classesWrapper.push('active')
}
+
return (
<div class={ classesWrapper.join(' ')}>
<button onClick={this.activateTab(index)} class={ classesTab.join(' ') }>{slot.data.attrs.label}</button>
</div>
)
- });
- const contents = this.$slots.default.filter(_=>_.data).map(( slot, index ) => {
+ })
+
+ const contents = this.$slots.default.map((slot, index) => {
+ if (!slot.tag) return
const active = index === this.active
return (
<div class={active ? 'active' : 'hidden'}>
{slot}
</div>
)
- });
+ })
+
return (
<div class="tab-switcher">
<div class="tabs">
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
@@ -5,24 +5,33 @@ import Timeline from '../timeline/timeline.vue'
const UserProfile = {
created () {
this.$store.commit('clearTimeline', { timeline: 'user' })
+ this.$store.commit('clearTimeline', { timeline: 'favorites' })
this.$store.dispatch('startFetching', ['user', this.fetchBy])
+ this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
if (!this.user.id) {
this.$store.dispatch('fetchUser', this.fetchBy)
}
},
destroyed () {
this.$store.dispatch('stopFetching', 'user')
+ this.$store.dispatch('stopFetching', 'favorites')
},
computed: {
timeline () {
return this.$store.state.statuses.timelines.user
},
+ favorites () {
+ return this.$store.state.statuses.timelines.favorites
+ },
userId () {
return this.$route.params.id || this.user.id
},
userName () {
return this.$route.params.name || this.user.screen_name
},
+ isUs () {
+ return this.userId === this.$store.state.users.currentUser.id
+ },
friends () {
return this.user.friends
},
@@ -62,21 +71,28 @@ const UserProfile = {
}
},
watch: {
+ // TODO get rid of this copypasta
userName () {
if (this.isExternal) {
return
}
this.$store.dispatch('stopFetching', 'user')
+ this.$store.dispatch('stopFetching', 'favorites')
this.$store.commit('clearTimeline', { timeline: 'user' })
+ this.$store.commit('clearTimeline', { timeline: 'favorites' })
this.$store.dispatch('startFetching', ['user', this.fetchBy])
+ this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
},
userId () {
if (!this.isExternal) {
return
}
this.$store.dispatch('stopFetching', 'user')
+ this.$store.dispatch('stopFetching', 'favorites')
this.$store.commit('clearTimeline', { timeline: 'user' })
+ this.$store.commit('clearTimeline', { timeline: 'favorites' })
this.$store.dispatch('startFetching', ['user', this.fetchBy])
+ this.$store.dispatch('startFetching', ['favorites', this.fetchBy])
},
user () {
if (this.user.id && !this.user.followers) {
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
@@ -20,6 +20,7 @@
<i class="icon-spin3 animate-spin"></i>
</div>
</div>
+ <Timeline v-if="isUs" :label="$t('user_card.favorites')" :embedded="true" :title="$t('user_profile.favorites_title')" timeline-name="favorites" :timeline="favorites"/>
</tab-switcher>
</div>
<div v-else class="panel user-profile-placeholder">
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -324,6 +324,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
@@ -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
@@ -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,11 @@ const mergeOrAdd = (arr, obj, item) => {
}
}
+const sortById = (a, b) => 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 +114,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 +161,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 +224,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,7 +234,7 @@ 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)
})
@@ -288,42 +252,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)
-
- const fresh = !notification.is_seen
- const status = notification.ntype === 'like'
- ? action.favorited_status
- : action
-
- const result = {
- type: notification.ntype,
- status,
- action,
- seen: !fresh
- }
+ 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
- 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 +304,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
@@ -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
@@ -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',
@@ -237,24 +243,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 +276,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 +324,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 +355,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 +366,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 +427,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
@@ -0,0 +1,263 @@
+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.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.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)
+
+ 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
@@ -10,8 +10,8 @@ export const visibleTypes = store => ([
].filter(_ => _))
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((a, b) => a.action.id > b.action.id ? -1 : 1)
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
@@ -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/test/fixtures/mastoapi.json 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"14660\" href=\"https://pleroma.soykaf.com/users/sampo\">@<span>sampo</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"982\" href=\"https://bikeshed.party/users/feld\">@<span>feld</span></a></span><br /><a href=\"https://shigusegubu.club/media/4596ab2f-28e6-4f26-83db-0f26f29848cd/Jotaro - YES YES YES YES YES-sq_Fm7qfRQk.webm\">Jotaro - YES YES YES YES YES-sq…</a>",
+ "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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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<br /><a href=\"https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png\">scrot_17-01-19_18-16-40.png</a>",
+ "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<br /><a href=\"https://pleroma.soykaf.com/media/fd13d009-2c1f-4a53-9762-257e592a7ff6/scrot_17-01-19_18-16-40.png\">scrot_17-01-19_18-16-40.png</a>",
+ "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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"982\" href=\"https://bikeshed.party/users/feld\">@<span>feld</span></a></span><br /><a href=\"https://shigusegubu.club/media/65de40a9-a99b-4207-97d0-40dd836532db/Uhh No.avi-Xrne2-gOoqU.webm\">Uhh No.avi-Xrne2-gOoqU.webm</a>",
+ "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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"16633\" href=\"https://social.super-niche.club/user/31\">@<span>fedebot</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "#<span><a href=\"https://social.super-niche.club/tag/animeirl\">animeirl</a></span> <a href=\"https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg\" title=\"https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg\">https://social.super-niche.club/attachment/368974</a>",
+ "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": "#<span><a href=\"https://social.super-niche.club/tag/animeirl\">animeirl</a></span> <a href=\"https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg\" title=\"https://social.super-niche.club/file/c366cae1e5820d68dc1e6bc7a06a2f2bc15166de1faabea4f060490d45fdf527.jpg\">https://social.super-niche.club/attachment/368974</a>",
+ "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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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<br /><a href=\"https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png\">image.png</a>",
+ "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<br /><a href=\"https://miniwa.moe/media/4076945a-4a3b-4fb3-8b62-04eb401697ff/image.png\">image.png</a>",
+ "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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"570\" href=\"https://social.sakamoto.gq/users/eal\">@<span>eal</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"4395\" href=\"https://blovice.bahnhof.cz/users/pony\">@<span>pony</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"27194\" href=\"https://queer.hacktivis.me/users/lanodan\">@<span>lanodan</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"58\" href=\"https://pleroma.soykaf.com/users/lain\">@<span>lain</span></a></span> <br />1. 🔪<br />2. trigger trypophobia<br />3. sprinkle with spices<br />4. pee on it<br />5. pat pat<br />6. blanket time<br />7. bring in the cocaine<br />8. ?????????????<br />9. ???? hitler ???????<br />10. ???????????<br />11. ???? Adobe After Effects ????<br />12. !!!!!!!!!!!!!!BREAK IT!!!!!!!!!!!<br />13. !!!kindar suprize!!<br />14. (time skip for two hours, realisation that using cocaine was a bad idea)<br />15. (still not over from cocaine)<br />16. куличики! Плов, огурцы, это еще что бля<br />17. fuck it, play it cool, just put meat on the mounds<br />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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"55339\" href=\"https://pleroma.site/users/cathode\">@<span>cathode</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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<br /><br />welcome to my profile :333<br /><br /><a href=\"https://cathode.neocities.org/\">https://cathode.neocities.org/</a>",
+ "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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"58\" href=\"https://pleroma.soykaf.com/users/lain\">@<span>lain</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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.<br />let's be friends <br />ぷれろまの生徒会長。謎の外人。日本語OK. <br />公主病.<br />I invented the internet.<br />xmpp: lain@trashserver.net<br />matrix: lambadalambda@matrix.heldscal.la<br />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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"17544\" href=\"https://iscute.moe/users/proxeus\">@<span>proxeus</span></a></span> 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 <span><a data-user=\"1\" href=\"https://shigusegubu.club/users/hj\">@<span>hj</span></a></span>: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": "<span><a data-user=\"60913\" href=\"https://shigusegubu.club/users/cdmnky\">@<span>cdmnky</span></a></span> 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
@@ -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
@@ -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
@@ -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: '<p>haha benis</p>',
+ 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: '<p>ebin</p>',
+ 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 <img src="whatever">',
+ 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 <span><a data-user="1" href="https://shigusegubu.club/users/hj">@<span>hj</span></a></span>: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:
+ '<span><a data-user="14660" href="https://pleroma.soykaf.com/users/sampo">@<span>sampo</span></a></span> 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
@@ -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
}