use real statuses

This commit is contained in:
Nolan Lawson 2018-01-17 18:35:27 -08:00
parent bfe310fcca
commit b58033203d
5 changed files with 61 additions and 4849 deletions

View File

@ -46,13 +46,13 @@
</svg> </svg>
</button> </button>
</div> </div>
<div class="status-media" style="grid-template-columns: repeat(auto-fit, minmax({{minMediaWidth}}px, 1fr));"> <!--<div class="status-media" style="grid-template-columns: repeat(auto-fit, minmax({{minMediaWidth}}px, 1fr));">
{{#each originalMedia as media}} {{#each originalMedia as media}}
<div class="status-media-container"> <div class="status-media-container">
<img src="{{media.preview_url}}" alt="{{media.description || ''}}"/> <img src="{{media.preview_url}}" alt="{{media.description || ''}}"/>
</div> </div>
{{/each}} {{/each}}
</div> </div>-->
</article> </article>
<style> <style>

View File

@ -1,6 +1,6 @@
<div class="timeline"> <div class="timeline">
<VirtualList component="{{StatusListItem}}" <VirtualList component="{{StatusListItem}}"
items="{{statuses}}" items="{{keyedStatuses}}"
on:scrollToBottom="onScrollToBottom()" /> on:scrollToBottom="onScrollToBottom()" />
</div> </div>
<style> <style>
@ -11,25 +11,33 @@
<script> <script>
import { store } from '../_utils/store' import { store } from '../_utils/store'
import { getHomeTimeline } from '../_utils/mastodon/oauth' import { getHomeTimeline } from '../_utils/mastodon/oauth'
import fixture from '../_utils/fixture.json'
import StatusListItem from './StatusListItem.html' import StatusListItem from './StatusListItem.html'
import VirtualList from './VirtualList.html' import VirtualList from './VirtualList.html'
import { splice, push } from 'svelte-extras' import { splice, push } from 'svelte-extras'
import { mark, stop } from '../_utils/marks' import { mark, stop } from '../_utils/marks'
let i = -1
const createData = () => fixture.slice(0, 20).map(_ => ({
key: `${++i}`,
props: _
}))
export default { export default {
async oncreate() {
let instanceName = this.store.get('currentInstance')
let instanceData = this.store.get('currentInstanceData')
let statuses = await getHomeTimeline(instanceName, instanceData.access_token, null, 10)
this.set({
statuses: statuses,
})
},
data: () => ({ data: () => ({
target: 'home', target: 'home',
statuses: createData(), StatusListItem: StatusListItem,
StatusListItem: StatusListItem statuses: [],
runningUpdate: false
}), }),
computed: {
keyedStatuses: (statuses) => statuses.map(status => ({
props: status,
key: status.id
})),
lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id
},
store: () => store, store: () => store,
components: { components: {
VirtualList VirtualList
@ -37,13 +45,21 @@
methods: { methods: {
splice: splice, splice: splice,
push: push, push: push,
onScrollToBottom() { async onScrollToBottom() {
mark('onScrollToBottom') mark('onScrollToBottom')
if (this.get('runningUpdate')) {
return
}
this.set({ runningUpdate: true })
let lastStatusId = this.get('lastStatusId')
let instanceName = this.store.get('currentInstance')
let instanceData = this.store.get('currentInstanceData')
let newStatuses = await getHomeTimeline(instanceName, instanceData.access_token, lastStatusId, 10)
let statuses = this.get('statuses') let statuses = this.get('statuses')
if (statuses) { if (statuses) {
let itemsToAdd = createData() this.addItems(newStatuses)
this.addItems(itemsToAdd)
} }
this.set({ runningUpdate: false })
stop('onScrollToBottom') stop('onScrollToBottom')
}, },
addItems(items) { addItems(items) {

View File

@ -36,10 +36,14 @@
export default { export default {
oncreate() { oncreate() {
let key = this.get('key') let key = this.get('key')
// TODO: implement AsyncLayout
// TODO: implement batchUpdate
// TODO: fix resize on media
onIntersectionCallbacks[key] = entry => { onIntersectionCallbacks[key] = entry => {
console.log('onIntersection', key, entry.boundingClientRect.height)
let rect = entry.boundingClientRect let rect = entry.boundingClientRect
updateItemHeights[key] = rect.height updateItemHeights[key] = rect.height
promise.then(() => { promise = promise.then(() => {
// update all item heights in one microtask batch for better perf // update all item heights in one microtask batch for better perf
let updatedKeys = Object.keys(updateItemHeights) let updatedKeys = Object.keys(updateItemHeights)
if (!updatedKeys.length) { if (!updatedKeys.length) {
@ -57,12 +61,22 @@
updateItemHeights = {} updateItemHeights = {}
stop('batch update VirtualListItem') stop('batch update VirtualListItem')
}) })
this.set({ unobserved: true })
intersectionObserver.unobserve(this.refs.node)
} }
intersectionObserver.observe(this.refs.node) intersectionObserver.observe(this.refs.node)
}, },
ondestroy() { ondestroy() {
let key = this.get('key')
if (!this.get('unobserved')) {
intersectionObserver.unobserve(this.refs.node) intersectionObserver.unobserve(this.refs.node)
}
delete onIntersectionCallbacks[key]
delete updateItemHeights[key]
}, },
data: () => ({
unobserved: false
}),
store: () => virtualListStore, store: () => virtualListStore,
computed: { computed: {
'shown': ($itemHeights, key) => $itemHeights[key] > 0 'shown': ($itemHeights, key) => $itemHeights[key] > 0

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,20 @@ export function getAccessTokenFromAuthCode(instanceName, clientId, clientSecret,
}) })
} }
export function getHomeTimeline(instanceName, accessToken) { export function getHomeTimeline(instanceName, accessToken, since, limit) {
let url = `https://${instanceName}/api/v1/timelines/home` let url = `https://${instanceName}/api/v1/timelines/home`
let params = {}
if (since) {
params[since] = since
}
if (limit) {
params[limit] = limit
}
url += '?' + paramsString(params)
return get(url, { return get(url, {
'Authorization': `Bearer ${accessToken}` 'Authorization': `Bearer ${accessToken}`
}) })