update fav boost accounts for stale views (#510)
This commit is contained in:
parent
6d50c65352
commit
01b1d083a9
|
@ -12,9 +12,22 @@ import {
|
|||
getTimeline as getTimelineFromDatabase
|
||||
} from '../_database/timelines/pagination'
|
||||
import { getStatus, getStatusContext } from '../_api/statuses'
|
||||
import { emit } from '../_utils/eventBus'
|
||||
|
||||
const FETCH_LIMIT = 20
|
||||
|
||||
async function storeFreshTimelineItemsInDatabase (instanceName, timelineName, items) {
|
||||
await insertTimelineItemsInDatabase(instanceName, timelineName, items)
|
||||
if (timelineName.startsWith('status/')) {
|
||||
// For status threads, we want to be sure to update the favorite/reblog counts even if
|
||||
// this is a stale "view" of the status. See 119-status-counts-update.js for
|
||||
// an example of why we need this.
|
||||
items.forEach(item => {
|
||||
emit('statusUpdated', item)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchTimelineItemsFromNetwork (instanceName, accessToken, timelineName, lastTimelineItemId) {
|
||||
if (timelineName.startsWith('status/')) { // special case - this is a list of descendents and ancestors
|
||||
let statusId = timelineName.split('/').slice(-1)[0]
|
||||
|
@ -37,7 +50,7 @@ async function fetchTimelineItems (instanceName, accessToken, timelineName, last
|
|||
} else {
|
||||
try {
|
||||
items = await fetchTimelineItemsFromNetwork(instanceName, accessToken, timelineName, lastTimelineItemId)
|
||||
/* no await */ insertTimelineItemsInDatabase(instanceName, timelineName, items)
|
||||
/* no await */ storeFreshTimelineItemsInDatabase(instanceName, timelineName, items)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast.say('Internet request failed. Showing offline content.')
|
||||
|
|
|
@ -133,16 +133,43 @@
|
|||
import ExternalLink from '../ExternalLink.html'
|
||||
import { store } from '../../_store/store'
|
||||
import { getDateFormatter, getShortDateFormatter } from '../../_utils/formatters'
|
||||
import { on } from '../../_utils/eventBus'
|
||||
|
||||
export default {
|
||||
oncreate () {
|
||||
let { originalStatusId } = this.get()
|
||||
on('statusUpdated', this, status => {
|
||||
if (status.id === originalStatusId) {
|
||||
this.set({
|
||||
overrideNumReblogs: status.reblogs_count || 0,
|
||||
overrideNumFavs: status.favourites_count || 0
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
store: () => store,
|
||||
data: () => ({
|
||||
overrideNumReblogs: void 0,
|
||||
overrideNumFavs: void 0
|
||||
}),
|
||||
computed: {
|
||||
originalStatusId: ({ originalStatus }) => originalStatus.id,
|
||||
application: ({ originalStatus }) => originalStatus.application,
|
||||
applicationName: ({ application }) => (application && application.name),
|
||||
applicationWebsite: ({ application }) => (application && application.website),
|
||||
createdAtDate: ({ originalStatus }) => originalStatus.created_at,
|
||||
numReblogs: ({ originalStatus }) => originalStatus.reblogs_count || 0,
|
||||
numFavs: ({ originalStatus }) => originalStatus.favourites_count || 0,
|
||||
numReblogs: ({ overrideNumReblogs, originalStatus }) => {
|
||||
if (typeof overrideNumReblogs === 'number') {
|
||||
return overrideNumReblogs
|
||||
}
|
||||
return originalStatus.reblogs_count || 0
|
||||
},
|
||||
numFavs: ({ overrideNumFavs, originalStatus }) => {
|
||||
if (typeof overrideNumFavs === 'number') {
|
||||
return overrideNumFavs
|
||||
}
|
||||
return originalStatus.favourites_count || 0
|
||||
},
|
||||
formattedDate: ({ createdAtDate, $isMobileSize }) => {
|
||||
let formatter = $isMobileSize ? getShortDateFormatter() : getDateFormatter()
|
||||
return formatter.format(new Date(createdAtDate))
|
||||
|
|
|
@ -7,6 +7,7 @@ import { deleteStatus } from '../routes/_api/delete'
|
|||
import { authorizeFollowRequest, getFollowRequests } from '../routes/_actions/followRequests'
|
||||
import { followAccount, unfollowAccount } from '../routes/_api/follow'
|
||||
import { updateCredentials } from '../routes/_api/updateCredentials'
|
||||
import { reblogStatus } from '../routes/_api/reblog'
|
||||
|
||||
global.fetch = fetch
|
||||
global.File = FileApi.File
|
||||
|
@ -18,6 +19,10 @@ export async function favoriteStatusAs (username, statusId) {
|
|||
return favoriteStatus(instanceName, users[username].accessToken, statusId)
|
||||
}
|
||||
|
||||
export async function reblogStatusAs (username, statusId) {
|
||||
return reblogStatus(instanceName, users[username].accessToken, statusId)
|
||||
}
|
||||
|
||||
export async function postAs (username, text) {
|
||||
return postStatus(instanceName, users[username].accessToken, text,
|
||||
null, null, false, null, 'public')
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
import { loginAsFoobar } from '../roles'
|
||||
import {
|
||||
getFavoritesCount,
|
||||
getNthStatus, getNthStatusContent, getReblogsCount, homeNavButton
|
||||
} from '../utils'
|
||||
import { favoriteStatusAs, postAs, reblogStatusAs } from '../serverActions'
|
||||
|
||||
fixture`119-status-counts-update.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('Fav stats update', async t => {
|
||||
let status = await postAs('foobar', 'hey hello look at this toot')
|
||||
let statusId = status.id
|
||||
await favoriteStatusAs('admin', statusId)
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.expect(getNthStatusContent(0).innerText).contains('hey hello look at this toot')
|
||||
.click(getNthStatus(0))
|
||||
.expect(getFavoritesCount()).eql(1)
|
||||
.click(homeNavButton)
|
||||
await favoriteStatusAs('quux', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getFavoritesCount()).eql(2)
|
||||
.click(homeNavButton)
|
||||
await favoriteStatusAs('baz', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getFavoritesCount()).eql(3)
|
||||
.click(homeNavButton)
|
||||
await favoriteStatusAs('LockedAccount', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getFavoritesCount()).eql(4)
|
||||
})
|
||||
|
||||
test('Reblog stats update', async t => {
|
||||
let status = await postAs('foobar', 'oh why hello it looks like another toot')
|
||||
let statusId = status.id
|
||||
await reblogStatusAs('admin', statusId)
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.expect(getNthStatusContent(0).innerText).contains('oh why hello it looks like another toot')
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(1)
|
||||
.click(homeNavButton)
|
||||
await reblogStatusAs('quux', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(2)
|
||||
.click(homeNavButton)
|
||||
await reblogStatusAs('baz', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(3)
|
||||
.click(homeNavButton)
|
||||
await reblogStatusAs('LockedAccount', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(4)
|
||||
})
|
||||
|
||||
test('Fav and reblog stats update for a boosted toot', async t => {
|
||||
let status = await postAs('ExternalLinks', 'this will get boosted')
|
||||
let statusId = status.id
|
||||
await reblogStatusAs('admin', statusId)
|
||||
await favoriteStatusAs('admin', statusId)
|
||||
await favoriteStatusAs('quux', statusId)
|
||||
await loginAsFoobar(t)
|
||||
await t
|
||||
.expect(getNthStatusContent(0).innerText).contains('this will get boosted')
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(1)
|
||||
.expect(getFavoritesCount()).eql(2)
|
||||
.click(homeNavButton)
|
||||
await favoriteStatusAs('baz', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(1)
|
||||
.expect(getFavoritesCount()).eql(3)
|
||||
.click(homeNavButton)
|
||||
await favoriteStatusAs('LockedAccount', statusId)
|
||||
await t
|
||||
.click(getNthStatus(0))
|
||||
.expect(getReblogsCount()).eql(1)
|
||||
.expect(getFavoritesCount()).eql(4)
|
||||
})
|
Loading…
Reference in New Issue