Add followers and following lists to profile page

This commit is contained in:
silverpill 2022-01-02 18:03:24 +00:00
parent 1c50089734
commit d440b91033
3 changed files with 102 additions and 19 deletions

View file

@ -1,5 +1,6 @@
import { BACKEND_URL } from "@/constants"
import { http } from "./common"
import { Profile } from "./users"
export interface Relationship {
id: string,
@ -58,3 +59,23 @@ export async function unfollow(
return data
}
}
export async function getFollowers(
authToken: string,
accountId: string,
): Promise<Profile[]> {
const url = `${BACKEND_URL}/api/v1/accounts/${accountId}/followers`
const response = await http(url, { authToken })
const data = await response.json()
return data
}
export async function getFollowing(
authToken: string,
accountId: string,
): Promise<Profile[]> {
const url = `${BACKEND_URL}/api/v1/accounts/${accountId}/following`
const response = await http(url, { authToken })
const data = await response.json()
return data
}

View file

@ -86,6 +86,12 @@ const routes: Array<RouteRecordRaw> = [
component: ProfileView,
meta: { },
},
{
path: "/profile/:profileId/:tabName",
name: "profile-tab",
component: ProfileView,
meta: { onlyAuthenticated: true },
},
{
path: "/profile-directory",
name: "profile-directory",

View file

@ -1,7 +1,7 @@
<template>
<div id="main" v-if="profile">
<div class="content posts">
<div class="profile">
<div class="profile-block">
<div class="profile-header">
<img v-if="profile.header" :src="profile.header">
</div>
@ -27,16 +27,44 @@
<dd v-html="field.value"></dd>
</dl>
</div>
<dl class="stats">
<dt>{{ profile.statuses_count }}</dt><dd>posts</dd>
<dt>{{ profile.following_count }}</dt><dd>following</dd>
<dt>{{ profile.followers_count }}</dt><dd>followers</dd>
</dl>
<div class="stats">
<component
class="stats-item"
:is="isCurrentUser() ? 'router-link' : 'div'"
:to="{ name: 'profile-tab', params: { profileId: profile.id, tabName: 'posts' }}"
>
<span class="value">{{ profile.statuses_count }}</span>
<span class="label">posts</span>
</component>
<component
class="stats-item"
:is="isCurrentUser() ? 'router-link' : 'div'"
:to="{ name: 'profile-tab', params: { profileId: profile.id, tabName: 'followers' }}">
<span class="value">{{ profile.followers_count }}</span>
<span class="label">followers</span>
</component>
<component
class="stats-item"
:is="isCurrentUser() ? 'router-link' : 'div'"
:to="{ name: 'profile-tab', params: { profileId: profile.id, tabName: 'following' }}"
>
<span class="value">{{ profile.following_count }}</span>
<span class="label">following</span>
</component>
</div>
</div>
<post-list
v-if="tabName === 'posts'"
:posts="posts"
@load-next-page="loadNextPage"
></post-list>
<template v-if="tabName === 'followers' || tabName === 'following'">
<profile-list-item
v-for="profile in followList"
:profile="profile"
:key="profile.id"
></profile-list-item>
</template>
</div>
<sidebar></sidebar>
</div>
@ -52,9 +80,12 @@ import {
unfollow,
Relationship,
getRelationship,
getFollowers,
getFollowing,
} from "@/api/relationships"
import Avatar from "@/components/Avatar.vue"
import PostList from "@/components/PostList.vue"
import ProfileListItem from "@/components/ProfileListItem.vue"
import Sidebar from "@/components/Sidebar.vue"
import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user"
@ -63,6 +94,7 @@ import { useCurrentUser } from "@/store/user"
components: {
Avatar,
PostList,
ProfileListItem,
Sidebar,
},
})
@ -76,7 +108,9 @@ export default class ProfileView extends Vue {
profile: Profile | null = null
relationship: Relationship | null = null
tabName = "posts"
posts: Post[] = []
followList: Profile[] = []
async created() {
this.profile = await getProfile(
@ -89,10 +123,23 @@ export default class ProfileView extends Vue {
this.profile.id,
)
}
this.tabName = this.$route.params.tabName as string || "posts"
if (this.tabName === "posts") {
this.posts = await getProfileTimeline(
this.store.authToken,
this.profile.id,
)
} else if (this.tabName === "followers" && this.isCurrentUser()) {
this.followList = await getFollowers(
this.store.ensureAuthToken(),
this.profile.id,
)
} else if (this.tabName === "following" && this.isCurrentUser()) {
this.followList = await getFollowing(
this.store.ensureAuthToken(),
this.profile.id,
)
}
}
get actorAddress(): string {
@ -168,7 +215,7 @@ export default class ProfileView extends Vue {
$avatar-size: 170px;
.profile {
.profile-block {
background-color: $block-background-color;
border-radius: $block-border-radius;
margin-bottom: $block-outer-padding;
@ -256,19 +303,28 @@ $avatar-size: 170px;
.stats {
display: flex;
flex-direction: row;
flex-wrap: wrap;
font-weight: bold;
gap: $block-inner-padding 30px;
padding: 0 $block-inner-padding $block-inner-padding;
text-align: center;
dt {
.stats-item {
display: flex;
gap: 5px;
.value {
font-size: 18px;
}
dd {
.label {
align-self: flex-end;
color: $secondary-text-color;
margin-left: 5px;
margin-right: 30px;
}
}
}
.profile {
margin-bottom: $block-outer-padding;
}
</style>