akkoma-fe/src/modules/statuses.js

164 lines
4.7 KiB
JavaScript
Raw Normal View History

2016-10-28 13:59:49 +00:00
import { map, slice, last, intersectionBy, sortBy, unionBy, toInteger, groupBy, differenceBy, each, find } from 'lodash'
import moment from 'moment'
2016-10-30 15:12:35 +00:00
import apiService from '../services/api/api.service.js'
2016-10-26 17:03:55 +00:00
export const defaultState = {
2016-10-26 17:03:55 +00:00
allStatuses: [],
maxId: 0,
timelines: {
public: {
statuses: [],
faves: [],
visibleStatuses: [],
newStatusCount: 0,
maxId: 0,
2016-11-06 16:44:05 +00:00
minVisibleId: 0,
loading: false
2016-10-26 17:03:55 +00:00
},
publicAndExternal: {
statuses: [],
faves: [],
visibleStatuses: [],
newStatusCount: 0,
maxId: 0,
2016-11-06 16:44:05 +00:00
minVisibleId: 0,
loading: false
2016-10-26 17:03:55 +00:00
},
friends: {
statuses: [],
faves: [],
visibleStatuses: [],
newStatusCount: 0,
maxId: 0,
2016-11-06 16:44:05 +00:00
minVisibleId: 0,
loading: false
2016-10-26 17:03:55 +00:00
}
}
}
const statusType = (status) => {
return !status.is_post_verb && status.uri.match(/fave/) ? 'fave' : 'status'
}
2016-11-06 16:44:05 +00:00
const addStatusesToTimeline = (addedStatuses, showImmediately, { statuses, visibleStatuses, newStatusCount, faves, loading }) => {
2016-10-26 17:03:55 +00:00
const statusesAndFaves = groupBy(addedStatuses, statusType)
const addedFaves = statusesAndFaves['fave'] || []
const unseenFaves = differenceBy(addedFaves, faves, 'id')
// Update fave count
each(unseenFaves, ({in_reply_to_status_id}) => {
const status = find(statuses, { id: toInteger(in_reply_to_status_id) })
if (status) {
status.fave_num += 1
}
})
addedStatuses = statusesAndFaves['status'] || []
2016-10-28 23:38:41 +00:00
// Add some html and nsfw to the statuses.
2016-10-26 17:03:55 +00:00
each(addedStatuses, (status) => {
const statusoid = status.retweeted_status || status
2016-10-31 09:20:02 +00:00
statusoid.created_at_parsed = statusoid.created_at
2016-10-26 17:03:55 +00:00
if (statusoid.parsedText === undefined) {
// statusoid.parsedText = statusParserService.parse(statusoid)
statusoid.parsedText = statusoid.text
}
2016-10-28 23:38:41 +00:00
if (statusoid.nsfw === undefined) {
const nsfwRegex = /#nsfw/i
statusoid.nsfw = statusoid.text.match(nsfwRegex)
}
2016-10-26 17:03:55 +00:00
})
const newStatuses = sortBy(
unionBy(addedStatuses, statuses, 'id'),
({id}) => -id
)
let newNewStatusCount = newStatusCount + (newStatuses.length - statuses.length)
let newVisibleStatuses = visibleStatuses
if (showImmediately) {
newVisibleStatuses = unionBy(addedStatuses, newVisibleStatuses, 'id')
newVisibleStatuses = sortBy(newVisibleStatuses, ({id}) => -id)
newNewStatusCount = newStatusCount
};
newVisibleStatuses = intersectionBy(newStatuses, newVisibleStatuses, 'id')
return {
statuses: newStatuses,
visibleStatuses: newVisibleStatuses,
newStatusCount: newNewStatusCount,
maxId: newStatuses[0].id,
2016-10-27 16:03:14 +00:00
minVisibleId: (last(newVisibleStatuses) || { id: undefined }).id,
2016-11-06 16:44:05 +00:00
faves: unionBy(faves, addedFaves, 'id'),
loading
2016-10-26 17:03:55 +00:00
}
}
2016-10-28 13:59:49 +00:00
const updateTimestampsInStatuses = (statuses) => {
2016-10-28 23:38:41 +00:00
return map(statuses, (statusoid) => {
const status = statusoid.retweeted_status || statusoid
2016-10-28 13:59:49 +00:00
// Parse date
status.created_at_parsed = moment(status.created_at).fromNow()
return status
})
}
export const mutations = {
addNewStatuses (state, { statuses, showImmediately = false, timeline }) {
state.timelines[timeline] = addStatusesToTimeline(statuses, showImmediately, state.timelines[timeline])
state.allStatuses = unionBy(state.timelines[timeline].statuses, state.allStatuses.id)
},
showNewStatuses (state, { timeline }) {
const oldTimeline = (state.timelines[timeline])
oldTimeline.newStatusCount = 0
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
},
updateTimestamps (state) {
updateTimestampsInStatuses(state.allStatuses)
},
setFavorited (state, { status, value }) {
const newStatus = find(state.allStatuses, status)
newStatus.favorited = value
},
setLoading (state, { timeline, value }) {
state.timelines[timeline].loading = value
},
setNsfw (state, { id, nsfw }) {
// For now, walk through all the statuses because the stuff might be in the replied_to_status
// TODO: Save the replied_tos as references.
each(state.allStatuses, (statusoid) => {
const status = statusoid.retweeted_status || statusoid
if (status.id === id) {
status.nsfw = nsfw
}
})
}
}
2016-10-26 17:03:55 +00:00
const statuses = {
state: defaultState,
2016-10-30 15:12:35 +00:00
actions: {
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 })
}
},
mutations
2016-10-26 17:03:55 +00:00
}
export default statuses