refs #2988 Lazy load followers in user's profile
This commit is contained in:
parent
7f106ad06b
commit
488f3759d3
|
@ -8,6 +8,7 @@
|
|||
</DynamicScrollerItem>
|
||||
</template>
|
||||
</DynamicScroller>
|
||||
<div class="loading-card" v-loading="lazyLoading" :element-loading-background="backgroundColor"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -22,7 +23,11 @@ export default {
|
|||
computed: {
|
||||
...mapState('TimelineSpace/Contents/SideBar/AccountProfile/Followers', {
|
||||
followers: state => state.followers,
|
||||
relationships: state => state.relationships
|
||||
relationships: state => state.relationships,
|
||||
lazyLoading: state => state.lazyLoading
|
||||
}),
|
||||
...mapState('App', {
|
||||
backgroundColor: state => state.theme.background_color
|
||||
})
|
||||
},
|
||||
created() {
|
||||
|
@ -33,6 +38,14 @@ export default {
|
|||
this.load()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
|
||||
},
|
||||
destroyed() {
|
||||
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
|
||||
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async load() {
|
||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
||||
|
@ -48,6 +61,21 @@ export default {
|
|||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
||||
}
|
||||
},
|
||||
onScroll(event) {
|
||||
// for lazyLoading
|
||||
if (
|
||||
event.target.clientHeight + event.target.scrollTop >= document.getElementById('account_profile').clientHeight - 10 &&
|
||||
!this.lazyloading
|
||||
) {
|
||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Followers/lazyFetchFollowers', this.account).catch(err => {
|
||||
console.error(err)
|
||||
this.$message({
|
||||
message: this.$t('message.timeline_fetch_error'),
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
targetRelation(id) {
|
||||
return this.relationships.find(r => r.id === id)
|
||||
},
|
||||
|
@ -83,4 +111,12 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.loading-card {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.loading-card:empty {
|
||||
height: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,28 +1,45 @@
|
|||
import generator, { Entity } from 'megalodon'
|
||||
import parse from 'parse-link-header'
|
||||
import { Module, MutationTree, ActionTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
export type FollowersState = {
|
||||
followers: Array<Entity.Account>
|
||||
relationships: Array<Entity.Relationship>
|
||||
lazyLoading: boolean
|
||||
maxId: string | null
|
||||
}
|
||||
|
||||
const state = (): FollowersState => ({
|
||||
followers: [],
|
||||
relationships: []
|
||||
relationships: [],
|
||||
lazyLoading: false,
|
||||
maxId: null
|
||||
})
|
||||
|
||||
export const MUTATION_TYPES = {
|
||||
UPDATE_FOLLOWERS: 'updateFollowers',
|
||||
UPDATE_RELATIONSHIPS: 'updateRelationships'
|
||||
APPEND_FOLLOWERS: 'appendFollowers',
|
||||
UPDATE_RELATIONSHIPS: 'updateRelationships',
|
||||
CHANGE_LAZY_LOADING: 'changeLazyLoading',
|
||||
CHANGE_MAX_ID: 'changeMaxId'
|
||||
}
|
||||
|
||||
const mutations: MutationTree<FollowersState> = {
|
||||
[MUTATION_TYPES.UPDATE_FOLLOWERS]: (state, users: Array<Entity.Account>) => {
|
||||
state.followers = users
|
||||
},
|
||||
[MUTATION_TYPES.APPEND_FOLLOWERS]: (state, users: Array<Entity.Account>) => {
|
||||
state.followers = state.followers.concat(users)
|
||||
},
|
||||
[MUTATION_TYPES.UPDATE_RELATIONSHIPS]: (state, relations: Array<Entity.Relationship>) => {
|
||||
state.relationships = relations
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_LAZY_LOADING]: (state, loading: boolean) => {
|
||||
state.lazyLoading = loading
|
||||
},
|
||||
[MUTATION_TYPES.CHANGE_MAX_ID]: (state, maxId: string | null) => {
|
||||
state.maxId = maxId
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +53,51 @@ const actions: ActionTree<FollowersState, RootState> = {
|
|||
)
|
||||
const res = await client.getAccountFollowers(account.id, { limit: 80 })
|
||||
commit(MUTATION_TYPES.UPDATE_FOLLOWERS, res.data)
|
||||
// Parse link header
|
||||
try {
|
||||
const link = parse(res.headers.link)
|
||||
if (link !== null) {
|
||||
commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
|
||||
} else {
|
||||
commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
|
||||
}
|
||||
} catch (err) {
|
||||
commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
|
||||
console.error(err)
|
||||
}
|
||||
return res.data
|
||||
},
|
||||
lazyFetchFollowers: async ({ commit, state, rootState }, account: Entity.Account) => {
|
||||
if (state.lazyLoading) {
|
||||
return Promise.resolve(null)
|
||||
}
|
||||
if (!state.maxId) {
|
||||
return Promise.resolve(null)
|
||||
}
|
||||
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, true)
|
||||
const client = generator(
|
||||
rootState.TimelineSpace.sns,
|
||||
rootState.TimelineSpace.account.baseURL,
|
||||
rootState.TimelineSpace.account.accessToken,
|
||||
rootState.App.userAgent
|
||||
)
|
||||
const res = await client.getAccountFollowers(account.id, { limit: 80, max_id: state.maxId }).finally(() => {
|
||||
commit(MUTATION_TYPES.CHANGE_LAZY_LOADING, false)
|
||||
})
|
||||
|
||||
commit(MUTATION_TYPES.APPEND_FOLLOWERS, res.data)
|
||||
// Parse link header
|
||||
try {
|
||||
const link = parse(res.headers.link)
|
||||
if (link !== null) {
|
||||
commit(MUTATION_TYPES.CHANGE_MAX_ID, link.next.max_id)
|
||||
} else {
|
||||
commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
|
||||
}
|
||||
} catch (err) {
|
||||
commit(MUTATION_TYPES.CHANGE_MAX_ID, null)
|
||||
console.error(err)
|
||||
}
|
||||
return res.data
|
||||
},
|
||||
fetchRelationships: async ({ commit, rootState }, accounts: Array<Entity.Account>) => {
|
||||
|
|
Loading…
Reference in New Issue