refs #3301 Rewrite TimelineSpace/Contents/SideBar/AccountProfile/Follows with composition API

This commit is contained in:
AkiraFukushima 2022-06-30 22:29:58 +09:00
parent ef7f783a6f
commit 5016f992cd
No known key found for this signature in database
GPG Key ID: B6E51BAC4DE1A957
2 changed files with 99 additions and 74 deletions

View File

@ -18,104 +18,123 @@
</div>
</template>
<script>
import { mapState } from 'vuex'
import User from '~/src/renderer/components/molecules/User'
<script lang="ts">
import { defineComponent, PropType, computed, onMounted, watch, onUnmounted, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import { useI18next } from 'vue3-i18next'
import { Entity } from 'megalodon'
import { useStore } from '@/store'
import User from '@/components/molecules/User.vue'
import { ACTION_TYPES } from '@/store/TimelineSpace/Contents/SideBar/AccountProfile/Follows'
import { ACTION_TYPES as PROFILE_ACTION, MUTATION_TYPES as PROFILE_MUTATION } from '@/store/TimelineSpace/Contents/SideBar/AccountProfile'
export default {
export default defineComponent({
name: 'follows',
props: ['account'],
props: {
account: {
type: Object as PropType<Entity.Account>,
required: true
}
},
components: { User },
computed: {
...mapState('TimelineSpace/Contents/SideBar/AccountProfile/Follows', {
follows: state => state.follows,
relationships: state => state.relationships,
lazyLoading: state => state.lazyLoading
}),
...mapState('App', {
backgroundColor: state => state.theme.background_color
setup(props) {
const space = 'TimelineSpace/Contents/SideBar/AccountProfile/Follows'
const { account } = toRefs(props)
const store = useStore()
const i18n = useI18next()
const follows = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.Follows.follows)
const relationships = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.Follows.relationships)
const lazyLoading = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.Follows.lazyLoading)
const backgroundColor = computed(() => store.state.App.theme.background_color)
onMounted(() => {
load()
document.getElementById('sidebar_scrollable')?.addEventListener('scroll', onScroll)
})
},
created() {
this.load()
},
mounted() {
document.getElementById('sidebar_scrollable').addEventListener('scroll', this.onScroll)
},
unmounted() {
if (document.getElementById('sidebar_scrollable') !== undefined && document.getElementById('sidebar_scrollable') !== null) {
document.getElementById('sidebar_scrollable').removeEventListener('scroll', this.onScroll)
watch(account, () => {
load()
})
onUnmounted(() => {
const el = document.getElementById('sidebar_scrollable')
if (el !== undefined && el !== null) {
el.removeEventListener('scroll', onScroll)
}
},
watch: {
account: function (_newAccount, _oldAccount) {
this.load()
}
},
methods: {
async load() {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
})
const load = async () => {
store.commit(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_MUTATION.CHANGE_LOADING}`, true)
try {
const follows = await this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Follows/fetchFollows', this.account)
await this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Follows/fetchRelationships', follows)
const follows = await store.dispatch(`${space}/${ACTION_TYPES.FETCH_FOLLOWS}`, account.value)
await store.dispatch(`${space}/${ACTION_TYPES.FETCH_RELATIONSHIPS}`, follows.value)
} catch (err) {
console.error(err)
this.$message({
message: this.$t('message.follows_fetch_error'),
ElMessage({
message: i18n.t('message.follows_fetch_error'),
type: 'error'
})
} finally {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
store.commit(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_MUTATION.CHANGE_LOADING}`, false)
}
},
onScroll(event) {
}
const onScroll = (event: Event) => {
// for lazyLoading
if (
event.target.clientHeight + event.target.scrollTop >= document.getElementById('account_profile').clientHeight - 10 &&
!this.lazyloading
(event.target as HTMLElement)!.clientHeight + (event.target as HTMLElement)!.scrollTop >=
document.getElementById('account_profile')!.clientHeight - 10 &&
!lazyLoading.value
) {
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Follows/lazyFetchFollows', this.account).catch(err => {
store.dispatch(`${space}/${ACTION_TYPES.LAZY_FETCH_FOLLOWS}`, account.value).catch(err => {
console.error(err)
this.$message({
message: this.$t('message.timeline_fetch_error'),
ElMessage({
message: i18n.t('message.timeline_fetch_error'),
type: 'error'
})
})
}
},
targetRelation(id) {
return this.relationships.find(r => r.id === id)
},
async followAccount(account) {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
}
const targetRelation = (id: string) => {
return relationships.value.find(r => r.id === id)
}
const followAccount = async (account: Entity.Account) => {
store.commit(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_MUTATION.CHANGE_LOADING}`, true)
try {
await this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/follow', account)
await this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Follows/fetchRelationships', this.follows)
await store.dispatch(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_ACTION.FOLLOW}`, account)
await store.dispatch(`${space}/${ACTION_TYPES.FETCH_RELATIONSHIPS}`, follows.value)
} catch (err) {
this.$message({
message: this.$t('message.follow_error'),
ElMessage({
message: i18n.t('message.follow_error'),
type: 'error'
})
} finally {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
store.commit(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_MUTATION.CHANGE_LOADING}`, false)
}
},
async unfollowAccount(account) {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
}
const unfollowAccount = async (account: Entity.Status) => {
store.commit(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_MUTATION.CHANGE_LOADING}`, true)
try {
await this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unfollow', account)
await this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/Follows/fetchRelationships', this.follows)
await store.dispatch(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_ACTION.UNFOLLOW}`, account)
await store.dispatch(`${space}/${ACTION_TYPES.FETCH_RELATIONSHIPS}`, follows.value)
} catch (err) {
this.$message({
message: this.$t('message.unfollow_error'),
ElMessage({
message: i18n.t('message.unfollow_error'),
type: 'error'
})
} finally {
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
store.commit(`TimelineSpace/Contents/SideBar/AccountProfile/${PROFILE_MUTATION.CHANGE_LOADING}`, false)
}
}
return {
follows,
targetRelation,
followAccount,
unfollowAccount,
lazyLoading,
backgroundColor
}
}
}
})
</script>
<style lang="scss" scoped>

View File

@ -43,8 +43,14 @@ const mutations: MutationTree<FollowsState> = {
}
}
export const ACTION_TYPES = {
FETCH_FOLLOWS: 'fetchFollows',
LAZY_FETCH_FOLLOWS: 'lazyFetchFollows',
FETCH_RELATIONSHIPS: 'fetchRelationships'
}
const actions: ActionTree<FollowsState, RootState> = {
fetchFollows: async ({ commit, rootState }, account: Entity.Account) => {
[ACTION_TYPES.FETCH_FOLLOWS]: async ({ commit, rootState }, account: Entity.Account) => {
const client = generator(
rootState.TimelineSpace.sns,
rootState.TimelineSpace.account.baseURL,
@ -67,7 +73,7 @@ const actions: ActionTree<FollowsState, RootState> = {
}
return res.data
},
lazyFetchFollows: async ({ commit, state, rootState }, account: Entity.Account) => {
[ACTION_TYPES.LAZY_FETCH_FOLLOWS]: async ({ commit, state, rootState }, account: Entity.Account) => {
if (state.lazyLoading) {
return Promise.resolve(null)
}
@ -100,7 +106,7 @@ const actions: ActionTree<FollowsState, RootState> = {
}
return res.data
},
fetchRelationships: async ({ commit, rootState }, accounts: Array<Entity.Account>) => {
[ACTION_TYPES.FETCH_RELATIONSHIPS]: async ({ commit, rootState }, accounts: Array<Entity.Account>) => {
const ids = accounts.map(a => a.id)
const client = generator(
rootState.TimelineSpace.sns,