topics and authors grouped by letter

This commit is contained in:
Igor Lobanov 2022-10-05 17:56:59 +02:00
parent e63b018efa
commit 71cec8a6c2
3 changed files with 93 additions and 71 deletions

View File

@ -1,15 +1,14 @@
import { createEffect, createSignal, For, Show } from 'solid-js'
import { createEffect, createMemo, createSignal, For, Show } from 'solid-js'
import type { Author } from '../../graphql/types.gen'
import { AuthorCard } from '../Author/Card'
import { byFirstChar, sortBy } from '../../utils/sortby'
import { groupByName } from '../../utils/groupby'
import { Icon } from '../Nav/Icon'
import { t } from '../../utils/intl'
import { useAuthorsStore } from '../../stores/zine/authors'
import { useAuthorsStore, setSortAllBy as setSortAllAuthorsBy } from '../../stores/zine/authors'
import { handleClientRouteLinkClick, useRouter } from '../../stores/router'
import { useAuthStore } from '../../stores/auth'
import { getLogger } from '../../utils/logger'
import '../../styles/AllTopics.scss'
import { Topic } from '../../graphql/types.gen'
const log = getLogger('AllAuthorsView')
@ -23,31 +22,37 @@ type Props = {
export const AllAuthorsView = (props: Props) => {
const { sortedAuthors } = useAuthorsStore({ authors: props.authors })
const [sortedKeys, setSortedKeys] = createSignal<string[]>([])
const [abc, setAbc] = createSignal([])
const { session } = useAuthStore()
createEffect(() => {
setSortAllAuthorsBy(getSearchParams().by || 'shouts')
})
const subscribed = (s) => Boolean(session()?.news?.authors && session()?.news?.authors?.includes(s || ''))
const { getSearchParams } = useRouter<AllAuthorsPageSearchParams>()
createEffect(() => {
if ((!getSearchParams().by || getSearchParams().by === 'name') && abc().length === 0) {
console.log('[authors] default grouping by abc')
const grouped = { ...groupByName(sortedAuthors()) }
grouped['A-Z'] = sortBy(grouped['A-Z'], byFirstChar)
setAbc(grouped)
const keys = Object.keys(abc)
keys.sort()
setSortedKeys(keys)
} else {
console.log('[authors] sorting by ' + getSearchParams().by)
///setSortedAuthors(sortBy(authorList(), getSearchParams().by))
}
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
return sortedAuthors().reduce((acc, author) => {
const letter = author.name[0]
if (!acc[letter]) {
acc[letter] = []
}
acc[letter].push(author)
return acc
}, {} as { [letter: string]: Author[] })
})
log.debug(getSearchParams())
const sortedKeys = createMemo<string[]>(() => {
const keys = Object.keys(byLetter())
keys.sort()
return keys
})
// log.debug(getSearchParams())
return (
<div class="all-topics-page">
@ -108,7 +113,7 @@ export const AllAuthorsView = (props: Props) => {
<h2>{letter}</h2>
<div class="container">
<div class="row">
<For each={abc()[letter]}>
<For each={byLetter()[letter]}>
{(author: Author) => (
<div class="topic col-sm-6 col-md-3">
<div class="topic-title">

View File

@ -1,4 +1,4 @@
import { createEffect, For, Show } from 'solid-js'
import { createEffect, createMemo, For, Show } from 'solid-js'
import type { Topic } from '../../graphql/types.gen'
import { Icon } from '../Nav/Icon'
import { t } from '../../utils/intl'
@ -33,6 +33,25 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
setSortAllTopicsBy(getSearchParams().by || 'shouts')
})
const byLetter = createMemo<{ [letter: string]: Topic[] }>(() => {
return sortedTopics().reduce((acc, topic) => {
const letter = topic.title[0]
if (!acc[letter]) {
acc[letter] = []
}
acc[letter].push(topic)
return acc
}, {} as { [letter: string]: Topic[] })
})
const sortedKeys = createMemo<string[]>(() => {
const keys = Object.keys(byLetter())
keys.sort()
return keys
})
const subscribed = (s) => Boolean(session()?.news?.topics && session()?.news?.topics?.includes(s || ''))
return (
@ -80,48 +99,39 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
</li>
</ul>
<div class="stats">
<For each={sortedTopics()}>
{(topic) => (
<TopicCard topic={topic} compact={false} subscribed={subscribed(topic.slug)} />
<Show
when={getSearchParams().by === 'title'}
fallback={() => (
<div class="stats">
<For each={sortedTopics()}>
{(topic) => (
<TopicCard topic={topic} compact={false} subscribed={subscribed(topic.slug)} />
)}
</For>
</div>
)}
>
<For each={sortedKeys()}>
{(letter) => (
<div class="group">
<h2>{letter}</h2>
<div class="container">
<div class="row">
<For each={byLetter()[letter]}>
{(topic) => (
<div class="topic col-sm-6 col-md-3">
<div class="topic-title">
<a href={`/topic/${topic.slug}`}>{topic.title}</a>
</div>
</div>
)}
</For>
</div>
</div>
</div>
)}
</For>
</div>
{/*FIXME*/}
{/*<Show*/}
{/* when={params()['by'] === 'abc'}*/}
{/* fallback={() => (*/}
{/* <div class="stats">*/}
{/* <For each={getSortedTopics()}>*/}
{/* {(topic: Topic) => (*/}
{/* <TopicCard topic={topic} compact={false} subscribed={subscribed(topic.slug)} />*/}
{/* )}*/}
{/* </For>*/}
{/* </div>*/}
{/* )}*/}
{/*>*/}
{/* <For each={sortedKeys() || []}>*/}
{/* {(letter: string) => (*/}
{/* <div class="group">*/}
{/* <h2>{letter}</h2>*/}
{/* <div class="container">*/}
{/* <div class="row">*/}
{/* <For each={abc()[letter]}>*/}
{/* {(topic: Partial<Topic>) => (*/}
{/* <div class="topic col-sm-6 col-md-3">*/}
{/* <div class="topic-title">*/}
{/* <a href={`/topic/${topic.slug}`}>{topic.title}</a>*/}
{/* </div>*/}
{/* </div>*/}
{/* )}*/}
{/* </For>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* )}*/}
{/* </For>*/}
{/*</Show>*/}
</Show>
</div>
</div>
</div>

View File

@ -1,6 +1,6 @@
import { apiClient } from '../../utils/apiClient'
import type { Author } from '../../graphql/types.gen'
import { byCreated } from '../../utils/sortby'
import { byCreated, byStat, byTopicStatDesc } from '../../utils/sortby'
import { getLogger } from '../../utils/logger'
import { createSignal } from 'solid-js'
@ -8,9 +8,11 @@ import { createLazyMemo } from '@solid-primitives/memo'
const log = getLogger('authors store')
export type AuthorsSortBy = 'created' | 'name'
export type AuthorsSortBy = 'shouts' | 'name' | 'rating'
const [sortAllBy, setSortAllBy] = createSignal<AuthorsSortBy>('created')
const [sortAllBy, setSortAllBy] = createSignal<AuthorsSortBy>('shouts')
export { setSortAllBy }
const [authorEntities, setAuthorEntities] = createSignal<{ [authorSlug: string]: Author }>({})
const [authorsByTopic, setAuthorsByTopic] = createSignal<{ [topicSlug: string]: Author[] }>({})
@ -18,16 +20,21 @@ const [authorsByTopic, setAuthorsByTopic] = createSignal<{ [topicSlug: string]:
const sortedAuthors = createLazyMemo(() => {
const authors = Object.values(authorEntities())
switch (sortAllBy()) {
case 'created': {
log.debug('sorted by created')
authors.sort(byCreated)
// case 'created': {
// log.debug('sorted by created')
// authors.sort(byCreated)
// break
// }
case 'rating':
// TODO:
break
}
case 'name': {
case 'shouts':
// TODO:
break
case 'name':
log.debug('sorted by name')
authors.sort((a, b) => a.name.localeCompare(b.name))
break
}
}
return authors
})