all-topics-all-authors-cosmetics-and-refactoring
This commit is contained in:
parent
8dd394eee1
commit
3624004e03
|
@ -9,6 +9,7 @@ import { locale } from '../../stores/ui'
|
||||||
import { follow, unfollow } from '../../stores/zine/common'
|
import { follow, unfollow } from '../../stores/zine/common'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { useSession } from '../../context/session'
|
import { useSession } from '../../context/session'
|
||||||
|
import { StatMetrics } from '../_shared/StatMetrics'
|
||||||
|
|
||||||
interface AuthorCardProps {
|
interface AuthorCardProps {
|
||||||
caption?: string
|
caption?: string
|
||||||
|
@ -69,9 +70,11 @@ export const AuthorCard = (props: AuthorCardProps) => {
|
||||||
|
|
||||||
<Show when={!props.hideDescription}>
|
<Show when={!props.hideDescription}>
|
||||||
{props.isAuthorsList}
|
{props.isAuthorsList}
|
||||||
<div class={styles.authorAbout} classList={{ 'text-truncate': props.truncateBio }}>
|
<div
|
||||||
{bio()}
|
class={styles.authorAbout}
|
||||||
</div>
|
classList={{ 'text-truncate': props.truncateBio }}
|
||||||
|
innerHTML={props.caption || bio()}
|
||||||
|
></div>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { capitalize, plural } from '../../utils'
|
import { capitalize } from '../../utils'
|
||||||
import styles from './Card.module.scss'
|
import styles from './Card.module.scss'
|
||||||
import { createMemo, Show } from 'solid-js'
|
import { createMemo, Show } from 'solid-js'
|
||||||
import type { Topic } from '../../graphql/types.gen'
|
import type { Topic } from '../../graphql/types.gen'
|
||||||
import { FollowingEntity } from '../../graphql/types.gen'
|
import { FollowingEntity } from '../../graphql/types.gen'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { locale } from '../../stores/ui'
|
|
||||||
import { follow, unfollow } from '../../stores/zine/common'
|
import { follow, unfollow } from '../../stores/zine/common'
|
||||||
import { getLogger } from '../../utils/logger'
|
import { getLogger } from '../../utils/logger'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { useSession } from '../../context/session'
|
import { useSession } from '../../context/session'
|
||||||
|
import { StatMetrics } from '../_shared/StatMetrics'
|
||||||
|
|
||||||
const log = getLogger('TopicCard')
|
const log = getLogger('TopicCard')
|
||||||
|
|
||||||
|
@ -74,54 +74,6 @@ export const TopicCard = (props: TopicProps) => {
|
||||||
{props.topic.body}
|
{props.topic.body}
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={props.topic?.stat}>
|
|
||||||
<div class={styles.topicDetails}>
|
|
||||||
<Show when={props.showPublications}>
|
|
||||||
<span class={styles.topicDetailsItem} classList={{ compact: props.compact }}>
|
|
||||||
{props.topic.stat?.shouts +
|
|
||||||
' ' +
|
|
||||||
t('post') +
|
|
||||||
plural(
|
|
||||||
props.topic.stat?.shouts || 0,
|
|
||||||
locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</Show>
|
|
||||||
<Show when={!props.compact}>
|
|
||||||
<span class={styles.topicDetailsItem} classList={{ compact: props.compact }}>
|
|
||||||
{props.topic.stat?.authors +
|
|
||||||
' ' +
|
|
||||||
t('author') +
|
|
||||||
plural(
|
|
||||||
props.topic.stat?.authors || 0,
|
|
||||||
locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<span class={styles.topicDetailsItem} classList={{ compact: props.compact }}>
|
|
||||||
{props.topic.stat?.followers +
|
|
||||||
' ' +
|
|
||||||
t('follower') +
|
|
||||||
plural(
|
|
||||||
props.topic.stat?.followers || 0,
|
|
||||||
locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
{/*FIXME*/}
|
|
||||||
{/*<Show when={false && !props.subscribeButtonBottom}>*/}
|
|
||||||
{/* <span class='topic-details__item'>*/}
|
|
||||||
{/* {topic().stat?.viewed +*/}
|
|
||||||
{/* ' ' +*/}
|
|
||||||
{/* t('view') +*/}
|
|
||||||
{/* plural(*/}
|
|
||||||
{/* topic().stat?.viewed || 0,*/}
|
|
||||||
{/* locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']*/}
|
|
||||||
{/* )}*/}
|
|
||||||
{/* </span>*/}
|
|
||||||
{/*</Show>*/}
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class={styles.controlContainer}
|
class={styles.controlContainer}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createEffect, createMemo, createSignal, For, Show } from 'solid-js'
|
import { createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||||
import type { Author } from '../../graphql/types.gen'
|
import type { Author } from '../../graphql/types.gen'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
|
@ -11,9 +11,10 @@ import { locale } from '../../stores/ui'
|
||||||
import { translit } from '../../utils/ru2en'
|
import { translit } from '../../utils/ru2en'
|
||||||
import { SearchField } from '../_shared/SearchField'
|
import { SearchField } from '../_shared/SearchField'
|
||||||
import { scrollHandler } from '../../utils/scroll'
|
import { scrollHandler } from '../../utils/scroll'
|
||||||
|
import { StatMetrics } from '../_shared/StatMetrics'
|
||||||
|
|
||||||
type AllAuthorsPageSearchParams = {
|
type AllAuthorsPageSearchParams = {
|
||||||
by: '' | 'name' | 'shouts' | 'rating'
|
by: '' | 'name' | 'shouts' | 'followers'
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -24,23 +25,27 @@ const PAGE_SIZE = 20
|
||||||
const ALPHABET = [...'@АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ']
|
const ALPHABET = [...'@АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ']
|
||||||
|
|
||||||
export const AllAuthorsView = (props: Props) => {
|
export const AllAuthorsView = (props: Props) => {
|
||||||
const { sortedAuthors } = useAuthorsStore({ authors: props.authors })
|
|
||||||
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
||||||
|
const { searchParams, changeSearchParam } = useRouter<AllAuthorsPageSearchParams>()
|
||||||
|
const { sortedAuthors } = useAuthorsStore({
|
||||||
|
authors: props.authors,
|
||||||
|
sortBy: searchParams().by || 'shouts'
|
||||||
|
})
|
||||||
|
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
|
|
||||||
|
onMount(() => changeSearchParam('by', 'shouts'))
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
setAuthorsSort(searchParams().by || 'shouts')
|
setAuthorsSort(searchParams().by || 'shouts')
|
||||||
|
setLimit(PAGE_SIZE)
|
||||||
})
|
})
|
||||||
|
|
||||||
const subscribed = (s) => Boolean(session()?.news?.authors && session()?.news?.authors?.includes(s || ''))
|
const subscribed = (s) => Boolean(session()?.news?.authors && session()?.news?.authors?.includes(s || ''))
|
||||||
|
|
||||||
const { searchParams, changeSearchParam } = useRouter<AllAuthorsPageSearchParams>()
|
|
||||||
|
|
||||||
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
|
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
|
||||||
return sortedAuthors().reduce((acc, author) => {
|
return sortedAuthors().reduce((acc, author) => {
|
||||||
let letter = author.name.trim().split(' ').pop().at(0).toUpperCase()
|
let letter = author.name.trim().split(' ').pop().at(0).toUpperCase()
|
||||||
if (!/[А-Я]/i.test(letter) && locale() === 'ru') letter = '@'
|
if (!/[А-я]/i.test(letter) && locale() === 'ru') letter = '@'
|
||||||
if (!acc[letter]) acc[letter] = []
|
if (!acc[letter]) acc[letter] = []
|
||||||
acc[letter].push(author)
|
acc[letter].push(author)
|
||||||
return acc
|
return acc
|
||||||
|
@ -64,8 +69,8 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
<li classList={{ selected: searchParams().by === 'shouts' }}>
|
<li classList={{ selected: searchParams().by === 'shouts' }}>
|
||||||
<a href="/authors?by=shouts">{t('By shouts')}</a>
|
<a href="/authors?by=shouts">{t('By shouts')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li classList={{ selected: searchParams().by === 'rating' }}>
|
<li classList={{ selected: searchParams().by === 'followers' }}>
|
||||||
<a href="/authors?by=rating">{t('By rating')}</a>
|
<a href="/authors?by=followers">{t('By rating')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li classList={{ selected: !searchParams().by || searchParams().by === 'name' }}>
|
<li classList={{ selected: !searchParams().by || searchParams().by === 'name' }}>
|
||||||
<a href="/authors?by=name">{t('By name')}</a>
|
<a href="/authors?by=name">{t('By name')}</a>
|
||||||
|
@ -167,15 +172,18 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
<Show when={searchResults().length > 0}>
|
<Show when={searchResults().length > 0}>
|
||||||
<For each={searchResults().slice(0, limit())}>
|
<For each={searchResults().slice(0, limit())}>
|
||||||
{(author) => (
|
{(author) => (
|
||||||
<AuthorCard
|
<>
|
||||||
author={author}
|
<AuthorCard
|
||||||
compact={false}
|
author={author}
|
||||||
hasLink={true}
|
compact={false}
|
||||||
subscribed={subscribed(author.slug)}
|
hasLink={true}
|
||||||
noSocialButtons={true}
|
subscribed={subscribed(author.slug)}
|
||||||
isAuthorsList={true}
|
noSocialButtons={true}
|
||||||
truncateBio={true}
|
isAuthorsList={true}
|
||||||
/>
|
truncateBio={true}
|
||||||
|
/>
|
||||||
|
<StatMetrics fields={['shouts', 'followers', 'comments']} stat={author.stat} />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</Show>
|
</Show>
|
||||||
|
@ -185,15 +193,18 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
<div class="col-lg-10 col-xl-9">
|
<div class="col-lg-10 col-xl-9">
|
||||||
<For each={sortedAuthors().slice(0, limit())}>
|
<For each={sortedAuthors().slice(0, limit())}>
|
||||||
{(author) => (
|
{(author) => (
|
||||||
<AuthorCard
|
<>
|
||||||
author={author}
|
<AuthorCard
|
||||||
compact={false}
|
author={author}
|
||||||
hasLink={true}
|
compact={false}
|
||||||
subscribed={subscribed(author.slug)}
|
hasLink={true}
|
||||||
noSocialButtons={true}
|
subscribed={subscribed(author.slug)}
|
||||||
isAuthorsList={true}
|
noSocialButtons={true}
|
||||||
truncateBio={true}
|
isAuthorsList={true}
|
||||||
/>
|
truncateBio={true}
|
||||||
|
/>
|
||||||
|
<StatMetrics fields={['shouts', 'followers', 'comments']} stat={author.stat} />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createEffect, createMemo, createSignal, For, Show } from 'solid-js'
|
import { createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||||
import type { Topic } from '../../graphql/types.gen'
|
import type { Topic } from '../../graphql/types.gen'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics'
|
import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics'
|
||||||
|
@ -11,6 +11,7 @@ import { translit } from '../../utils/ru2en'
|
||||||
import styles from '../../styles/AllTopics.module.scss'
|
import styles from '../../styles/AllTopics.module.scss'
|
||||||
import { SearchField } from '../_shared/SearchField'
|
import { SearchField } from '../_shared/SearchField'
|
||||||
import { scrollHandler } from '../../utils/scroll'
|
import { scrollHandler } from '../../utils/scroll'
|
||||||
|
import { StatMetrics } from '../_shared/StatMetrics'
|
||||||
|
|
||||||
type AllTopicsPageSearchParams = {
|
type AllTopicsPageSearchParams = {
|
||||||
by: 'shouts' | 'authors' | 'title' | ''
|
by: 'shouts' | 'authors' | 'title' | ''
|
||||||
|
@ -34,6 +35,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
|
||||||
|
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
|
|
||||||
|
onMount(() => changeSearchParam('by', 'shouts'))
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
setTopicsSort(searchParams().by || 'shouts')
|
setTopicsSort(searchParams().by || 'shouts')
|
||||||
setLimit(PAGE_SIZE)
|
setLimit(PAGE_SIZE)
|
||||||
|
@ -182,12 +184,15 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
|
||||||
<Show when={searchParams().by && searchParams().by !== 'title'}>
|
<Show when={searchParams().by && searchParams().by !== 'title'}>
|
||||||
<For each={sortedTopics().slice(0, limit())}>
|
<For each={sortedTopics().slice(0, limit())}>
|
||||||
{(topic) => (
|
{(topic) => (
|
||||||
<TopicCard
|
<>
|
||||||
topic={topic}
|
<TopicCard
|
||||||
compact={false}
|
topic={topic}
|
||||||
subscribed={subscribed(topic.slug)}
|
compact={false}
|
||||||
showPublications={true}
|
subscribed={subscribed(topic.slug)}
|
||||||
/>
|
showPublications={true}
|
||||||
|
/>
|
||||||
|
<StatMetrics fields={['shouts', 'authors', 'followers']} stat={topic.stat} />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
34
src/components/_shared/Stat.module.scss
Normal file
34
src/components/_shared/Stat.module.scss
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
.statMetrics {
|
||||||
|
@include font-size(1.7rem);
|
||||||
|
|
||||||
|
color: #9fa1a7;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
|
||||||
|
@include media-breakpoint-down(md) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.statMetricsItem {
|
||||||
|
@include font-size(1.5rem);
|
||||||
|
|
||||||
|
margin-right: 1.6rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.compact {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.followers {
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.button {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
35
src/components/_shared/StatMetrics.tsx
Normal file
35
src/components/_shared/StatMetrics.tsx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { For } from 'solid-js'
|
||||||
|
import type { Stat, TopicStat } from '../../graphql/types.gen'
|
||||||
|
import { locale } from '../../stores/ui'
|
||||||
|
import { plural } from '../../utils'
|
||||||
|
import { t } from '../../utils/intl'
|
||||||
|
import styles from './Stat.module.scss'
|
||||||
|
|
||||||
|
interface StatMetricsProps {
|
||||||
|
fields?: string[]
|
||||||
|
stat: Stat | TopicStat
|
||||||
|
compact?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const pseudonames = {
|
||||||
|
comments: 'discussions'
|
||||||
|
}
|
||||||
|
|
||||||
|
const nos = (s) => s.slice(0, s.length - 1)
|
||||||
|
|
||||||
|
export const StatMetrics = (props: StatMetricsProps) => {
|
||||||
|
return (
|
||||||
|
<div class={styles.statMetrics}>
|
||||||
|
<For each={props.fields}>
|
||||||
|
{(entity: string) => (
|
||||||
|
<span class={styles.statMetricsItem} classList={{ compact: props.compact }}>
|
||||||
|
{props.stat[entity] +
|
||||||
|
' ' +
|
||||||
|
t(nos(pseudonames[entity] || entity)) +
|
||||||
|
plural(props.stat[entity] || 0, locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's'])}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ export default gql`
|
||||||
stat {
|
stat {
|
||||||
shouts
|
shouts
|
||||||
followers
|
followers
|
||||||
|
comments: commented
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,10 @@ export type Author = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AuthorStat = {
|
export type AuthorStat = {
|
||||||
|
rating?: Maybe<Scalars['Int']>
|
||||||
commented?: Maybe<Scalars['Int']>
|
commented?: Maybe<Scalars['Int']>
|
||||||
followers?: Maybe<Scalars['Int']>
|
followers?: Maybe<Scalars['Int']>
|
||||||
followings?: Maybe<Scalars['Int']>
|
followings?: Maybe<Scalars['Int']>
|
||||||
rating?: Maybe<Scalars['Int']>
|
|
||||||
shouts?: Maybe<Scalars['Int']>
|
shouts?: Maybe<Scalars['Int']>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,6 +615,8 @@ export type Stat = {
|
||||||
rating?: Maybe<Scalars['Int']>
|
rating?: Maybe<Scalars['Int']>
|
||||||
reacted?: Maybe<Scalars['Int']>
|
reacted?: Maybe<Scalars['Int']>
|
||||||
viewed?: Maybe<Scalars['Int']>
|
viewed?: Maybe<Scalars['Int']>
|
||||||
|
shouts?: Maybe<Scalars['Int']>
|
||||||
|
followers?: Maybe<Scalars['Int']>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Subscription = {
|
export type Subscription = {
|
||||||
|
|
|
@ -178,5 +178,7 @@
|
||||||
"topics": "темы",
|
"topics": "темы",
|
||||||
"user already exist": "пользователь уже существует",
|
"user already exist": "пользователь уже существует",
|
||||||
"view": "просмотр",
|
"view": "просмотр",
|
||||||
"zine": "журнал"
|
"zine": "журнал",
|
||||||
|
"shout": "пост",
|
||||||
|
"discussion": "дискурс"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ import { apiClient } from '../../utils/apiClient'
|
||||||
import type { Author } from '../../graphql/types.gen'
|
import type { Author } from '../../graphql/types.gen'
|
||||||
import { createSignal } from 'solid-js'
|
import { createSignal } from 'solid-js'
|
||||||
import { createLazyMemo } from '@solid-primitives/memo'
|
import { createLazyMemo } from '@solid-primitives/memo'
|
||||||
|
import { byStat } from '../../utils/sortby'
|
||||||
|
|
||||||
export type AuthorsSortBy = 'shouts' | 'name' | 'rating'
|
export type AuthorsSortBy = 'shouts' | 'name' | 'followers'
|
||||||
|
|
||||||
const [sortAllBy, setSortAllBy] = createSignal<AuthorsSortBy>('shouts')
|
const [sortAllBy, setSortAllBy] = createSignal<AuthorsSortBy>('shouts')
|
||||||
|
|
||||||
|
@ -15,21 +16,15 @@ const [authorsByTopic, setAuthorsByTopic] = createSignal<{ [topicSlug: string]:
|
||||||
const sortedAuthors = createLazyMemo(() => {
|
const sortedAuthors = createLazyMemo(() => {
|
||||||
const authors = Object.values(authorEntities())
|
const authors = Object.values(authorEntities())
|
||||||
switch (sortAllBy()) {
|
switch (sortAllBy()) {
|
||||||
// case 'created': {
|
case 'followers': {
|
||||||
// log.debug('sorted by created')
|
authors.sort(byStat('followers'))
|
||||||
// authors.sort(byCreated)
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
case 'rating': {
|
|
||||||
// TODO:
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'shouts': {
|
case 'shouts': {
|
||||||
// TODO:
|
authors.sort(byStat('shouts'))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'name': {
|
case 'name': {
|
||||||
console.debug('sorted by name')
|
|
||||||
authors.sort((a, b) => a.name.localeCompare(b.name))
|
authors.sort((a, b) => a.name.localeCompare(b.name))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -84,9 +79,13 @@ export const loadAllAuthors = async (): Promise<void> => {
|
||||||
|
|
||||||
type InitialState = {
|
type InitialState = {
|
||||||
authors?: Author[]
|
authors?: Author[]
|
||||||
|
sortBy?: AuthorsSortBy
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAuthorsStore = (initialState: InitialState = {}) => {
|
export const useAuthorsStore = (initialState: InitialState = {}) => {
|
||||||
|
if (initialState.sortBy) {
|
||||||
|
setSortAllBy(initialState.sortBy)
|
||||||
|
}
|
||||||
addAuthors([...(initialState.authors || [])])
|
addAuthors([...(initialState.authors || [])])
|
||||||
|
|
||||||
return { authorEntities, sortedAuthors, authorsByTopic }
|
return { authorEntities, sortedAuthors, authorsByTopic }
|
||||||
|
|
|
@ -260,9 +260,7 @@ export const apiClient = {
|
||||||
},
|
},
|
||||||
getReactionsBy: async ({ by, limit = REACTIONS_AMOUNT_PER_PAGE, offset = 0 }) => {
|
getReactionsBy: async ({ by, limit = REACTIONS_AMOUNT_PER_PAGE, offset = 0 }) => {
|
||||||
const resp = await publicGraphQLClient.query(reactionsLoadBy, { by, limit, offset }).toPromise()
|
const resp = await publicGraphQLClient.query(reactionsLoadBy, { by, limit, offset }).toPromise()
|
||||||
|
resp.error ?? console.error(resp.error)
|
||||||
console.log('resactions response', resp)
|
|
||||||
|
|
||||||
return resp.data.loadReactionsBy
|
return resp.data.loadReactionsBy
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ export const byLength = (
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO more typing
|
|
||||||
export const byStat = (metric: keyof Stat) => {
|
export const byStat = (metric: keyof Stat) => {
|
||||||
return (a, b) => {
|
return (a, b) => {
|
||||||
const x = (a?.stat && a.stat[metric]) || 0
|
const x = (a?.stat && a.stat[metric]) || 0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user