({
StatusListItem: StatusListItem,
LoadingFooter: LoadingFooter,
- statuses: [],
+ statusIds: [],
runningUpdate: false,
initialized: false
}),
computed: {
- keyedStatuses: (statuses) => statuses.map(status => ({
- props: status,
- key: status.id
- })),
- lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id,
+ makeProps: ($currentInstance) => (statusId) => database.getStatus($currentInstance, statusId),
+ items: (statusIds) => {
+ return statusIds.map(statusId => ({
+ key: statusId
+ }))
+ },
+ lastStatusId: (statusIds) => statusIds.length && statusIds[statusIds.length - 1],
label: (timeline, $currentInstance) => {
if (timelines[timeline]) {
`${timelines[timeline].label} timeline for ${$currentInstance}`
@@ -89,12 +92,16 @@
if (process.env.NODE_ENV !== 'production') {
console.log('addStatuses()')
}
- let statuses = this.get('statuses')
- if (!statuses) {
+ let instanceName = this.store.get('instanceName')
+ let timeline = this.get('timeline')
+ /* no await */ database.insertStatuses(instanceName, timeline, newStatuses)
+ let statusIds = this.get('statusIds')
+ if (!statusIds) {
return
}
- let merged = mergeStatuses(statuses, newStatuses)
- this.set({ statuses: merged })
+ let newStatusIds = newStatuses.map(status => status.id)
+ let merged = mergeStatuses(statusIds, newStatusIds)
+ this.set({ statusIds: merged })
},
async fetchStatusesAndPossiblyFallBack() {
let online = this.get('online')
diff --git a/routes/_components/VirtualList.html b/routes/_components/VirtualList.html
index 1d8c311c..fcc694a6 100644
--- a/routes/_components/VirtualList.html
+++ b/routes/_components/VirtualList.html
@@ -1,11 +1,11 @@
{{#each $visibleItems as item @key}}
-
{{/each}}
{{#if $showFooter}}
@@ -19,7 +19,7 @@
}
\ No newline at end of file
diff --git a/routes/_utils/database/databaseCore.js b/routes/_utils/database/databaseCore.js
index 0f531aa5..7a07bc29 100644
--- a/routes/_utils/database/databaseCore.js
+++ b/routes/_utils/database/databaseCore.js
@@ -13,6 +13,18 @@ import {
STATUSES_STORE, ACCOUNTS_STORE
} from './constants'
+import QuickLRU from 'quick-lru'
+
+const statusesCache = new QuickLRU({maxSize: 100})
+
+if (process.browser && process.env.NODE_ENV !== 'production') {
+ window.cacheStats = {
+ cache: statusesCache,
+ cacheHits: 0,
+ cacheMisses: 0
+ }
+}
+
export async function getTimeline(instanceName, timeline, maxId = null, limit = 20) {
const db = await getDatabase(instanceName, timeline)
return await dbPromise(db, [TIMELINE_STORE, STATUSES_STORE], 'readonly', (stores, callback) => {
@@ -37,6 +49,9 @@ export async function getTimeline(instanceName, timeline, maxId = null, limit =
}
export async function insertStatuses(instanceName, timeline, statuses) {
+ for (let status of statuses) {
+ statusesCache.set(status.id, status)
+ }
const db = await getDatabase(instanceName, timeline)
await dbPromise(db, [TIMELINE_STORE, STATUSES_STORE, ACCOUNTS_STORE], 'readwrite', (stores) => {
let [ timelineStore, statusesStore, accountsStore ] = stores
@@ -85,4 +100,24 @@ export async function getAccount(instanceName, accountId) {
export async function clearDatabaseForInstance(instanceName) {
await deleteDatabase(instanceName)
+}
+
+export async function getStatus(instanceName, statusId) {
+ if (statusesCache.has(statusId)) {
+ if (process.browser && process.env.NODE_ENV !== 'production') {
+ window.cacheStats.cacheHits++
+ }
+ return statusesCache.get(statusId)
+ }
+ const db = await getDatabase(instanceName)
+ let result = await dbPromise(db, STATUSES_STORE, 'readonly', (store, callback) => {
+ store.get(statusId).onsuccess = (e) => {
+ callback(e.target.result && e.target.result)
+ }
+ })
+ statusesCache.set(statusId, result)
+ if (process.browser && process.env.NODE_ENV !== 'production') {
+ window.cacheStats.cacheMisses++
+ }
+ return result
}
\ No newline at end of file
diff --git a/routes/_utils/statuses.js b/routes/_utils/statuses.js
index 93654556..05868471 100644
--- a/routes/_utils/statuses.js
+++ b/routes/_utils/statuses.js
@@ -1,27 +1,26 @@
// Merge two lists of statuses for the same timeline, e.g. one from IDB
// and another from the network. In case of duplicates, prefer the fresh.
-export function mergeStatuses(leftStatuses, rightStatuses) {
+export function mergeStatuses(leftStatusIds, rightStatusIds) {
let leftIndex = 0
let rightIndex = 0
let merged = []
- while (leftIndex < leftStatuses.length || rightIndex < rightStatuses.length) {
- if (leftIndex === leftStatuses.length) {
- merged.push(rightStatuses[rightIndex])
+ while (leftIndex < leftStatusIds.length || rightIndex < rightStatusIds.length) {
+ if (leftIndex === leftStatusIds.length) {
+ merged.push(rightStatusIds[rightIndex])
rightIndex++
continue
}
- if (rightIndex === rightStatuses.length) {
- merged.push(leftStatuses[leftIndex])
+ if (rightIndex === rightStatusIds.length) {
+ merged.push(leftStatusIds[leftIndex])
leftIndex++
continue
}
- let left = leftStatuses[leftIndex]
- let right = rightStatuses[rightIndex]
- if (right.id === left.id) {
- merged.push(right.pinafore_stale ? left : right)
+ let left = leftStatusIds[leftIndex]
+ let right = rightStatusIds[rightIndex]
+ if (right === left) {
rightIndex++
leftIndex++
- } else if (parseInt(right.id, 10) > parseInt(left.id, 10)) {
+ } else if (parseInt(right, 10) > parseInt(left, 10)) {
merged.push(right)
rightIndex++
} else {
diff --git a/routes/_utils/virtualListStore.js b/routes/_utils/virtualListStore.js
index 32b7ea72..8d02c358 100644
--- a/routes/_utils/virtualListStore.js
+++ b/routes/_utils/virtualListStore.js
@@ -56,7 +56,7 @@ virtualListStore.compute('visibleItems',
let len = items.length
let i = -1
while (++i < len) {
- let { props, key } = items[i]
+ let { key } = items[i]
let height = itemHeights[key] || 0
let currentOffset = totalOffset
totalOffset += height
@@ -72,7 +72,6 @@ virtualListStore.compute('visibleItems',
}
visibleItems.push({
offset: currentOffset,
- props: props,
key: key,
index: i
})