forked from cybrespace/pinafore
delete statuses should delete notifications
This commit is contained in:
parent
da2daa955d
commit
06575a0b81
|
@ -3,30 +3,46 @@ import { store } from '../_store/store'
|
||||||
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
||||||
import { database } from '../_database/database'
|
import { database } from '../_database/database'
|
||||||
import forEach from 'lodash/forEach'
|
import forEach from 'lodash/forEach'
|
||||||
|
import isEqual from 'lodash/isEqual'
|
||||||
|
|
||||||
function deleteStatusIdsFromStore (instanceName, idsToDelete) {
|
function filterItemIdsFromTimelines (instanceName, timelineFilter, idFilter) {
|
||||||
let idsToDeleteSet = new Set(idsToDelete)
|
let keys = ['timelineItemIds', 'itemIdsToAdd']
|
||||||
let idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
|
||||||
|
|
||||||
let timelinesToTimelineItemIds = store.getAllTimelineData(instanceName, 'timelineItemIds')
|
keys.forEach(key => {
|
||||||
|
let timelineData = store.getAllTimelineData(instanceName, key)
|
||||||
forEach(timelinesToTimelineItemIds, (timelineItemIds, timelineName) => {
|
forEach(timelineData, (ids, timelineName) => {
|
||||||
|
if (!timelineFilter(timelineName)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let filteredIds = ids.filter(idFilter)
|
||||||
|
if (!isEqual(ids, filteredIds)) {
|
||||||
store.setForTimeline(instanceName, timelineName, {
|
store.setForTimeline(instanceName, timelineName, {
|
||||||
timelineItemIds: timelineItemIds.filter(idWasNotDeleted)
|
[key]: filteredIds
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
let timelinesToItemIdsToAdd = store.getAllTimelineData(instanceName, 'itemIdsToAdd')
|
|
||||||
|
|
||||||
forEach(timelinesToItemIdsToAdd, (itemIdsToAdd, timelineName) => {
|
|
||||||
store.setForTimeline(instanceName, timelineName, {
|
|
||||||
itemIdsToAdd: itemIdsToAdd.filter(idWasNotDeleted)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteStatusIdsFromStore (instanceName, idsToDelete) {
|
||||||
|
let idsToDeleteSet = new Set(idsToDelete)
|
||||||
|
let idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
||||||
|
let notNotificationTimeline = timelineName => timelineName !== 'notifications'
|
||||||
|
|
||||||
|
filterItemIdsFromTimelines(instanceName, notNotificationTimeline, idWasNotDeleted)
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNotificationIdsFromStore (instanceName, idsToDelete) {
|
||||||
|
let idsToDeleteSet = new Set(idsToDelete)
|
||||||
|
let idWasNotDeleted = id => !idsToDeleteSet.has(id)
|
||||||
|
let isNotificationTimeline = timelineName => timelineName === 'notifications'
|
||||||
|
|
||||||
|
filterItemIdsFromTimelines(instanceName, isNotificationTimeline, idWasNotDeleted)
|
||||||
|
}
|
||||||
|
|
||||||
async function deleteStatusesAndNotifications (instanceName, statusIdsToDelete, notificationIdsToDelete) {
|
async function deleteStatusesAndNotifications (instanceName, statusIdsToDelete, notificationIdsToDelete) {
|
||||||
deleteStatusIdsFromStore(instanceName, statusIdsToDelete)
|
deleteStatusIdsFromStore(instanceName, statusIdsToDelete)
|
||||||
|
deleteNotificationIdsFromStore(instanceName, notificationIdsToDelete)
|
||||||
await database.deleteStatusesAndNotifications(instanceName, statusIdsToDelete, notificationIdsToDelete)
|
await database.deleteStatusesAndNotifications(instanceName, statusIdsToDelete, notificationIdsToDelete)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +50,7 @@ async function doDeleteStatus (instanceName, statusId) {
|
||||||
console.log('deleting statusId', statusId)
|
console.log('deleting statusId', statusId)
|
||||||
let rebloggedIds = await getIdsThatRebloggedThisStatus(instanceName, statusId)
|
let rebloggedIds = await getIdsThatRebloggedThisStatus(instanceName, statusId)
|
||||||
let statusIdsToDelete = Array.from(new Set([statusId].concat(rebloggedIds).filter(Boolean)))
|
let statusIdsToDelete = Array.from(new Set([statusId].concat(rebloggedIds).filter(Boolean)))
|
||||||
let notificationIdsToDelete = new Set(await getNotificationIdsForStatuses(instanceName, statusIdsToDelete))
|
let notificationIdsToDelete = Array.from(new Set(await getNotificationIdsForStatuses(instanceName, statusIdsToDelete)))
|
||||||
await deleteStatusesAndNotifications(instanceName, statusIdsToDelete, notificationIdsToDelete)
|
await deleteStatusesAndNotifications(instanceName, statusIdsToDelete, notificationIdsToDelete)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,13 +301,15 @@ export async function getReblogsForStatus (instanceName, id) {
|
||||||
|
|
||||||
export async function getNotificationIdsForStatuses (instanceName, statusIds) {
|
export async function getNotificationIdsForStatuses (instanceName, statusIds) {
|
||||||
const db = await getDatabase(instanceName)
|
const db = await getDatabase(instanceName)
|
||||||
await dbPromise(db, NOTIFICATIONS_STORE, 'readonly', (notificationsStore, callback) => {
|
return dbPromise(db, NOTIFICATIONS_STORE, 'readonly', (notificationsStore, callback) => {
|
||||||
let res = []
|
let res = []
|
||||||
callback(res)
|
callback(res)
|
||||||
statusIds.forEach(statusId => {
|
statusIds.forEach(statusId => {
|
||||||
let req = notificationsStore.index(STATUS_ID).getAllKeys(IDBKeyRange.only(statusId))
|
let req = notificationsStore.index(STATUS_ID).getAllKeys(IDBKeyRange.only(statusId))
|
||||||
req.onsuccess = e => {
|
req.onsuccess = e => {
|
||||||
res = res.concat(e.target.result)
|
for (let id of e.target.result) {
|
||||||
|
res.push(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -371,7 +373,7 @@ export async function deleteStatusesAndNotifications (instanceName, statusIds, n
|
||||||
notificationsStore.delete(notificationId)
|
notificationsStore.delete(notificationId)
|
||||||
deleteAll(
|
deleteAll(
|
||||||
notificationTimelinesStore,
|
notificationTimelinesStore,
|
||||||
notificationTimelinesStore.index('statusId'),
|
notificationTimelinesStore.index('notificationId'),
|
||||||
IDBKeyRange.only(notificationId)
|
IDBKeyRange.only(notificationId)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { foobarRole } from '../roles'
|
import { foobarRole } from '../roles'
|
||||||
|
|
||||||
fixture`130-favorite-unfavorite.js`
|
fixture`100-favorite-unfavorite.js`
|
||||||
.page`http://localhost:4002`
|
.page`http://localhost:4002`
|
||||||
|
|
||||||
test('favorites a status', async t => {
|
test('favorites a status', async t => {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { foobarRole } from '../roles'
|
import { foobarRole } from '../roles'
|
||||||
import {
|
import {
|
||||||
clickToNotificationsAndBackHome, forceOffline, forceOnline, getNthStatus, getUrl, homeNavButton,
|
clickToNotificationsAndBackHome, forceOffline, forceOnline, getNthStatus, getUrl, homeNavButton,
|
||||||
|
notificationsNavButton,
|
||||||
sleep
|
sleep
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { deleteAsAdmin, postAsAdmin, postReplyAsAdmin } from '../serverActions'
|
import { deleteAsAdmin, postAsAdmin, postReplyAsAdmin } from '../serverActions'
|
||||||
|
@ -53,3 +54,15 @@ test('deleted statuses are removed from threads', async t => {
|
||||||
.expect(getNthStatus(0).innerText).contains("I won't delete this")
|
.expect(getNthStatus(0).innerText).contains("I won't delete this")
|
||||||
await forceOnline()
|
await forceOnline()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('deleted statuses result in deleted notifications', async t => {
|
||||||
|
await t.useRole(foobarRole)
|
||||||
|
.hover(getNthStatus(0))
|
||||||
|
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications')
|
||||||
|
let status = await postAsAdmin("@foobar yo yo foobar what's up")
|
||||||
|
await sleep(2000)
|
||||||
|
await t.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (1)')
|
||||||
|
await deleteAsAdmin(status.id)
|
||||||
|
await sleep(5000)
|
||||||
|
await t.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications')
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue