delete statuses should delete notifications

This commit is contained in:
Nolan Lawson 2018-03-10 21:05:00 -08:00
parent da2daa955d
commit 06575a0b81
4 changed files with 52 additions and 21 deletions

View File

@ -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)
} }

View File

@ -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)
) )
} }

View File

@ -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 => {

View File

@ -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')
})