<:Window bind:online /> <div class="timeline" role="feed" aria-label="{{label}}" > <VirtualList component="{{StatusListItem}}" items="{{keyedStatuses}}" on:scrollToBottom="onScrollToBottom()" /> </div> <style> .timeline { min-height: 50vh; } </style> <script> import { store } from '../_utils/store' import { getTimeline } from '../_utils/mastodon/timelines' import StatusListItem from './StatusListItem.html' import VirtualList from './VirtualList.html' import { splice, push } from 'svelte-extras' import { insertStatuses as insertStatusesIntoDatabase, getTimeline as getTimelineFromDatabase } from '../_utils/database/statuses' import { mergeStatuses } from '../_utils/statuses' import { mark, stop } from '../_utils/marks' import { timelines } from '../_static/timelines' const FETCH_LIMIT = 20 export default { async oncreate() { let instanceName = this.store.get('currentInstance') let instanceData = this.store.get('currentInstanceData') let online = this.get('online') let statuses = online ? await getTimeline(instanceName, instanceData.access_token, this.get('timeline'), null, FETCH_LIMIT) : await getTimelineFromDatabase(instanceName, this.get('timeline'), null, FETCH_LIMIT) if (online) { insertStatusesIntoDatabase(instanceName, this.get('timeline'), statuses) } this.addStatuses(statuses) this.set({initialized: true}) }, data: () => ({ StatusListItem: StatusListItem, statuses: [], runningUpdate: false, initialized: false }), computed: { keyedStatuses: (statuses) => statuses.map(status => ({ props: status, key: status.id })), lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id, label: (timeline, $currentInstance) => `${timelines[timeline].label} timeline for ${$currentInstance}` }, store: () => store, components: { VirtualList }, methods: { splice: splice, push: push, async onScrollToBottom() { if (!this.get('initialized')) { return } if (this.get('runningUpdate')) { return } mark('onScrollToBottom') this.set({ runningUpdate: true }) let lastStatusId = this.get('lastStatusId') let instanceName = this.store.get('currentInstance') let instanceData = this.store.get('currentInstanceData') let online = this.get('online') let newStatuses = online ? await getTimeline(instanceName, instanceData.access_token, this.get('timeline'), lastStatusId, FETCH_LIMIT) : await getTimelineFromDatabase(instanceName, this.get('timeline'), lastStatusId, FETCH_LIMIT) if (online) { insertStatusesIntoDatabase(instanceName, this.get('timeline'), newStatuses) } let statuses = this.get('statuses') if (statuses) { this.addStatuses(newStatuses) } this.set({ runningUpdate: false }) stop('onScrollToBottom') }, addStatuses(newStatuses) { if (process.env.NODE_ENV !== 'production') { console.log('addStatuses()') } let statuses = this.get('statuses') if (!statuses) { return } let merged = mergeStatuses(statuses, newStatuses) this.set({ statuses: merged }) } } } </script>