diff options
Diffstat (limited to 'src/modules/statuses.js')
| -rw-r--r-- | src/modules/statuses.js | 127 |
1 files changed, 40 insertions, 87 deletions
diff --git a/src/modules/statuses.js b/src/modules/statuses.js index c564dec1..baeef8bf 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -1,8 +1,8 @@ -import { includes, remove, slice, each, find, 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 = () => ({ +export const emptyTl = (tl, userId = 0) => (Object.assign(tl, { statuses: [], statusesObject: {}, faves: [], @@ -14,9 +14,9 @@ const emptyTl = () => ({ loading: false, followers: [], friends: [], - userId: 0, - flushMarker: 0 -}) + flushMarker: 0, + userId +})) export const defaultState = { allStatuses: [], @@ -33,30 +33,17 @@ export const defaultState = { favorites: new Set(), error: false, timelines: { - mentions: emptyTl(), - public: emptyTl(), - user: emptyTl(), - publicAndExternal: emptyTl(), - friends: emptyTl(), - tag: emptyTl(), - dms: emptyTl() + mentions: emptyTl({ type: 'mentions' }), + public: emptyTl({ type: 'public' }), + user: emptyTl({ type: 'user' }), // TODO: switch to unregistered + publicAndExternal: emptyTl({ type: 'publicAndExternal' }), + friends: emptyTl({ type: 'friends' }), + tag: emptyTl({ type: 'tag' }), + dms: emptyTl({ type: 'dms' }) } } -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,31 +62,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' -} - const mergeOrAdd = (arr, obj, item) => { // For sequential IDs BE passes numbers as numbers, we want them as strings. item.id = String(item.id) @@ -138,7 +100,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us const allStatuses = state.allStatuses const allStatusesObject = state.allStatusesObject - const timelineObject = state.timelines[timeline] + const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline] const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0 const older = timeline && maxNew < timelineObject.maxId @@ -154,13 +116,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 @@ -264,6 +226,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) @@ -271,7 +236,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) }) @@ -289,15 +254,11 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot const allStatuses = state.allStatuses const allStatusesObject = state.allStatusesObject each(notifications, (notification) => { - notification.notice.id = String(notification.notice.id) - const result = mergeOrAdd(allStatuses, allStatusesObject, notification.notice) - const action = result.item - // For sequential IDs BE passes numbers as numbers, we want them as strings. - action.id = String(action.id) + 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 - // TODO: this technically works but should be checking for notification.id, not action.id i think - if (!find(state.notifications.data, (oldNotification) => oldNotification.action.id === action.id)) { + if (!state.notifications.idStore.hasOwnProperty(notification.id)) { state.notifications.maxId = notification.id > state.notifications.maxId ? notification.id : state.notifications.maxId @@ -305,35 +266,24 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot ? notification.id : state.notifications.minId - const fresh = !notification.is_seen - const status = notification.ntype === 'like' - ? action.favorited_status - : action - - const result = { - type: notification.ntype, - status, - action, - seen: !fresh - } - - state.notifications.data.push(result) - state.notifications.idStore[notification.id] = result + state.notifications.data.push(notification) + state.notifications.idStore[notification.id] = notification if ('Notification' in window && window.Notification.permission === 'granted') { + const notifObj = {} + const action = notification.action const title = action.user.name - const result = {} - result.icon = action.user.profile_image_url - result.body = action.text // there's a problem that it doesn't put a space before links tho + notifObj.icon = action.user.profile_image_url + notifObj.body = action.text // there's a problem that it doesn't put a space before links tho // Shows first attached non-nsfw image, if any. Should add configuration for this somehow... if (action.attachments && action.attachments.length > 0 && !action.nsfw && action.attachments[0].mimetype.startsWith('image/')) { - result.image = action.attachments[0].url + notifObj.image = action.attachments[0].url } - if (fresh && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.ntype)) { - let notification = new window.Notification(title, result) + if (notification.fresh && !state.notifications.desktopNotificationSilence && visibleNotificationTypes.includes(notification.ntype)) { + let notification = new window.Notification(title, notifObj) // Chrome is known for not closing notifications automatically // according to MDN, anyway. setTimeout(notification.close.bind(notification), 5000) @@ -347,7 +297,7 @@ export const mutations = { addNewStatuses, addNewNotifications, showNewStatuses (state, { timeline }) { - const oldTimeline = (state.timelines[timeline]) + const oldTimeline = (typeof timeline === 'object' ? timeline : state.timelines[timeline]) oldTimeline.newStatusCount = 0 oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50) @@ -356,7 +306,8 @@ export const mutations = { each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status }) }, clearTimeline (state, { timeline }) { - state.timelines[timeline] = emptyTl() + const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline] + emptyTl(timelineObject, timeline.userId) }, setFavorited (state, { status, value }) { const newStatus = state.allStatusesObject[status.id] @@ -376,7 +327,8 @@ export const mutations = { newStatus.deleted = true }, setLoading (state, { timeline, value }) { - state.timelines[timeline].loading = value + const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline] + timelineObject.loading = value }, setNsfw (state, { id, nsfw }) { const newStatus = state.allStatusesObject[id] @@ -397,7 +349,8 @@ export const mutations = { }) }, queueFlush (state, { timeline, id }) { - state.timelines[timeline].flushMarker = id + const timelineObject = typeof timeline === 'object' ? timeline : state.timelines[timeline] + timelineObject.flushMarker = id } } |
