Page MenuHomePhorge

No OneTemporary

Size
31 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/chat_panel/chat_panel.js b/src/components/chat_panel/chat_panel.js
index d528d0a1bf..d8736d17b0 100644
--- a/src/components/chat_panel/chat_panel.js
+++ b/src/components/chat_panel/chat_panel.js
@@ -1,25 +1,25 @@
const chatPanel = {
data () {
return {
currentMessage: '',
channel: null,
- collapsed: false
+ collapsed: true
}
},
computed: {
messages () {
return this.$store.state.chat.messages
}
},
methods: {
submit (message) {
this.$store.state.chat.channel.push('new_msg', {text: message}, 10000)
this.currentMessage = ''
},
togglePanel () {
this.collapsed = !this.collapsed
}
}
}
export default chatPanel
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index bd52f161b5..b493c212ad 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,398 +1,398 @@
import { includes, remove, slice, sortBy, toInteger, each, find, flatten, 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 = () => ({
statuses: [],
statusesObject: {},
faves: [],
visibleStatuses: [],
visibleStatusesObject: {},
newStatusCount: 0,
maxId: 0,
minVisibleId: 0,
loading: false,
followers: [],
friends: [],
viewing: 'statuses',
flushMarker: 0
})
export const defaultState = {
allStatuses: [],
allStatusesObject: {},
maxId: 0,
notifications: [],
favorites: new Set(),
error: false,
timelines: {
mentions: emptyTl(),
public: emptyTl(),
user: emptyTl(),
publicAndExternal: emptyTl(),
friends: emptyTl(),
tag: emptyTl()
}
}
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.retweeted_status.nsfw = status.nsfw
+ status.nsfw = status.retweeted_status.nsfw
}
}
// Set deleted flag
status.deleted = false
// To make the array reactive
status.attachments = status.attachments || []
return status
}
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'
}
// TODO change to status.activity_type === 'follow' when gs supports it
if (status.text.match(/started following/)) {
return 'follow'
}
return 'unknown'
}
export const findMaxId = (...args) => {
return (maxBy(flatten(args), 'id') || {}).id
}
const mergeOrAdd = (arr, obj, item) => {
const oldItem = obj[item.id]
if (oldItem) {
// We already have this, so only merge the new info.
merge(oldItem, item)
// Reactivity fix.
oldItem.attachments.splice(oldItem.attachments.length)
return {item: oldItem, new: false}
} else {
// This is a new item, prepare it
prepareStatus(item)
arr.push(item)
obj[item.id] = item
return {item, new: true}
}
}
const sortTimeline = (timeline) => {
timeline.visibleStatuses = sortBy(timeline.visibleStatuses, ({id}) => -id)
timeline.statuses = sortBy(timeline.statuses, ({id}) => -id)
timeline.minVisibleId = (last(timeline.visibleStatuses) || {}).id
return timeline
}
const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {}, noIdUpdate = false }) => {
// Sanity check
if (!isArray(statuses)) {
return false
}
const allStatuses = state.allStatuses
const allStatusesObject = state.allStatusesObject
const timelineObject = state.timelines[timeline]
const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0
const older = timeline && maxNew < timelineObject.maxId
if (timeline && !noIdUpdate && statuses.length > 0 && !older) {
timelineObject.maxId = maxNew
}
const addStatus = (status, showImmediately, addToTimeline = true) => {
const result = mergeOrAdd(allStatuses, allStatusesObject, status)
status = result.item
if (result.new) {
if (statusType(status) === 'retweet' && status.retweeted_status.user.id === user.id) {
- addNotification({ type: 'repeat', status: status.retweeted_status, action: status })
+ addNotification({ type: 'repeat', status: status, action: status })
}
// We are mentioned in a post
if (statusType(status) === 'status' && find(status.attentions, { id: user.id })) {
const mentions = state.timelines.mentions
// Add the mention to the mentions timeline
if (timelineObject !== mentions) {
mergeOrAdd(mentions.statuses, mentions.statusesObject, status)
mentions.newStatusCount += 1
sortTimeline(mentions)
}
// Don't add notification for self-mention
if (status.user.id !== user.id) {
addNotification({ type: 'mention', status, action: status })
}
}
}
// Decide if we should treat the status as new for this timeline.
let resultForCurrentTimeline
// Some statuses should only be added to the global status repository.
if (timeline && addToTimeline) {
resultForCurrentTimeline = mergeOrAdd(timelineObject.statuses, timelineObject.statusesObject, status)
}
if (timeline && showImmediately) {
// Add it directly to the visibleStatuses, don't change
// newStatusCount
mergeOrAdd(timelineObject.visibleStatuses, timelineObject.visibleStatusesObject, status)
} else if (timeline && addToTimeline && resultForCurrentTimeline.new) {
// Just change newStatuscount
timelineObject.newStatusCount += 1
}
return status
}
const addNotification = ({type, status, action}) => {
// Only add a new notification if we don't have one for the same action
if (!find(state.notifications, (oldNotification) => oldNotification.action.id === action.id)) {
state.notifications.push({ type, status, action, seen: false })
if ('Notification' in window && window.Notification.permission === 'granted') {
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
// 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
}
let notification = new window.Notification(title, result)
// Chrome is known for not closing notifications automatically
// according to MDN, anyway.
setTimeout(notification.close.bind(notification), 5000)
}
}
}
const favoriteStatus = (favorite) => {
const status = find(allStatuses, { id: toInteger(favorite.in_reply_to_status_id) })
if (status) {
status.fave_num += 1
// This is our favorite, so the relevant bit.
if (favorite.user.id === user.id) {
status.favorited = true
}
// Add a notification if the user's status is favorited
if (status.user.id === user.id) {
addNotification({type: 'favorite', status, action: favorite})
}
}
return status
}
const processors = {
'status': (status) => {
addStatus(status, showImmediately)
},
'retweet': (status) => {
// RetweetedStatuses are never shown immediately
const retweetedStatus = addStatus(status.retweeted_status, false, false)
let retweet
// If the retweeted status is already there, don't add the retweet
// to the timeline.
if (timeline && find(timelineObject.statuses, (s) => {
if (s.retweeted_status) {
return s.id === retweetedStatus.id || s.retweeted_status.id === retweetedStatus.id
} else {
return s.id === retweetedStatus.id
}
})) {
// Already have it visible (either as the original or another RT), don't add to timeline, don't show.
retweet = addStatus(status, false, false)
} else {
retweet = addStatus(status, showImmediately)
}
retweet.retweeted_status = retweetedStatus
},
'favorite': (favorite) => {
// Only update if this is a new favorite.
if (!state.favorites.has(favorite.id)) {
state.favorites.add(favorite.id)
favoriteStatus(favorite)
}
},
'follow': (status) => {
let re = new RegExp(`started following ${user.name} \\(${user.statusnet_profile_url}\\)`)
let repleroma = new RegExp(`started following ${user.screen_name}$`)
if (status.text.match(re) || status.text.match(repleroma)) {
addNotification({ type: 'follow', status: status, action: status })
}
},
'deletion': (deletion) => {
const uri = deletion.uri
// Remove possible notification
const status = find(allStatuses, {uri})
if (!status) {
return
}
remove(state.notifications, ({action: {id}}) => id === status.id)
remove(allStatuses, { uri })
if (timeline) {
remove(timelineObject.statuses, { uri })
remove(timelineObject.visibleStatuses, { uri })
}
},
'default': (unknown) => {
console.log('unknown status type')
console.log(unknown)
}
}
each(statuses, (status) => {
const type = statusType(status)
const processor = processors[type] || processors['default']
processor(status)
})
// Keep the visible statuses sorted
if (timeline) {
sortTimeline(timelineObject)
if ((older || timelineObject.minVisibleId <= 0) && statuses.length > 0) {
timelineObject.minVisibleId = minBy(statuses, 'id').id
}
}
}
export const mutations = {
addNewStatuses,
showNewStatuses (state, { timeline }) {
const oldTimeline = (state.timelines[timeline])
oldTimeline.newStatusCount = 0
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
oldTimeline.minVisibleId = last(oldTimeline.visibleStatuses).id
oldTimeline.visibleStatusesObject = {}
each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status })
},
clearTimeline (state, { timeline }) {
state.timelines[timeline] = emptyTl()
},
setFavorited (state, { status, value }) {
const newStatus = state.allStatusesObject[status.id]
newStatus.favorited = value
},
setRetweeted (state, { status, value }) {
const newStatus = state.allStatusesObject[status.id]
newStatus.repeated = value
},
setDeleted (state, { status }) {
const newStatus = state.allStatusesObject[status.id]
newStatus.deleted = true
},
setLoading (state, { timeline, value }) {
state.timelines[timeline].loading = value
},
setNsfw (state, { id, nsfw }) {
const newStatus = state.allStatusesObject[id]
newStatus.nsfw = nsfw
},
setError (state, { value }) {
state.error = value
},
setProfileView (state, { v }) {
// load followers / friends only when needed
state.timelines['user'].viewing = v
},
addFriends (state, { friends }) {
state.timelines['user'].friends = friends
},
addFollowers (state, { followers }) {
state.timelines['user'].followers = followers
},
markNotificationsAsSeen (state, notifications) {
each(notifications, (notification) => {
notification.seen = true
})
},
queueFlush (state, { timeline, id }) {
state.timelines[timeline].flushMarker = id
}
}
const statuses = {
state: defaultState,
actions: {
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false }) {
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser })
},
setError ({ rootState, commit }, { value }) {
commit('setError', { value })
},
addFriends ({ rootState, commit }, { friends }) {
commit('addFriends', { friends })
},
addFollowers ({ rootState, commit }, { followers }) {
commit('addFollowers', { followers })
},
deleteStatus ({ rootState, commit }, status) {
commit('setDeleted', { status })
apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
favorite ({ rootState, commit }, status) {
// Optimistic favoriting...
commit('setFavorited', { status, value: true })
apiService.favorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
unfavorite ({ rootState, commit }, status) {
// Optimistic favoriting...
commit('setFavorited', { status, value: false })
apiService.unfavorite({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
retweet ({ rootState, commit }, status) {
// Optimistic retweeting...
commit('setRetweeted', { status, value: true })
apiService.retweet({ id: status.id, credentials: rootState.users.currentUser.credentials })
},
queueFlush ({ rootState, commit }, { timeline, id }) {
commit('queueFlush', { timeline, id })
}
},
mutations
}
export default statuses
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
index 372d1aaa62..f929192b90 100644
--- a/test/unit/specs/modules/statuses.spec.js
+++ b/test/unit/specs/modules/statuses.spec.js
@@ -1,426 +1,426 @@
import { cloneDeep } from 'lodash'
import { defaultState, mutations, findMaxId, prepareStatus, statusType } from '../../../../src/modules/statuses.js'
// eslint-disable-next-line camelcase
const makeMockStatus = ({id, text, is_post_verb = true}) => {
return {
id,
user: {id: 0},
name: 'status',
text: text || `Text number ${id}`,
fave_num: 0,
uri: '',
is_post_verb,
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'})
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})
mutations.addNewStatuses(state, { statuses: [status], timeline: 'public' })
expect(state.allStatuses).to.eql([status])
expect(state.timelines.public.statuses).to.eql([status])
expect(state.timelines.public.visibleStatuses).to.eql([])
expect(state.timelines.public.newStatusCount).to.equal(1)
})
it('counts the status as new if it has not been seen on this timeline', () => {
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
mutations.addNewStatuses(state, { statuses: [status], timeline: 'public' })
mutations.addNewStatuses(state, { statuses: [status], timeline: 'friends' })
expect(state.allStatuses).to.eql([status])
expect(state.timelines.public.statuses).to.eql([status])
expect(state.timelines.public.visibleStatuses).to.eql([])
expect(state.timelines.public.newStatusCount).to.equal(1)
expect(state.allStatuses).to.eql([status])
expect(state.timelines.friends.statuses).to.eql([status])
expect(state.timelines.friends.visibleStatuses).to.eql([])
expect(state.timelines.friends.newStatusCount).to.equal(1)
})
it('add the statuses to allStatuses if no timeline is given', () => {
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
mutations.addNewStatuses(state, { statuses: [status] })
expect(state.allStatuses).to.eql([status])
expect(state.timelines.public.statuses).to.eql([])
expect(state.timelines.public.visibleStatuses).to.eql([])
expect(state.timelines.public.newStatusCount).to.equal(0)
})
it('adds the status to allStatuses and to the given timeline, directly visible', () => {
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
expect(state.allStatuses).to.eql([status])
expect(state.timelines.public.statuses).to.eql([status])
expect(state.timelines.public.visibleStatuses).to.eql([status])
expect(state.timelines.public.newStatusCount).to.equal(0)
})
it('removes statuses by tag on deletion', () => {
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
const otherStatus = makeMockStatus({id: 3})
status.uri = 'xxx'
const deletion = makeMockStatus({id: 2, is_post_verb: false})
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
deletion.uri = 'xxx'
mutations.addNewStatuses(state, { statuses: [status, otherStatus], showImmediately: true, timeline: 'public' })
mutations.addNewStatuses(state, { statuses: [deletion], showImmediately: true, timeline: 'public' })
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)
})
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})
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
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)
})
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})
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)
mutations.addNewStatuses(state, { statuses: [statusThree], showImmediately: true, timeline: 'public' })
expect(state.timelines.public.statuses).to.eql([statusThree, status, statusTwo, nonVisibleStatus])
expect(state.timelines.public.visibleStatuses).to.eql([statusThree, status, statusTwo])
})
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'})
retweet.retweeted_status = status
// It adds both statuses, but only the retweet to visible.
mutations.addNewStatuses(state, { statuses: [retweet], timeline: 'public', showImmediately: true })
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)
// 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].text).to.equal(modStatus.text)
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'})
// Add original status
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
expect(state.timelines.public.visibleStatuses).to.have.length(1)
expect(state.allStatuses).to.have.length(1)
// Add new version of status
mutations.addNewStatuses(state, { statuses: [modStatus], showImmediately: true, timeline: 'public' })
expect(state.timelines.public.visibleStatuses).to.have.length(1)
expect(state.allStatuses).to.have.length(1)
expect(state.allStatuses[0].text).to.eql(modStatus.text)
})
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})
retweet.retweeted_status = modStatus
// Add original status
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
expect(state.timelines.public.visibleStatuses).to.have.length(1)
expect(state.allStatuses).to.have.length(1)
// Add new version of status
mutations.addNewStatuses(state, { statuses: [retweet], showImmediately: false, timeline: 'public' })
expect(state.timelines.public.visibleStatuses).to.have.length(1)
// Don't add the retweet itself if the tweet is visible
expect(state.timelines.public.statuses).to.have.length(1)
expect(state.allStatuses).to.have.length(2)
expect(state.allStatuses[0].text).to.eql(modStatus.text)
})
it('handles favorite actions', () => {
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
const favorite = {
id: 2,
is_post_verb: false,
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: {}
}
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
mutations.addNewStatuses(state, { statuses: [favorite], showImmediately: true, timeline: 'public' })
expect(state.timelines.public.visibleStatuses.length).to.eql(1)
expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
expect(state.timelines.public.maxId).to.eq(favorite.id)
// Adding it again does nothing
mutations.addNewStatuses(state, { statuses: [favorite], showImmediately: true, timeline: 'public' })
expect(state.timelines.public.visibleStatuses.length).to.eql(1)
expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
expect(state.timelines.public.maxId).to.eq(favorite.id)
// If something is favorited by the current user, it also sets the 'favorited' property
const user = {
id: 1
}
const ownFavorite = {
id: 3,
is_post_verb: false,
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
}
mutations.addNewStatuses(state, { statuses: [ownFavorite], showImmediately: true, timeline: 'public', user })
expect(state.timelines.public.visibleStatuses.length).to.eql(1)
expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(2)
expect(state.timelines.public.visibleStatuses[0].favorited).to.eql(true)
})
describe('notifications', () => {
it('adds a notfications for retweets if you are the retweetet', () => {
const user = { id: 1 }
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
status.user = user
const retweet = makeMockStatus({id: 2, is_post_verb: false})
retweet.retweeted_status = status
mutations.addNewStatuses(state, { statuses: [retweet], user })
expect(state.notifications.length).to.eql(1)
- expect(state.notifications[0].status).to.eql(status)
+ expect(state.notifications[0].status).to.eql(retweet)
expect(state.notifications[0].action).to.eql(retweet)
expect(state.notifications[0].type).to.eql('repeat')
})
it('adds a notification when you are mentioned', () => {
const user = { id: 1 }
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
const mentionedStatus = makeMockStatus({id: 2})
mentionedStatus.attentions = [user]
mutations.addNewStatuses(state, { statuses: [status], user })
expect(state.notifications.length).to.eql(0)
mutations.addNewStatuses(state, { statuses: [mentionedStatus], user })
expect(state.notifications.length).to.eql(1)
expect(state.notifications[0].status).to.eql(mentionedStatus)
expect(state.notifications[0].action).to.eql(mentionedStatus)
expect(state.notifications[0].type).to.eql('mention')
})
it('removes a notification when the notice gets removed', () => {
const user = { id: 1 }
const state = cloneDeep(defaultState)
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})
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
deletion.uri = 'xxx'
mutations.addNewStatuses(state, { statuses: [status, otherStatus], user })
expect(state.notifications.length).to.eql(1)
mutations.addNewStatuses(state, { statuses: [mentionedStatus], user })
expect(state.allStatuses.length).to.eql(3)
expect(state.notifications.length).to.eql(2)
expect(state.notifications[1].status).to.eql(mentionedStatus)
expect(state.notifications[1].action).to.eql(mentionedStatus)
expect(state.notifications[1].type).to.eql('mention')
mutations.addNewStatuses(state, { statuses: [deletion], user })
expect(state.allStatuses.length).to.eql(2)
expect(state.notifications.length).to.eql(1)
})
it('adds the message to mentions when you are mentioned', () => {
const user = { id: 1 }
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
const mentionedStatus = makeMockStatus({id: 2})
mentionedStatus.attentions = [user]
mutations.addNewStatuses(state, { statuses: [status], user })
expect(state.timelines.mentions.statuses).to.have.length(0)
mutations.addNewStatuses(state, { statuses: [mentionedStatus], user })
expect(state.timelines.mentions.statuses).to.have.length(1)
expect(state.timelines.mentions.statuses).to.eql([mentionedStatus])
})
it('adds a notfication when one of the user\'s status is favorited', () => {
const state = cloneDeep(defaultState)
const status = makeMockStatus({id: 1})
const user = {id: 1}
status.user = user
const favorite = {
id: 2,
is_post_verb: false,
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: {}
}
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public', user })
mutations.addNewStatuses(state, { statuses: [favorite], showImmediately: true, timeline: 'public', user })
expect(state.notifications).to.have.length(1)
})
it('adds a notification when the user is followed', () => {
const state = cloneDeep(defaultState)
const user = {id: 1, screen_name: 'b'}
const follower = {id: 2, screen_name: 'a'}
const follow = {
id: 3,
is_post_verb: false,
activity_type: 'follow',
text: 'a started following b',
user: follower
}
mutations.addNewStatuses(state, { statuses: [follow], showImmediately: true, timeline: 'public', user })
expect(state.notifications).to.have.length(1)
})
it('does not add a notification when an other user is followed', () => {
const state = cloneDeep(defaultState)
const user = {id: 1, screen_name: 'b'}
const follower = {id: 2, screen_name: 'a'}
const follow = {
id: 3,
is_post_verb: false,
activity_type: 'follow',
text: 'a started following b@shitposter.club',
user: follower
}
mutations.addNewStatuses(state, { statuses: [follow], showImmediately: true, timeline: 'public', user })
expect(state.notifications).to.have.length(0)
})
})
})

File Metadata

Mime Type
text/x-diff
Expires
Fri, Aug 28, 9:56 AM (3 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1736342
Default Alt Text
(31 KB)

Event Timeline