diff --git a/src/routes/_actions/addStatusOrNotification.js b/src/routes/_actions/addStatusOrNotification.js index 9138854c..fb81b318 100644 --- a/src/routes/_actions/addStatusOrNotification.js +++ b/src/routes/_actions/addStatusOrNotification.js @@ -1,15 +1,15 @@ import { mark, stop } from '../_utils/marks' import { store } from '../_store/store' import uniqBy from 'lodash-es/uniqBy' -import uniq from 'lodash-es/uniq' import isEqual from 'lodash-es/isEqual' import { database } from '../_database/database' -import { concat } from '../_utils/arrays' +import { concat, indexWhere } from '../_utils/arrays' import { scheduleIdleTask } from '../_utils/scheduleIdleTask' +import { timelineItemToSummary } from '../_utils/timelineItemToSummary' function getExistingItemIdsSet (instanceName, timelineName) { - let timelineItemIds = store.getForTimeline(instanceName, timelineName, 'timelineItemIds') || [] - return new Set(timelineItemIds) + let timelineItemSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') || [] + return new Set(timelineItemSummaries.map(_ => _.id)) } function removeDuplicates (instanceName, timelineName, updates) { @@ -27,28 +27,37 @@ async function insertUpdatesIntoTimeline (instanceName, timelineName, updates) { await database.insertTimelineItems(instanceName, timelineName, updates) - let itemIdsToAdd = store.getForTimeline(instanceName, timelineName, 'itemIdsToAdd') || [] - let newItemIdsToAdd = uniq(concat(itemIdsToAdd, updates.map(_ => _.id))) - if (!isEqual(itemIdsToAdd, newItemIdsToAdd)) { - console.log('adding ', (newItemIdsToAdd.length - itemIdsToAdd.length), - 'items to itemIdsToAdd for timeline', timelineName) - store.setForTimeline(instanceName, timelineName, { itemIdsToAdd: newItemIdsToAdd }) + let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') || [] + console.log('itemSummariesToAdd', JSON.parse(JSON.stringify(itemSummariesToAdd))) + console.log('updates.map(timelineItemToSummary)', JSON.parse(JSON.stringify(updates.map(timelineItemToSummary)))) + console.log('concat(itemSummariesToAdd, updates.map(timelineItemToSummary))', + JSON.parse(JSON.stringify(concat(itemSummariesToAdd, updates.map(timelineItemToSummary))))) + let newItemSummariesToAdd = uniqBy( + concat(itemSummariesToAdd, updates.map(timelineItemToSummary)), + _ => _.id + ) + if (!isEqual(itemSummariesToAdd, newItemSummariesToAdd)) { + console.log('adding ', (newItemSummariesToAdd.length - itemSummariesToAdd.length), + 'items to timelineItemSummariesToAdd for timeline', timelineName) + store.setForTimeline(instanceName, timelineName, { timelineItemSummariesToAdd: newItemSummariesToAdd }) } } -function isValidStatusForThread (thread, timelineName, itemIdsToAdd) { +function isValidStatusForThread (thread, timelineName, itemSummariesToAdd) { + let itemSummariesToAddIdSet = new Set(itemSummariesToAdd.map(_ => _.id)) + let threadIdSet = new Set(thread.map(_ => _.id)) let focusedStatusId = timelineName.split('/')[1] // e.g. "status/123456" - let focusedStatusIdx = thread.indexOf(focusedStatusId) + let focusedStatusIdx = indexWhere(thread, _ => _.id === focusedStatusId) return status => { - let repliedToStatusIdx = thread.indexOf(status.in_reply_to_id) + let repliedToStatusIdx = indexWhere(thread, _ => _.id === status.in_reply_to_id) return ( // A reply to an ancestor status is not valid for this thread, but for the focused status // itself or any of its descendents, it is valid. repliedToStatusIdx >= focusedStatusIdx && // Not a duplicate - !thread.includes(status.id) && + !threadIdSet.has(status.id) && // Not already about to be added - !itemIdsToAdd.includes(status.id) + !itemSummariesToAddIdSet.has(status.id) ) } } @@ -63,16 +72,19 @@ async function insertUpdatesIntoThreads (instanceName, updates) { for (let timelineName of timelineNames) { let thread = threads[timelineName] - let itemIdsToAdd = store.getForTimeline(instanceName, timelineName, 'itemIdsToAdd') || [] - let validUpdates = updates.filter(isValidStatusForThread(thread, timelineName, itemIdsToAdd)) + let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') || [] + let validUpdates = updates.filter(isValidStatusForThread(thread, timelineName, itemSummariesToAdd)) if (!validUpdates.length) { continue } - let newItemIdsToAdd = uniq(concat(itemIdsToAdd, validUpdates.map(_ => _.id))) - if (!isEqual(itemIdsToAdd, newItemIdsToAdd)) { - console.log('adding ', (newItemIdsToAdd.length - itemIdsToAdd.length), - 'items to itemIdsToAdd for thread', timelineName) - store.setForTimeline(instanceName, timelineName, { itemIdsToAdd: newItemIdsToAdd }) + let newItemSummariesToAdd = uniqBy( + concat(itemSummariesToAdd, validUpdates.map(timelineItemToSummary)), + _ => _.id + ) + if (!isEqual(itemSummariesToAdd, newItemSummariesToAdd)) { + console.log('adding ', (newItemSummariesToAdd.length - itemSummariesToAdd.length), + 'items to timelineItemSummariesToAdd for thread', timelineName) + store.setForTimeline(instanceName, timelineName, { timelineItemSummariesToAdd: newItemSummariesToAdd }) } } } diff --git a/src/routes/_actions/deleteStatuses.js b/src/routes/_actions/deleteStatuses.js index 2fdcd9ba..e8f13d83 100644 --- a/src/routes/_actions/deleteStatuses.js +++ b/src/routes/_actions/deleteStatuses.js @@ -5,20 +5,21 @@ import { database } from '../_database/database' import { scheduleIdleTask } from '../_utils/scheduleIdleTask' function filterItemIdsFromTimelines (instanceName, timelineFilter, idFilter) { - let keys = ['timelineItemIds', 'itemIdsToAdd'] + let keys = ['timelineItemSummaries', 'timelineItemSummariesToAdd'] + let summaryFilter = _ => idFilter(_.id) keys.forEach(key => { let timelineData = store.getAllTimelineData(instanceName, key) Object.keys(timelineData).forEach(timelineName => { - let ids = timelineData[timelineName] + let summaries = timelineData[timelineName] if (!timelineFilter(timelineName)) { return } - let filteredIds = ids.filter(idFilter) - if (!isEqual(ids, filteredIds)) { + let filteredSummaries = summaries.filter(summaryFilter) + if (!isEqual(summaries, filteredSummaries)) { console.log('deleting an item from timelineName', timelineName, 'for key', key) store.setForTimeline(instanceName, timelineName, { - [key]: filteredIds + [key]: filteredSummaries }) } }) diff --git a/src/routes/_actions/timeline.js b/src/routes/_actions/timeline.js index 0e91a4f6..cb2867c3 100644 --- a/src/routes/_actions/timeline.js +++ b/src/routes/_actions/timeline.js @@ -3,12 +3,13 @@ import { getTimeline } from '../_api/timelines' import { toast } from '../_components/toast/toast' import { mark, stop } from '../_utils/marks' import { concat, mergeArrays } from '../_utils/arrays' -import { byItemIds } from '../_utils/sorting' +import { compareTimelineItemSummaries } from '../_utils/sorting' import isEqual from 'lodash-es/isEqual' import { database } from '../_database/database' import { getStatus, getStatusContext } from '../_api/statuses' import { emit } from '../_utils/eventBus' import { TIMELINE_BATCH_SIZE } from '../_static/timelines' +import { timelineItemToSummary } from '../_utils/timelineItemToSummary' async function storeFreshTimelineItemsInDatabase (instanceName, timelineName, items) { await database.insertTimelineItems(instanceName, timelineName, items) @@ -59,23 +60,23 @@ async function fetchTimelineItems (instanceName, accessToken, timelineName, last async function addTimelineItems (instanceName, timelineName, items, stale) { console.log('addTimelineItems, length:', items.length) - mark('addTimelineItems') - let newIds = items.map(item => item.id) - addTimelineItemIds(instanceName, timelineName, newIds, stale) - stop('addTimelineItems') + mark('addTimelineItemSummaries') + let newSummaries = items.map(timelineItemToSummary) + addTimelineItemSummaries(instanceName, timelineName, newSummaries, stale) + stop('addTimelineItemSummaries') } -export async function addTimelineItemIds (instanceName, timelineName, newIds, newStale) { - let oldIds = store.getForTimeline(instanceName, timelineName, 'timelineItemIds') - let oldStale = store.getForTimeline(instanceName, timelineName, 'timelineItemIdsAreStale') +export async function addTimelineItemSummaries (instanceName, timelineName, newSummaries, newStale) { + let oldSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') || [] + let oldStale = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesAreStale') - let mergedIds = mergeArrays(oldIds || [], newIds) + let mergedSummaries = mergeArrays(oldSummaries, newSummaries, compareTimelineItemSummaries) - if (!isEqual(oldIds, mergedIds)) { - store.setForTimeline(instanceName, timelineName, { timelineItemIds: mergedIds }) + if (!isEqual(oldSummaries, mergedSummaries)) { + store.setForTimeline(instanceName, timelineName, { timelineItemSummaries: mergedSummaries }) } if (oldStale !== newStale) { - store.setForTimeline(instanceName, timelineName, { timelineItemIdsAreStale: newStale }) + store.setForTimeline(instanceName, timelineName, { timelineItemSummariesAreStale: newStale }) } } @@ -96,17 +97,17 @@ async function fetchTimelineItemsAndPossiblyFallBack () { export async function setupTimeline () { mark('setupTimeline') - // If we don't have any item ids, or if the current item ids are stale + // If we don't have any item summaries, or if the current item summaries are stale // (i.e. via offline mode), then we need to re-fetch // Also do this if it's a thread, because threads change pretty frequently and // we don't have a good way to update them. let { - timelineItemIds, - timelineItemIdsAreStale, + timelineItemSummaries, + timelineItemSummariesAreStale, currentTimeline } = store.get() - if (!timelineItemIds || - timelineItemIdsAreStale || + if (!timelineItemSummaries || + timelineItemSummariesAreStale || currentTimeline.startsWith('status/')) { await fetchTimelineItemsAndPossiblyFallBack() } @@ -123,11 +124,11 @@ export async function fetchTimelineItemsOnScrollToBottom (instanceName, timeline export async function showMoreItemsForTimeline (instanceName, timelineName) { mark('showMoreItemsForTimeline') - let itemIdsToAdd = store.getForTimeline(instanceName, timelineName, 'itemIdsToAdd') - itemIdsToAdd = itemIdsToAdd.sort(byItemIds).reverse() - addTimelineItemIds(instanceName, timelineName, itemIdsToAdd, false) + let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') + itemSummariesToAdd = itemSummariesToAdd.sort(compareTimelineItemSummaries).reverse() + addTimelineItemSummaries(instanceName, timelineName, itemSummariesToAdd, false) store.setForTimeline(instanceName, timelineName, { - itemIdsToAdd: [], + timelineItemSummariesToAdd: [], shouldShowHeader: false, showHeader: false }) @@ -144,17 +145,18 @@ export async function showMoreItemsForCurrentTimeline () { export async function showMoreItemsForThread (instanceName, timelineName) { mark('showMoreItemsForThread') - let itemIdsToAdd = store.getForTimeline(instanceName, timelineName, 'itemIdsToAdd') - let timelineItemIds = store.getForTimeline(instanceName, timelineName, 'timelineItemIds') + let itemSummariesToAdd = store.getForTimeline(instanceName, timelineName, 'timelineItemSummariesToAdd') + let timelineItemSummaries = store.getForTimeline(instanceName, timelineName, 'timelineItemSummaries') + let timelineItemIds = new Set(timelineItemSummaries.map(_ => _.id)) // TODO: update database and do the thread merge correctly - for (let itemIdToAdd of itemIdsToAdd) { - if (!timelineItemIds.includes(itemIdToAdd)) { - timelineItemIds.push(itemIdToAdd) + for (let itemSummaryToAdd of itemSummariesToAdd) { + if (!timelineItemIds.has(itemSummaryToAdd.id)) { + timelineItemSummaries.push(itemSummaryToAdd) } } store.setForTimeline(instanceName, timelineName, { - itemIdsToAdd: [], - timelineItemIds: timelineItemIds + timelineItemSummariesToAdd: [], + timelineItemSummaries: timelineItemSummaries }) stop('showMoreItemsForThread') } diff --git a/src/routes/_components/timeline/Timeline.html b/src/routes/_components/timeline/Timeline.html index e4264529..68fe9718 100644 --- a/src/routes/_components/timeline/Timeline.html +++ b/src/routes/_components/timeline/Timeline.html @@ -1,11 +1,4 @@