refactor timeline to use actions
This commit is contained in:
parent
c0c7e9fafe
commit
de248a9b1f
94
routes/_actions/timeline.js
Normal file
94
routes/_actions/timeline.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import { store } from '../_utils/store'
|
||||
import { database } from '../_utils/database/database'
|
||||
import { getTimeline } from '../_utils/mastodon/timelines'
|
||||
import { toast } from '../_utils/toast'
|
||||
import { StatusStream } from '../_utils/mastodon/StatusStream'
|
||||
import { getInstanceInfo } from '../_utils/mastodon/instance'
|
||||
import { mark, stop } from '../_utils/marks'
|
||||
import { mergeStatuses } from '../_utils/timelines'
|
||||
|
||||
const FETCH_LIMIT = 20
|
||||
|
||||
let statusStream
|
||||
|
||||
async function fetchStatuses(instanceName, accessToken, timelineName, lastStatusId, online) {
|
||||
mark('fetchStatuses')
|
||||
let statuses
|
||||
if (!online) {
|
||||
statuses = await database.getTimeline(instanceName, timelineName, lastStatusId, FETCH_LIMIT)
|
||||
} else {
|
||||
try {
|
||||
statuses = await getTimeline(instanceName, accessToken, timelineName, lastStatusId, FETCH_LIMIT)
|
||||
/* no await */ database.insertStatuses(instanceName, timelineName, statuses)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast.say('Internet request failed. Showing offline content.')
|
||||
statuses = await database.getTimeline(instanceName, timelineName, lastStatusId, FETCH_LIMIT)
|
||||
}
|
||||
}
|
||||
stop('fetchStatuses')
|
||||
return statuses
|
||||
}
|
||||
|
||||
async function addStatuses(instanceName, timelineName, newStatuses) {
|
||||
mark('addStatuses')
|
||||
let newStatusIds = newStatuses.map(status => status.id)
|
||||
let oldStatusIds = store.getForTimeline(instanceName, timelineName, 'statusIds') || []
|
||||
let merged = mergeStatuses(oldStatusIds, newStatusIds)
|
||||
store.setForTimeline(instanceName, timelineName, { statusIds: merged })
|
||||
stop('addStatuses')
|
||||
}
|
||||
|
||||
async function fetchStatusesAndPossiblyFallBack() {
|
||||
mark('fetchStatusesAndPossiblyFallBack')
|
||||
let timelineName = store.get('currentTimeline')
|
||||
let instanceName = store.get('currentInstance')
|
||||
let accessToken = store.get('accessToken')
|
||||
let lastStatusId = store.get('lastStatusId')
|
||||
let online = store.get('online')
|
||||
|
||||
let newStatuses = await fetchStatuses(instanceName, accessToken, timelineName, lastStatusId, online)
|
||||
addStatuses(instanceName, timelineName, newStatuses)
|
||||
stop('fetchStatusesAndPossiblyFallBack')
|
||||
}
|
||||
|
||||
export function initializeTimeline() {
|
||||
mark('initializeTimeline')
|
||||
let instanceName = store.get('currentInstance')
|
||||
let timeline = store.get('currentTimeline')
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
store.setForTimeline(instanceName, timeline, {initialized: true})
|
||||
})
|
||||
})
|
||||
stop('initializeTimeline')
|
||||
}
|
||||
|
||||
export async function setupTimeline() {
|
||||
mark('addStatuses')
|
||||
let timelineName = store.get('currentTimeline')
|
||||
let instanceName = store.get('currentInstance')
|
||||
let accessToken = store.get('accessToken')
|
||||
if (!store.get('statusIds').length) {
|
||||
await fetchStatusesAndPossiblyFallBack()
|
||||
}
|
||||
/* no await */ getInstanceInfo(instanceName).then(instanceInfo => database.setInstanceInfo(instanceName, instanceInfo))
|
||||
let instanceInfo = await database.getInstanceInfo(instanceName)
|
||||
if (statusStream) {
|
||||
statusStream.close()
|
||||
}
|
||||
statusStream = new StatusStream(instanceInfo.urls.streaming_api, accessToken, timelineName, {
|
||||
onMessage(message) {
|
||||
console.log('message', message)
|
||||
}
|
||||
})
|
||||
stop('addStatuses')
|
||||
}
|
||||
|
||||
export async function fetchStatusesOnScrollToBottom() {
|
||||
let timelineName = store.get('currentTimeline')
|
||||
let instanceName = store.get('currentInstance')
|
||||
store.setForTimeline(instanceName, timelineName, { runningUpdate: true })
|
||||
await fetchStatusesAndPossiblyFallBack()
|
||||
store.setForTimeline(instanceName, timelineName, { runningUpdate: false })
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
<:Window bind:online />
|
||||
<Nav :page :dynamicPage :dynamicHref :dynamicIcon :dynamicLabel/>
|
||||
|
||||
{{#if virtual}}
|
||||
|
@ -19,6 +20,11 @@
|
|||
import { store } from '../_utils/store'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
this.observe('online', online => {
|
||||
this.store.set({online: online})
|
||||
})
|
||||
},
|
||||
components: {
|
||||
VirtualListContainer,
|
||||
Nav
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<:Window bind:online />
|
||||
<div class="timeline" role="feed" aria-label="{{label}}">
|
||||
<VirtualList component="{{StatusListItem}}"
|
||||
:makeProps
|
||||
|
@ -18,41 +17,16 @@
|
|||
</style>
|
||||
<script>
|
||||
import { store } from '../../_utils/store'
|
||||
import { getTimeline } from '../../_utils/mastodon/timelines'
|
||||
import { getInstanceInfo } from '../../_utils/mastodon/instance'
|
||||
import StatusListItem from './StatusListItem.html'
|
||||
import LoadingFooter from './LoadingFooter.html'
|
||||
import VirtualList from '../virtualList/VirtualList.html'
|
||||
import { splice, push } from 'svelte-extras'
|
||||
import { mergeStatuses } from '../../_utils/statuses'
|
||||
import { mark, stop } from '../../_utils/marks'
|
||||
import { timelines } from '../../_static/timelines'
|
||||
import { toast } from '../../_utils/toast'
|
||||
import { database } from '../../_utils/database/database'
|
||||
import { StatusStream } from '../../_utils/mastodon/StatusStream'
|
||||
|
||||
const FETCH_LIMIT = 20
|
||||
import { initializeTimeline, fetchStatusesOnScrollToBottom, setupTimeline } from '../../_actions/timeline'
|
||||
|
||||
export default {
|
||||
async oncreate() {
|
||||
let timeline = this.get('timeline')
|
||||
let instanceName = this.store.get('currentInstance')
|
||||
let accessToken = this.store.get('accessToken')
|
||||
if (!this.store.get('statusIds').length) {
|
||||
this.addStatuses(await this.fetchStatusesAndPossiblyFallBack())
|
||||
}
|
||||
/* no await */ getInstanceInfo(instanceName).then(instanceInfo => database.setInstanceInfo(instanceName, instanceInfo))
|
||||
let instanceInfo = await database.getInstanceInfo(instanceName)
|
||||
this._statusStream = new StatusStream(instanceInfo.urls.streaming_api, accessToken, timeline, {
|
||||
onMessage(message) {
|
||||
console.log('message', message)
|
||||
}
|
||||
})
|
||||
},
|
||||
ondestroy() {
|
||||
if (this._statusStream) {
|
||||
this._statusStream.close()
|
||||
}
|
||||
setupTimeline()
|
||||
},
|
||||
data: () => ({
|
||||
StatusListItem: StatusListItem,
|
||||
|
@ -77,69 +51,17 @@
|
|||
VirtualList
|
||||
},
|
||||
methods: {
|
||||
splice: splice,
|
||||
push: push,
|
||||
initialize() {
|
||||
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.store.setForTimeline(instanceName, timeline, {initialized: true})
|
||||
})
|
||||
})
|
||||
initializeTimeline()
|
||||
},
|
||||
async onScrollToBottom() {
|
||||
if (!this.store.get('initialized')) {
|
||||
if (!this.store.get('initialized') || this.store.get('runningUpdate')) {
|
||||
return
|
||||
}
|
||||
if (this.store.get('runningUpdate')) {
|
||||
return
|
||||
}
|
||||
mark('onScrollToBottom')
|
||||
let timeline = this.get('timeline')
|
||||
let instanceName = this.store.get('currentInstance')
|
||||
this.store.setForTimeline(instanceName, timeline, { runningUpdate: true })
|
||||
let newStatuses = await this.fetchStatusesAndPossiblyFallBack()
|
||||
this.store.setForTimeline(instanceName, timeline, { runningUpdate: false })
|
||||
this.addStatuses(newStatuses)
|
||||
stop('onScrollToBottom')
|
||||
},
|
||||
addStatuses(newStatuses) {
|
||||
console.log('addStatuses()')
|
||||
let instanceName = this.store.get('currentInstance')
|
||||
let timeline = this.get('timeline')
|
||||
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.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.store.get('lastStatusId')
|
||||
let statuses
|
||||
if (!online) {
|
||||
statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
|
||||
} else {
|
||||
try {
|
||||
statuses = await getTimeline(instanceName, instanceData.access_token, timeline, lastStatusId, FETCH_LIMIT)
|
||||
/* no await */ database.insertStatuses(instanceName, timeline, statuses)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast.say('Internet request failed. Showing offline content.')
|
||||
statuses = await database.getTimeline(instanceName, timeline, lastStatusId, FETCH_LIMIT)
|
||||
}
|
||||
}
|
||||
return statuses
|
||||
fetchStatusesOnScrollToBottom()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,12 @@ class PinaforeStore extends Store {
|
|||
timelines[instanceName] = timelineData
|
||||
this.set({timelines: timelines})
|
||||
}
|
||||
|
||||
getForTimeline(instanceName, timelineName, key) {
|
||||
let timelines = this.get('timelines') || {}
|
||||
let timelineData = timelines[instanceName] || {}
|
||||
return (timelineData[timelineName] || {})[key]
|
||||
}
|
||||
}
|
||||
|
||||
const store = new PinaforeStore({
|
||||
|
|
Loading…
Reference in a new issue