refs #3301 Rewrite TimelineSpace/Contents/SideBar/AccountProfile with composition API
This commit is contained in:
parent
5016f992cd
commit
9fdd69ad0a
|
@ -8,14 +8,14 @@
|
||||||
role="article"
|
role="article"
|
||||||
aria-label="account profile"
|
aria-label="account profile"
|
||||||
>
|
>
|
||||||
<div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account.header + ')' }">
|
<div class="header-background" v-bind:style="{ backgroundImage: 'url(' + account?.header + ')' }">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="relationship" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
<div class="relationship" v-if="relationship !== null && !isOwnProfile">
|
||||||
<div class="follower-status">
|
<div class="follower-status">
|
||||||
<el-tag class="status" size="small" v-if="relationship.followed_by">{{ $t('side_bar.account_profile.follows_you') }}</el-tag>
|
<el-tag class="status" size="small" v-if="relationship.followed_by">{{ $t('side_bar.account_profile.follows_you') }}</el-tag>
|
||||||
<el-tag class="status" size="default" v-else>{{ $t('side_bar.account_profile.doesnt_follow_you') }}</el-tag>
|
<el-tag class="status" size="default" v-else>{{ $t('side_bar.account_profile.doesnt_follow_you') }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="notify" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
<div class="notify" v-if="relationship !== null && !isOwnProfile">
|
||||||
<div
|
<div
|
||||||
v-if="relationship.notifying"
|
v-if="relationship.notifying"
|
||||||
class="unsubscribe"
|
class="unsubscribe"
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<div class="more" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
<div class="more" v-if="relationship !== null && !isOwnProfile">
|
||||||
<el-popover placement="bottom" width="200" trigger="click" popper-class="account-menu-popper">
|
<el-popover placement="bottom" width="200" trigger="click" popper-class="account-menu-popper">
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li role="button" @click="openBrowser(account)">
|
<li role="button" @click="openBrowser(account)">
|
||||||
|
@ -62,9 +62,9 @@
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="icon" role="presentation">
|
<div class="icon" role="presentation">
|
||||||
<FailoverImg :src="account.avatar" :alt="`Avatar of ${account.username}`" />
|
<FailoverImg :src="account?.avatar" :alt="`Avatar of ${account?.username}`" />
|
||||||
</div>
|
</div>
|
||||||
<div class="follow-status" v-if="relationship !== null && relationship !== '' && !isOwnProfile">
|
<div class="follow-status" v-if="relationship !== null && !isOwnProfile">
|
||||||
<div v-if="relationship.following" class="unfollow" @click="unfollow(account)" :title="$t('side_bar.account_profile.unfollow')">
|
<div v-if="relationship.following" class="unfollow" @click="unfollow(account)" :title="$t('side_bar.account_profile.unfollow')">
|
||||||
<font-awesome-icon icon="user-xmark" size="xl" />
|
<font-awesome-icon icon="user-xmark" size="xl" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
<div class="username">
|
<div class="username">
|
||||||
<bdi v-html="username(account)"></bdi>
|
<bdi v-html="username(account)"></bdi>
|
||||||
</div>
|
</div>
|
||||||
<div class="account">@{{ account.acct }}</div>
|
<div class="account">@{{ account?.acct }}</div>
|
||||||
<div class="note" v-html="note(account)" @click.capture.prevent="noteClick"></div>
|
<div class="note" v-html="note(account)" @click.capture.prevent="noteClick"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="metadata">
|
<div class="metadata">
|
||||||
<dl v-for="(data, index) in account.fields" :key="index">
|
<dl v-for="(data, index) in account?.fields" :key="index">
|
||||||
<dt>
|
<dt>
|
||||||
{{ data.name }}
|
{{ data.name }}
|
||||||
</dt>
|
</dt>
|
||||||
|
@ -102,16 +102,16 @@
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<el-row class="basic-info">
|
<el-row class="basic-info">
|
||||||
<el-col :span="8" :class="activeTab === 1 ? 'info info-active' : 'info'" @click="changeTab">
|
<el-col :span="8" :class="activeTab === 1 ? 'info info-active' : 'info'">
|
||||||
<el-button type="text" class="tab" @click="changeTab(1)">
|
<el-button type="text" class="tab" @click="changeTab(1)">
|
||||||
<div class="title">{{ $t('side_bar.account_profile.toots') }}</div>
|
<div class="title">{{ $t('side_bar.account_profile.toots') }}</div>
|
||||||
<div class="count">{{ account.statuses_count }}</div>
|
<div class="count">{{ account?.statuses_count }}</div>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8" :class="activeTab === 2 ? 'info info-active' : 'info'">
|
<el-col :span="8" :class="activeTab === 2 ? 'info info-active' : 'info'">
|
||||||
<el-button type="text" class="tab" @click="changeTab(2)">
|
<el-button type="text" class="tab" @click="changeTab(2)">
|
||||||
<div class="title">{{ $t('side_bar.account_profile.follows') }}</div>
|
<div class="title">{{ $t('side_bar.account_profile.follows') }}</div>
|
||||||
<div class="count">{{ account.following_count }}</div>
|
<div class="count">{{ account?.following_count }}</div>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8" :class="activeTab === 3 ? 'info info-active' : 'info'">
|
<el-col :span="8" :class="activeTab === 3 ? 'info info-active' : 'info'">
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ $t('side_bar.account_profile.followers') }}
|
{{ $t('side_bar.account_profile.followers') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="count">{{ account.followers_count }}</div>
|
<div class="count">{{ account?.followers_count }}</div>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -131,16 +131,23 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { mapState, mapGetters } from 'vuex'
|
import { defineComponent, computed, ref, watch } from 'vue'
|
||||||
import { findLink } from '~/src/renderer/utils/tootParser'
|
import { ElMessage } from 'element-plus'
|
||||||
import emojify from '~/src/renderer/utils/emojify'
|
import { Entity } from 'megalodon'
|
||||||
import Timeline from './AccountProfile/Timeline'
|
import { useI18next } from 'vue3-i18next'
|
||||||
import Follows from './AccountProfile/Follows'
|
import { findLink } from '@/utils/tootParser'
|
||||||
import Followers from './AccountProfile/Followers'
|
import emojify from '@/utils/emojify'
|
||||||
import FailoverImg from '~/src/renderer/components/atoms/FailoverImg'
|
import Timeline from './AccountProfile/Timeline.vue'
|
||||||
|
import Follows from './AccountProfile/Follows.vue'
|
||||||
|
import Followers from './AccountProfile/Followers.vue'
|
||||||
|
import FailoverImg from '@/components/atoms/FailoverImg.vue'
|
||||||
|
import { useStore } from '@/store'
|
||||||
|
import { ACTION_TYPES, MUTATION_TYPES } from '@/store/TimelineSpace/Contents/SideBar/AccountProfile'
|
||||||
|
import { ACTION_TYPES as LIST_MEMBERSHIP_ACTION } from '@/store/TimelineSpace/Modals/ListMembership'
|
||||||
|
import { ACTION_TYPES as MUTE_ACTION } from '@/store/TimelineSpace/Modals/MuteConfirm'
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'account-profile',
|
name: 'account-profile',
|
||||||
components: {
|
components: {
|
||||||
Timeline,
|
Timeline,
|
||||||
|
@ -148,142 +155,165 @@ export default {
|
||||||
Followers,
|
Followers,
|
||||||
FailoverImg
|
FailoverImg
|
||||||
},
|
},
|
||||||
data() {
|
setup(_, ctx) {
|
||||||
return {
|
const space = 'TimelineSpace/Contents/SideBar/AccountProfile'
|
||||||
activeTab: 1
|
const store = useStore()
|
||||||
}
|
const i18n = useI18next()
|
||||||
},
|
|
||||||
computed: {
|
const activeTab = ref<number>(1)
|
||||||
...mapState({
|
|
||||||
theme: state => {
|
const theme = computed(() => {
|
||||||
return {
|
return {
|
||||||
'--theme-mask-color': state.App.theme.wrapper_mask_color,
|
'--theme-mask-color': store.state.App.theme.wrapper_mask_color,
|
||||||
'--theme-border-color': state.App.theme.border_color,
|
'--theme-border-color': store.state.App.theme.border_color,
|
||||||
'--theme-primary-color': state.App.theme.primary_color
|
'--theme-primary-color': store.state.App.theme.primary_color
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
...mapState('TimelineSpace/Contents/SideBar/AccountProfile', {
|
const account = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.account)
|
||||||
account: state => state.account,
|
const identityProofs = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.identityProofs)
|
||||||
identityProofs: state => state.identityProofs,
|
const relationship = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.relationship)
|
||||||
relationship: state => state.relationship,
|
const loading = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.loading)
|
||||||
loading: state => state.loading,
|
const muting = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.relationship?.muting)
|
||||||
muting: state => state.relationship && state.relationship.muting,
|
const blocking = computed(() => store.state.TimelineSpace.Contents.SideBar.AccountProfile.relationship?.blocking)
|
||||||
blocking: state => state.relationship && state.relationship.blocking
|
const isOwnProfile = computed(() => store.getters[`${space}/isOwnProfile`])
|
||||||
}),
|
|
||||||
...mapGetters('TimelineSpace/Contents/SideBar/AccountProfile', ['isOwnProfile'])
|
watch(account, () => {
|
||||||
},
|
activeTab.value = 1
|
||||||
watch: {
|
})
|
||||||
account: function () {
|
watch(loading, (newVal, _oldVal) => {
|
||||||
this.activeTab = 1
|
ctx.emit('change-loading', newVal)
|
||||||
},
|
})
|
||||||
loading: function (newState, _oldState) {
|
|
||||||
this.$emit('change-loading', newState)
|
const username = (account: Entity.Account) => {
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
username(account) {
|
|
||||||
if (account.display_name !== '') {
|
if (account.display_name !== '') {
|
||||||
return emojify(account.display_name, account.emojis)
|
return emojify(account.display_name, account.emojis)
|
||||||
} else {
|
} else {
|
||||||
return account.username
|
return account.username
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
note(account) {
|
const note = (account: Entity.Account) => {
|
||||||
return emojify(account.note, account.emojis)
|
return emojify(account.note, account.emojis)
|
||||||
},
|
}
|
||||||
noteClick(e) {
|
const noteClick = (e: Event) => {
|
||||||
const link = findLink(e.target, 'note')
|
const link = findLink(e.target as HTMLElement, 'note')
|
||||||
if (link !== null) {
|
if (link !== null) {
|
||||||
window.shell.openExternal(link)
|
;(window as any).shell.openExternal(link)
|
||||||
}
|
|
||||||
},
|
|
||||||
follow(account) {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
|
||||||
try {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/follow', account)
|
|
||||||
} catch (err) {
|
|
||||||
this.$message({
|
|
||||||
message: this.$t('message.follow_error'),
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
} finally {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unfollow(account) {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
|
||||||
try {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unfollow', account)
|
|
||||||
} catch (err) {
|
|
||||||
this.$message({
|
|
||||||
message: this.$t('message.unfollow_error'),
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
} finally {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changeTab(index) {
|
|
||||||
this.activeTab = index
|
|
||||||
},
|
|
||||||
openBrowser(account) {
|
|
||||||
window.shell.openExternal(account.url)
|
|
||||||
},
|
|
||||||
addToList(account) {
|
|
||||||
this.$store.dispatch('TimelineSpace/Modals/ListMembership/setAccount', account)
|
|
||||||
this.$store.dispatch('TimelineSpace/Modals/ListMembership/changeModal', true)
|
|
||||||
},
|
|
||||||
confirmMute(account) {
|
|
||||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeAccount', account)
|
|
||||||
this.$store.dispatch('TimelineSpace/Modals/MuteConfirm/changeModal', true)
|
|
||||||
},
|
|
||||||
unmute(account) {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unmute', account)
|
|
||||||
},
|
|
||||||
block(account) {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/block', account)
|
|
||||||
},
|
|
||||||
unblock(account) {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unblock', account)
|
|
||||||
},
|
|
||||||
metadataClick(e) {
|
|
||||||
const link = findLink(e.target, 'metadata')
|
|
||||||
if (link !== null) {
|
|
||||||
return window.shell.openExternal(link)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
identityOpen(link) {
|
|
||||||
return window.shell.openExternal(link)
|
|
||||||
},
|
|
||||||
subscribe(account) {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
|
||||||
try {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/subscribe', account)
|
|
||||||
} catch (err) {
|
|
||||||
this.$message({
|
|
||||||
message: this.$t('message.subscribe_error'),
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
} finally {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unsubscribe(account) {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', true)
|
|
||||||
try {
|
|
||||||
this.$store.dispatch('TimelineSpace/Contents/SideBar/AccountProfile/unsubscribe', account)
|
|
||||||
} catch (err) {
|
|
||||||
this.$message({
|
|
||||||
message: this.$t('message.unsubscribe_error'),
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
} finally {
|
|
||||||
this.$store.commit('TimelineSpace/Contents/SideBar/AccountProfile/changeLoading', false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const follow = (account: Entity.Account) => {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, true)
|
||||||
|
try {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.FOLLOW}`, account)
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage({
|
||||||
|
message: i18n.t('message.follow_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const unfollow = (account: Entity.Account) => {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, true)
|
||||||
|
try {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.UNFOLLOW}`, account)
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage({
|
||||||
|
message: i18n.t('message.unfollow_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const changeTab = (payload: number) => {
|
||||||
|
activeTab.value = payload
|
||||||
|
}
|
||||||
|
const openBrowser = (account: Entity.Account) => {
|
||||||
|
;(window as any).shell.openExternal(account.url)
|
||||||
|
}
|
||||||
|
const addToList = (account: Entity.Account) => {
|
||||||
|
store.dispatch(`TimelineSpace/Modals/ListMembership/${LIST_MEMBERSHIP_ACTION.SET_ACCOUNT}`, account)
|
||||||
|
store.dispatch(`TimelineSpace/Modals/ListMembership/${LIST_MEMBERSHIP_ACTION.CHANGE_MODAL}`, true)
|
||||||
|
}
|
||||||
|
const confirmMute = (account: Entity.Account) => {
|
||||||
|
store.dispatch(`TimelineSpace/Modals/MuteConfirm/${MUTE_ACTION.CHANGE_ACCOUNT}`, account)
|
||||||
|
store.dispatch(`TimelineSpace/Modals/MuteConfirm/${MUTE_ACTION.CHANGE_MODAL}`, true)
|
||||||
|
}
|
||||||
|
const unmute = (account: Entity.Account) => {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.UNMUTE}`, account)
|
||||||
|
}
|
||||||
|
const block = (account: Entity.Account) => {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.BLOCK}`, account)
|
||||||
|
}
|
||||||
|
const unblock = (account: Entity.Account) => {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.UNBLOCK}`, account)
|
||||||
|
}
|
||||||
|
const metadataClick = (e: Event) => {
|
||||||
|
const link = findLink(e.target as HTMLElement, 'metadata')
|
||||||
|
if (link !== null) {
|
||||||
|
return (window as any).shell.openExternal(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const identityOpen = (link: string) => {
|
||||||
|
return (window as any).shell.openExternal(link)
|
||||||
|
}
|
||||||
|
const subscribe = (account: Entity.Account) => {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, true)
|
||||||
|
try {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.SUBSCRIBE}`, account)
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage({
|
||||||
|
message: i18n.t('message.subscribe_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const unsubscribe = (account: Entity.Account) => {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, true)
|
||||||
|
try {
|
||||||
|
store.dispatch(`${space}/${ACTION_TYPES.UNSBSCRIBE}`, account)
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage({
|
||||||
|
message: i18n.t('message.unsubscribe_error'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
store.commit(`${space}/${MUTATION_TYPES.CHANGE_LOADING}`, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
activeTab,
|
||||||
|
loading,
|
||||||
|
account,
|
||||||
|
relationship,
|
||||||
|
isOwnProfile,
|
||||||
|
muting,
|
||||||
|
blocking,
|
||||||
|
identityProofs,
|
||||||
|
theme,
|
||||||
|
username,
|
||||||
|
note,
|
||||||
|
noteClick,
|
||||||
|
changeTab,
|
||||||
|
unsubscribe,
|
||||||
|
subscribe,
|
||||||
|
openBrowser,
|
||||||
|
addToList,
|
||||||
|
unmute,
|
||||||
|
confirmMute,
|
||||||
|
unblock,
|
||||||
|
block,
|
||||||
|
unfollow,
|
||||||
|
follow,
|
||||||
|
metadataClick,
|
||||||
|
identityOpen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in New Issue