From ef04a786344ff50cdfeefc79722dafd9c52dbf86 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 16 Aug 2018 13:12:31 +0300 Subject: [PATCH] added workaround for broken favorites --- src/modules/api.js | 4 ++ src/modules/statuses.js | 37 +++++++++++++++---- src/modules/users.js | 2 + src/services/api/api.service.js | 3 ++ .../backend_interactor_service.js | 11 ++++++ .../timeline_fetcher.service.js | 4 +- 6 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/modules/api.js b/src/modules/api.js index a61340c2..20586f5c 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -46,6 +46,10 @@ const api = { store.commit('addFetcher', {timeline, fetcher}) } }, + fetchOldPost (store, { postId }) { + console.log(store) + store.state.backendInteractor.fetchOldPost({ store, postId }) + }, stopFetching (store, timeline) { const fetcher = store.state.fetchers[timeline] window.clearInterval(fetcher) diff --git a/src/modules/statuses.js b/src/modules/statuses.js index bc3799dd..bd6b968f 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -27,7 +27,8 @@ export const defaultState = { maxId: 0, maxSavedId: 0, minId: Number.POSITIVE_INFINITY, - data: [] + data: [], + brokenFavorites: {} }, favorites: new Set(), error: false, @@ -35,6 +36,7 @@ export const defaultState = { mentions: emptyTl(), public: emptyTl(), user: emptyTl(), + own: emptyTl(), publicAndExternal: emptyTl(), friends: emptyTl(), tag: emptyTl() @@ -140,6 +142,12 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us const result = mergeOrAdd(allStatuses, allStatusesObject, status) status = result.item + const brokenFavorites = state.notifications.brokenFavorites[status.id] || [] + brokenFavorites.forEach((fav) => { + fav.status = status + }) + delete state.notifications.brokenFavorites[status.id] + if (result.new) { // We are mentioned in a post if (statusType(status) === 'status' && find(status.attentions, { id: user.id })) { @@ -174,7 +182,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us return status } - const favoriteStatus = (favorite) => { + const favoriteStatus = (favorite, counter) => { const status = find(allStatuses, { id: toInteger(favorite.in_reply_to_status_id) }) if (status) { status.fave_num += 1 @@ -258,7 +266,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } } -const addNewNotifications = (state, { notifications, older }) => { +const addNewNotifications = (state, { dispatch, notifications, older }) => { const allStatuses = state.allStatuses each(notifications, (notification) => { const action = notification.notice @@ -267,18 +275,31 @@ const addNewNotifications = (state, { notifications, older }) => { state.notifications.maxId = Math.max(notification.id, state.notifications.maxId) state.notifications.minId = Math.min(notification.id, state.notifications.minId) - console.log(notification) const fresh = !older && !notification.is_seen && notification.id > state.notifications.maxSavedId const status = notification.ntype === 'like' ? find(allStatuses, { id: action.in_reply_to_status_id }) : action - state.notifications.data.push({ + + const result = { type: notification.ntype, status, action, // Always assume older notifications as seen seen: !fresh - }) + } + + if (notification.ntype === 'like' && !status) { + let broken = state.notifications.brokenFavorites[action.in_reply_to_status_id] + if (broken) { + broken.push(result) + } else { + dispatch('fetchOldPost', { postId: action.in_reply_to_status_id }) + broken = [ result ] + state.notifications.brokenFavorites[action.in_reply_to_status_id] = broken + } + } + + state.notifications.data.push(result) if ('Notification' in window && window.Notification.permission === 'granted') { const title = action.user.name @@ -370,8 +391,8 @@ const statuses = { addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false }) { commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser }) }, - addNewNotifications ({ rootState, commit }, { notifications, older }) { - commit('addNewNotifications', { notifications, older }) + addNewNotifications ({ rootState, commit, dispatch }, { notifications, older }) { + commit('addNewNotifications', { dispatch, notifications, older }) }, setError ({ rootState, commit }, { value }) { commit('setError', { value }) diff --git a/src/modules/users.js b/src/modules/users.js index 8303ecc1..03686c60 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -103,6 +103,8 @@ const users = { // Start getting fresh tweets. store.dispatch('startFetching', 'friends') + // Start getting our own posts, only really needed for mitigating broken favorites + store.dispatch('startFetching', ['own', user.id]) // Get user mutes and follower info store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 9a09e503..351f88ca 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -305,6 +305,9 @@ 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, + // separate timeline for own posts, so it won't break due to user timeline bugs + // really needed only for broken favorites + own: QVITTER_USER_TIMELINE_URL, tag: TAG_TIMELINE_URL } diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index dbfb54f9..f65ad43e 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -54,6 +54,16 @@ const backendInteractorService = (credentials) => { return timelineFetcherService.startFetching({timeline, store, credentials, userId}) } + const fetchOldPost = ({store, postId}) => { + return timelineFetcherService.fetchAndUpdate({ + store, + credentials, + timeline: 'own', + older: true, + until: postId + }) + } + const setUserMute = ({id, muted = true}) => { return apiService.setUserMute({id, muted, credentials}) } @@ -86,6 +96,7 @@ const backendInteractorService = (credentials) => { fetchAllFollowing, verifyCredentials: apiService.verifyCredentials, startFetching, + fetchOldPost, setUserMute, fetchMutes, register, diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index bb5fdc2e..0e3e32d2 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -14,13 +14,13 @@ const update = ({store, statuses, timeline, showImmediately}) => { }) } -const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false, userId = false, tag = false}) => { +const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false, userId = false, tag = false, until}) => { const args = { timeline, credentials } const rootState = store.rootState || store.state const timelineData = rootState.statuses.timelines[camelCase(timeline)] if (older) { - args['until'] = timelineData.minVisibleId + args['until'] = until || timelineData.minVisibleId } else { args['since'] = timelineData.maxId }