aboutsummaryrefslogtreecommitdiff
path: root/src/components/user_profile
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/user_profile')
-rw-r--r--src/components/user_profile/user_profile.js137
-rw-r--r--src/components/user_profile/user_profile.vue147
2 files changed, 158 insertions, 126 deletions
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 1df06fe6..39b99dac 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -1,47 +1,39 @@
-import { compose } from 'vue-compose'
import get from 'lodash/get'
import UserCard from '../user_card/user_card.vue'
import FollowCard from '../follow_card/follow_card.vue'
import Timeline from '../timeline/timeline.vue'
+import Conversation from '../conversation/conversation.vue'
+import List from '../list/list.vue'
import withLoadMore from '../../hocs/with_load_more/with_load_more'
-import withList from '../../hocs/with_list/with_list'
-const FollowerList = compose(
- withLoadMore({
- fetch: (props, $store) => $store.dispatch('addFollowers', props.userId),
- select: (props, $store) => get($store.getters.findUser(props.userId), 'followers', []),
- destory: (props, $store) => $store.dispatch('clearFollowers', props.userId),
- childPropName: 'entries',
- additionalPropNames: ['userId']
- }),
- withList({ getEntryProps: user => ({ user }) })
-)(FollowCard)
+const FollowerList = withLoadMore({
+ fetch: (props, $store) => $store.dispatch('fetchFollowers', props.userId),
+ select: (props, $store) => get($store.getters.findUser(props.userId), 'followerIds', []).map(id => $store.getters.findUser(id)),
+ destroy: (props, $store) => $store.dispatch('clearFollowers', props.userId),
+ childPropName: 'items',
+ additionalPropNames: ['userId']
+})(List)
-const FriendList = compose(
- withLoadMore({
- fetch: (props, $store) => $store.dispatch('addFriends', props.userId),
- select: (props, $store) => get($store.getters.findUser(props.userId), 'friends', []),
- destory: (props, $store) => $store.dispatch('clearFriends', props.userId),
- childPropName: 'entries',
- additionalPropNames: ['userId']
- }),
- withList({ getEntryProps: user => ({ user }) })
-)(FollowCard)
+const FriendList = withLoadMore({
+ fetch: (props, $store) => $store.dispatch('fetchFriends', props.userId),
+ select: (props, $store) => get($store.getters.findUser(props.userId), 'friendIds', []).map(id => $store.getters.findUser(id)),
+ destroy: (props, $store) => $store.dispatch('clearFriends', props.userId),
+ childPropName: 'items',
+ additionalPropNames: ['userId']
+})(List)
const UserProfile = {
data () {
return {
error: false,
- fetchedUserId: null
+ userId: null
}
},
created () {
- if (!this.user.id) {
- this.fetchUserId()
- .then(() => this.startUp())
- } else {
- this.startUp()
- }
+ // Make sure that timelines used in this page are empty
+ this.cleanUp()
+ const routeParams = this.$route.params
+ this.load(routeParams.name || routeParams.id)
},
destroyed () {
this.cleanUp()
@@ -56,26 +48,12 @@ const UserProfile = {
media () {
return this.$store.state.statuses.timelines.media
},
- userId () {
- return this.$route.params.id || this.user.id || this.fetchedUserId
- },
- userName () {
- return this.$route.params.name || this.user.screen_name
- },
isUs () {
return this.userId && this.$store.state.users.currentUser.id &&
this.userId === this.$store.state.users.currentUser.id
},
- userInStore () {
- const routeParams = this.$route.params
- // This needs fetchedUserId so that computed will be refreshed when user is fetched
- return this.$store.getters.findUser(this.fetchedUserId || routeParams.name || routeParams.id)
- },
user () {
- if (this.userInStore) {
- return this.userInStore
- }
- return {}
+ return this.$store.getters.findUser(this.userId)
},
isExternal () {
return this.$route.name === 'external-user-profile'
@@ -88,40 +66,39 @@ const UserProfile = {
}
},
methods: {
- startFetchFavorites () {
- if (this.isUs) {
- this.$store.dispatch('startFetching', { timeline: 'favorites', userId: this.userId })
- }
- },
- fetchUserId () {
- let fetchPromise
- if (this.userId && !this.$route.params.name) {
- fetchPromise = this.$store.dispatch('fetchUser', this.userId)
+ load (userNameOrId) {
+ // Check if user data is already loaded in store
+ const user = this.$store.getters.findUser(userNameOrId)
+ if (user) {
+ this.userId = user.id
+ this.fetchTimelines()
} else {
- fetchPromise = this.$store.dispatch('fetchUser', this.userName)
+ this.$store.dispatch('fetchUser', userNameOrId)
.then(({ id }) => {
- this.fetchedUserId = id
+ this.userId = id
+ this.fetchTimelines()
+ })
+ .catch((reason) => {
+ const errorMessage = get(reason, 'error.error')
+ if (errorMessage === 'No user with such user_id') { // Known error
+ this.error = this.$t('user_profile.profile_does_not_exist')
+ } else if (errorMessage) {
+ this.error = errorMessage
+ } else {
+ this.error = this.$t('user_profile.profile_loading_error')
+ }
})
}
- return fetchPromise
- .catch((reason) => {
- const errorMessage = get(reason, 'error.error')
- if (errorMessage === 'No user with such user_id') { // Known error
- this.error = this.$t('user_profile.profile_does_not_exist')
- } else if (errorMessage) {
- this.error = errorMessage
- } else {
- this.error = this.$t('user_profile.profile_loading_error')
- }
- })
- .then(() => this.startUp())
},
- startUp () {
- if (this.userId) {
- this.$store.dispatch('startFetching', { timeline: 'user', userId: this.userId })
- this.$store.dispatch('startFetching', { timeline: 'media', userId: this.userId })
- this.startFetchFavorites()
+ fetchTimelines () {
+ const userId = this.userId
+ this.$store.dispatch('startFetchingTimeline', { timeline: 'user', userId })
+ this.$store.dispatch('startFetchingTimeline', { timeline: 'media', userId })
+ if (this.isUs) {
+ this.$store.dispatch('startFetchingTimeline', { timeline: 'favorites', userId })
}
+ // Fetch all pinned statuses immediately
+ this.$store.dispatch('fetchPinnedStatuses', userId)
},
cleanUp () {
this.$store.dispatch('stopFetching', 'user')
@@ -133,18 +110,16 @@ const UserProfile = {
}
},
watch: {
- // userId can be undefined if we don't know it yet
- userId (newVal) {
+ '$route.params.id': function (newVal) {
if (newVal) {
this.cleanUp()
- this.startUp()
+ this.load(newVal)
}
},
- userName () {
- if (this.$route.params.name) {
- this.fetchUserId()
+ '$route.params.name': function (newVal) {
+ if (newVal) {
this.cleanUp()
- this.startUp()
+ this.load(newVal)
}
},
$route () {
@@ -155,7 +130,9 @@ const UserProfile = {
UserCard,
Timeline,
FollowerList,
- FriendList
+ FriendList,
+ FollowCard,
+ Conversation
}
}
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index d449eb85..4ea0a869 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -1,55 +1,110 @@
<template>
-<div>
- <div v-if="user.id" class="user-profile panel panel-default">
- <UserCard :user="user" :switcher="true" :selected="timeline.viewing" rounded="top"/>
- <tab-switcher :renderOnlyFocused="true" ref="tabSwitcher">
- <Timeline
- :label="$t('user_card.statuses')"
- :disabled="!user.statuses_count"
- :count="user.statuses_count"
- :embedded="true"
- :title="$t('user_profile.timeline_title')"
- :timeline="timeline"
- :timeline-name="'user'"
- :user-id="userId"
+ <div>
+ <div
+ v-if="user"
+ class="user-profile panel panel-default"
+ >
+ <UserCard
+ :user="user"
+ :switcher="true"
+ :selected="timeline.viewing"
+ rounded="top"
/>
- <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
- <FriendList :userId="userId" />
- </div>
- <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
- <FollowerList :userId="userId" :entryProps="{noFollowsYou: isUs}" />
+ <tab-switcher
+ ref="tabSwitcher"
+ :render-only-focused="true"
+ >
+ <div :label="$t('user_card.statuses')">
+ <div class="timeline">
+ <template v-for="statusId in user.pinnedStatuseIds">
+ <Conversation
+ v-if="timeline.statusesObject[statusId]"
+ :key="statusId"
+ class="status-fadein"
+ :statusoid="timeline.statusesObject[statusId]"
+ :collapsable="true"
+ :show-pinned="true"
+ />
+ </template>
+ </div>
+ <Timeline
+ :count="user.statuses_count"
+ :embedded="true"
+ :title="$t('user_profile.timeline_title')"
+ :timeline="timeline"
+ :timeline-name="'user'"
+ :user-id="userId"
+ />
+ </div>
+ <div
+ v-if="followsTabVisible"
+ :label="$t('user_card.followees')"
+ :disabled="!user.friends_count"
+ >
+ <FriendList :user-id="userId">
+ <template
+ slot="item"
+ slot-scope="{item}"
+ >
+ <FollowCard :user="item" />
+ </template>
+ </FriendList>
+ </div>
+ <div
+ v-if="followersTabVisible"
+ :label="$t('user_card.followers')"
+ :disabled="!user.followers_count"
+ >
+ <FollowerList :user-id="userId">
+ <template
+ slot="item"
+ slot-scope="{item}"
+ >
+ <FollowCard
+ :user="item"
+ :no-follows-you="isUs"
+ />
+ </template>
+ </FollowerList>
+ </div>
+ <Timeline
+ :label="$t('user_card.media')"
+ :disabled="!media.visibleStatuses.length"
+ :embedded="true"
+ :title="$t('user_card.media')"
+ timeline-name="media"
+ :timeline="media"
+ :user-id="userId"
+ />
+ <Timeline
+ v-if="isUs"
+ :label="$t('user_card.favorites')"
+ :disabled="!favorites.visibleStatuses.length"
+ :embedded="true"
+ :title="$t('user_card.favorites')"
+ timeline-name="favorites"
+ :timeline="favorites"
+ />
+ </tab-switcher>
+ </div>
+ <div
+ v-else
+ class="panel user-profile-placeholder"
+ >
+ <div class="panel-heading">
+ <div class="title">
+ {{ $t('settings.profile_tab') }}
+ </div>
</div>
- <Timeline
- :label="$t('user_card.media')"
- :disabled="!media.visibleStatuses.length"
- :embedded="true" :title="$t('user_card.media')"
- timeline-name="media"
- :timeline="media"
- :user-id="userId"
- />
- <Timeline
- v-if="isUs"
- :label="$t('user_card.favorites')"
- :disabled="!favorites.visibleStatuses.length"
- :embedded="true"
- :title="$t('user_card.favorites')"
- timeline-name="favorites"
- :timeline="favorites"
- />
- </tab-switcher>
- </div>
- <div v-else class="panel user-profile-placeholder">
- <div class="panel-heading">
- <div class="title">
- {{ $t('settings.profile_tab') }}
+ <div class="panel-body">
+ <span v-if="error">{{ error }}</span>
+ <i
+ v-else
+ class="icon-spin3 animate-spin"
+ />
</div>
</div>
- <div class="panel-body">
- <span v-if="error">{{ error }}</span>
- <i class="icon-spin3 animate-spin" v-else></i>
- </div>
</div>
-</div>
</template>
<script src="./user_profile.js"></script>