@@ -8,7 +8,7 @@
{{/if}}
{{#await promise}}
{{then constructor}}
- <:Component {constructor} :timeline on:initialized="set({'loading': false})"/>
+ <:Component {constructor} :timeline />
{{catch error}}
Component failed to load. Please try refreshing! {{error}}
{{/await}}
@@ -34,11 +34,18 @@
import { importTimeline } from '../_utils/asyncModules'
import LoadingSpinner from './LoadingSpinner.html'
import { fade } from 'svelte-transitions'
+ import { store } from '../_utils/store'
export default {
+ oncreate() {
+ let instanceName = this.store.get('currentInstance')
+ let timeline = this.get('timeline')
+ this.store.set({currentTimeline: timeline})
+ this.store.setForTimeline(instanceName, timeline, {runningUpdate: false})
+ },
+ store: () => store,
data: () => ({
- promise: importTimeline(),
- loading: true
+ promise: importTimeline()
}),
components: {
LoadingSpinner
diff --git a/routes/_components/Timeline.html b/routes/_components/Timeline.html
index eff81ec..3419a40 100644
--- a/routes/_components/Timeline.html
+++ b/routes/_components/Timeline.html
@@ -1,13 +1,13 @@
<:Window bind:online />
-
+
@@ -31,12 +31,6 @@
import { database } from '../_utils/database/database'
import { StatusStream } from '../_utils/mastodon/StatusStream'
- const cachedTimelines = {}
-
- if (process.browser && process.env.NODE_ENV !== 'production') {
- window.cachedTimelines = cachedTimelines
- }
-
const FETCH_LIMIT = 20
export default {
@@ -44,10 +38,7 @@
let timeline = this.get('timeline')
let instanceName = this.store.get('currentInstance')
let accessToken = this.store.get('accessToken')
- let cachedStatusIds = cachedTimelines[timeline]
- if (cachedStatusIds) {
- this.set({statusIds: cachedStatusIds})
- } else {
+ if (!this.store.get('statusIds').length) {
this.addStatuses(await this.fetchStatusesAndPossiblyFallBack())
}
/* no await */ getInstanceInfo(instanceName).then(instanceInfo => database.setInstanceInfo(instanceName, instanceInfo))
@@ -62,18 +53,13 @@
if (this._statusStream) {
this._statusStream.close()
}
- cachedTimelines[this.get('timeline')] = this.get('statusIds')
},
data: () => ({
StatusListItem: StatusListItem,
- LoadingFooter: LoadingFooter,
- statusIds: [],
- runningUpdate: false,
- initialized: false
+ LoadingFooter: LoadingFooter
}),
computed: {
makeProps: ($currentInstance) => (statusId) => database.getStatus($currentInstance, statusId),
- lastStatusId: (statusIds) => statusIds.length && statusIds[statusIds.length - 1],
label: (timeline, $currentInstance) => {
if (timelines[timeline]) {
`${timelines[timeline].label} timeline for ${$currentInstance}`
@@ -94,27 +80,30 @@
splice: splice,
push: push,
initialize() {
- if (this.get('initialized') || !this.get('statusIds') || !this.get('statusIds').length) {
+ if (this.store.get('initialized') || !this.store.get('statusIds') || !this.store.get('statusIds').length) {
return
}
+ let instanceName = this.store.get('currentInstance')
+ let timeline = this.get('timeline')
requestAnimationFrame(() => {
requestAnimationFrame(() => {
- this.set({initialized: true})
- this.fire('initialized')
+ this.store.setForTimeline(instanceName, timeline, {initialized: true})
})
})
},
async onScrollToBottom() {
- if (!this.get('initialized')) {
+ if (!this.store.get('initialized')) {
return
}
- if (this.get('runningUpdate')) {
+ if (this.store.get('runningUpdate')) {
return
}
mark('onScrollToBottom')
- this.set({ runningUpdate: true })
+ let timeline = this.get('timeline')
+ let instanceName = this.store.get('currentInstance')
+ this.store.setForTimeline(instanceName, timeline, { runningUpdate: true })
let newStatuses = await this.fetchStatusesAndPossiblyFallBack()
- this.set({ runningUpdate: false })
+ this.store.setForTimeline(instanceName, timeline, { runningUpdate: false })
this.addStatuses(newStatuses)
stop('onScrollToBottom')
},
@@ -122,21 +111,21 @@
console.log('addStatuses()')
let instanceName = this.store.get('currentInstance')
let timeline = this.get('timeline')
- let statusIds = this.get('statusIds')
+ let statusIds = this.store.get('statusIds')
if (!statusIds) {
return
}
/* no await */ database.insertStatuses(instanceName, timeline, newStatuses)
let newStatusIds = newStatuses.map(status => status.id)
let merged = mergeStatuses(statusIds, newStatusIds)
- this.set({ statusIds: merged })
+ this.store.setForTimeline(instanceName, timeline, { statusIds: merged })
},
async fetchStatusesAndPossiblyFallBack() {
let online = this.get('online')
let instanceName = this.store.get('currentInstance')
let instanceData = this.store.get('currentInstanceData')
let timeline = this.get('timeline')
- let lastStatusId = this.get('lastStatusId')
+ let lastStatusId = this.store.get('lastStatusId')
let statuses
if (!online) {
statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
diff --git a/routes/_utils/AsyncLayout.js b/routes/_utils/AsyncLayout.js
index 5dd3cf3..eda81d6 100644
--- a/routes/_utils/AsyncLayout.js
+++ b/routes/_utils/AsyncLayout.js
@@ -14,6 +14,9 @@ class AsyncLayout {
}
observe(key, node, callback) {
+ if (!node) {
+ return
+ }
if (this._intersectionObserver) {
this._onIntersectionCallbacks[key] = (entry) => {
callback(getRectFromEntry(entry))
@@ -27,6 +30,9 @@ class AsyncLayout {
if (key in this._onIntersectionCallbacks) {
return
}
+ if (!node) {
+ return
+ }
if (this._intersectionObserver) {
this._intersectionObserver.unobserve(node)
}
diff --git a/routes/_utils/store.js b/routes/_utils/store.js
index 3cc20bd..e827209 100644
--- a/routes/_utils/store.js
+++ b/routes/_utils/store.js
@@ -11,7 +11,7 @@ const LOCAL_STORAGE_KEYS = new Set([
])
const LS = process.browser && localStorage
-class LocalStorageStore extends Store {
+class PinaforeStore extends Store {
constructor(state) {
super(state)
@@ -44,9 +44,18 @@ class LocalStorageStore extends Store {
this.keysToStore = {}
}
}
+
+ setForTimeline(instanceName, timelineName, obj) {
+ console.log('setForTimeline')
+ let timelines = this.get('timelines') || {}
+ let timelineData = timelines[instanceName] || {}
+ timelineData[timelineName] = Object.assign(timelineData[timelineName] || {}, obj)
+ timelines[instanceName] = timelineData
+ this.set({timelines: timelines})
+ }
}
-const store = new LocalStorageStore({
+const store = new PinaforeStore({
instanceNameInSearch: '',
currentRegisteredInstance: null,
currentRegisteredInstanceName: '',
@@ -98,6 +107,16 @@ store.compute(
}
)
+store.compute('currentTimelineData', ['currentInstance', 'currentTimeline', 'timelines'],
+ (currentInstance, currentTimeline, timelines) => {
+ return ((timelines && timelines[currentInstance]) || {})[currentTimeline] || {}
+})
+
+store.compute('statusIds', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.statusIds || [])
+store.compute('runningUpdate', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.runningUpdate)
+store.compute('initialized', ['currentTimelineData'], (currentTimelineData) => currentTimelineData.initialized)
+store.compute('lastStatusId', ['statusIds'], (statusIds) => statusIds.length && statusIds[statusIds.length - 1])
+
if (process.browser && process.env.NODE_ENV !== 'production') {
window.store = store // for debugging
}