Show user followers
This commit is contained in:
parent
1cfbffc213
commit
63ea0b8d63
|
@ -1,6 +1,8 @@
|
||||||
.author {
|
.author {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
margin-bottom: 2.4rem;
|
margin-bottom: 2.4rem;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
@ -293,6 +295,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nowrapView {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.authorComments {
|
.authorComments {
|
||||||
.authorName {
|
.authorName {
|
||||||
@include font-size(1.2rem);
|
@include font-size(1.2rem);
|
||||||
|
|
|
@ -30,6 +30,7 @@ interface AuthorCardProps {
|
||||||
liteButtons?: boolean
|
liteButtons?: boolean
|
||||||
isComments?: boolean
|
isComments?: boolean
|
||||||
isFeedMode?: boolean
|
isFeedMode?: boolean
|
||||||
|
isNowrap?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuthorCard = (props: AuthorCardProps) => {
|
export const AuthorCard = (props: AuthorCardProps) => {
|
||||||
|
@ -83,7 +84,8 @@ export const AuthorCard = (props: AuthorCardProps) => {
|
||||||
[styles.authorPage]: props.isAuthorPage,
|
[styles.authorPage]: props.isAuthorPage,
|
||||||
[styles.authorComments]: props.isComments,
|
[styles.authorComments]: props.isComments,
|
||||||
[styles.authorsListItem]: props.isAuthorsList,
|
[styles.authorsListItem]: props.isAuthorsList,
|
||||||
[styles.feedMode]: props.isFeedMode
|
[styles.feedMode]: props.isFeedMode,
|
||||||
|
[styles.nowrapView]: props.isNowrap
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Userpic
|
<Userpic
|
||||||
|
|
|
@ -55,4 +55,19 @@
|
||||||
max-height: 15em;
|
max-height: 15em;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
.subscriber {
|
||||||
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px 4px;
|
||||||
|
transition: background 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f7f7f7;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { Popup } from '../_shared/Popup'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import { Comment } from '../Article/Comment'
|
import { Comment } from '../Article/Comment'
|
||||||
|
import DialogAvatar from '../Inbox/DialogAvatar'
|
||||||
|
|
||||||
// TODO: load reactions on client
|
// TODO: load reactions on client
|
||||||
type AuthorProps = {
|
type AuthorProps = {
|
||||||
|
@ -43,7 +44,16 @@ export const AuthorView = (props: AuthorProps) => {
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
|
|
||||||
const author = createMemo(() => authorEntities()[props.authorSlug])
|
const author = createMemo(() => authorEntities()[props.authorSlug])
|
||||||
const subscribers = Array.from({ length: 12 }).fill(author())
|
const [followers, setFollowers] = createSignal<Author[]>([])
|
||||||
|
onMount(async () => {
|
||||||
|
try {
|
||||||
|
const authorSubscribers = await apiClient.getAuthorFollowers({ slug: props.author.slug })
|
||||||
|
setFollowers(authorSubscribers)
|
||||||
|
} catch (error) {
|
||||||
|
console.log('[getAuthorSubscribers]', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>()
|
const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>()
|
||||||
|
|
||||||
changeSearchParam('by', 'rating')
|
changeSearchParam('by', 'rating')
|
||||||
|
@ -136,19 +146,36 @@ export const AuthorView = (props: AuthorProps) => {
|
||||||
{...props}
|
{...props}
|
||||||
trigger={
|
trigger={
|
||||||
<div class={styles.subscribers}>
|
<div class={styles.subscribers}>
|
||||||
<Userpic user={author()} class={styles.userpic} />
|
<Switch>
|
||||||
<Userpic user={author()} class={styles.userpic} />
|
<Match when={followers().length <= 3}>
|
||||||
<Userpic user={author()} class={styles.userpic} />
|
<For each={followers().slice(0, 3)}>
|
||||||
<div class={clsx(styles.userpic, styles.subscribersCounter)}>12</div>
|
{(f) => <Userpic user={f} class={styles.userpic} />}
|
||||||
|
</For>
|
||||||
|
</Match>
|
||||||
|
<Match when={followers().length > 3}>
|
||||||
|
<For each={followers().slice(0, 2)}>
|
||||||
|
{(f) => <Userpic user={f} class={styles.userpic} />}
|
||||||
|
</For>
|
||||||
|
<div class={clsx(styles.userpic, styles.subscribersCounter)}>
|
||||||
|
{followers().length}
|
||||||
|
</div>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
variant="tiny"
|
variant="tiny"
|
||||||
>
|
>
|
||||||
<ul class={clsx('nodash', styles.subscribersList)}>
|
<ul class={clsx('nodash', styles.subscribersList)}>
|
||||||
<For each={subscribers}>
|
<For each={followers()}>
|
||||||
{(item: Author) => (
|
{(item: Author) => (
|
||||||
<li>
|
<li class={styles.subscriber}>
|
||||||
<AuthorCard author={item} hideDescription={true} hideFollow={true} hasLink={true} />
|
<AuthorCard
|
||||||
|
author={item}
|
||||||
|
isNowrap={true}
|
||||||
|
hideDescription={true}
|
||||||
|
hideFollow={true}
|
||||||
|
hasLink={true}
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
|
@ -156,7 +183,7 @@ export const AuthorView = (props: AuthorProps) => {
|
||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
<div class={styles.ratingContainer}>
|
<div class={styles.ratingContainer}>
|
||||||
Карма
|
{t('Karma')}
|
||||||
<RatingControl rating={19} class={styles.ratingControl} />
|
<RatingControl rating={19} class={styles.ratingControl} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,22 +2,12 @@ import { gql } from '@urql/core'
|
||||||
|
|
||||||
export default gql`
|
export default gql`
|
||||||
query UserSubscribersQuery($slug: String!) {
|
query UserSubscribersQuery($slug: String!) {
|
||||||
userSubcribers(slug: $slug) {
|
userFollowers(slug: $slug) {
|
||||||
_id: slug
|
_id: slug
|
||||||
id
|
id
|
||||||
slug
|
slug
|
||||||
name
|
name
|
||||||
bio
|
|
||||||
userpic
|
userpic
|
||||||
communities
|
|
||||||
links
|
|
||||||
createdAt
|
|
||||||
lastSeen
|
|
||||||
ratings {
|
|
||||||
_id: rater
|
|
||||||
rater
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
@ -237,5 +237,6 @@
|
||||||
"Header": "Заголовок",
|
"Header": "Заголовок",
|
||||||
"Subheader": "Подзаголовок",
|
"Subheader": "Подзаголовок",
|
||||||
"A short introduction to keep the reader interested": "Небольшое вступление, чтобы заинтересовать читателя",
|
"A short introduction to keep the reader interested": "Небольшое вступление, чтобы заинтересовать читателя",
|
||||||
"Publish": "Опубликовать"
|
"Publish": "Опубликовать",
|
||||||
|
"Karma": "Карма"
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import createArticle from '../graphql/mutation/article-create'
|
||||||
import myChats from '../graphql/query/chats-load'
|
import myChats from '../graphql/query/chats-load'
|
||||||
import chatMessagesLoadBy from '../graphql/query/chat-messages-load-by'
|
import chatMessagesLoadBy from '../graphql/query/chat-messages-load-by'
|
||||||
import authorBySlug from '../graphql/query/author-by-slug'
|
import authorBySlug from '../graphql/query/author-by-slug'
|
||||||
|
import userSubscribers from '../graphql/query/author-followers'
|
||||||
import topicBySlug from '../graphql/query/topic-by-slug'
|
import topicBySlug from '../graphql/query/topic-by-slug'
|
||||||
import createChat from '../graphql/mutation/create-chat'
|
import createChat from '../graphql/mutation/create-chat'
|
||||||
import reactionsLoadBy from '../graphql/query/reactions-load-by'
|
import reactionsLoadBy from '../graphql/query/reactions-load-by'
|
||||||
|
@ -217,9 +218,12 @@ export const apiClient = {
|
||||||
const response = await publicGraphQLClient.query(authorBySlug, { slug }).toPromise()
|
const response = await publicGraphQLClient.query(authorBySlug, { slug }).toPromise()
|
||||||
return response.data.getAuthor
|
return response.data.getAuthor
|
||||||
},
|
},
|
||||||
|
getAuthorFollowers: async ({ slug }: { slug: string }): Promise<Author[]> => {
|
||||||
|
const response = await publicGraphQLClient.query(userSubscribers, { slug }).toPromise()
|
||||||
|
return response.data.userFollowers
|
||||||
|
},
|
||||||
updateProfile: async (input: ProfileInput) => {
|
updateProfile: async (input: ProfileInput) => {
|
||||||
const response = await privateGraphQLClient.mutation(updateProfile, { profile: input }).toPromise()
|
const response = await privateGraphQLClient.mutation(updateProfile, { profile: input }).toPromise()
|
||||||
console.log('!!! response.data.getAuthor:', response.data.updateProfile)
|
|
||||||
return response.data.updateProfile
|
return response.data.updateProfile
|
||||||
},
|
},
|
||||||
getTopic: async ({ slug }: { slug: string }): Promise<Topic> => {
|
getTopic: async ({ slug }: { slug: string }): Promise<Topic> => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user