topics and authors grouped by letter
This commit is contained in:
parent
e63b018efa
commit
71cec8a6c2
|
@ -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 type { Author } from '../../graphql/types.gen'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { byFirstChar, sortBy } from '../../utils/sortby'
|
|
||||||
import { groupByName } from '../../utils/groupby'
|
|
||||||
import { Icon } from '../Nav/Icon'
|
import { Icon } from '../Nav/Icon'
|
||||||
import { t } from '../../utils/intl'
|
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 { handleClientRouteLinkClick, useRouter } from '../../stores/router'
|
||||||
import { useAuthStore } from '../../stores/auth'
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import { getLogger } from '../../utils/logger'
|
import { getLogger } from '../../utils/logger'
|
||||||
import '../../styles/AllTopics.scss'
|
import '../../styles/AllTopics.scss'
|
||||||
|
import { Topic } from '../../graphql/types.gen'
|
||||||
|
|
||||||
const log = getLogger('AllAuthorsView')
|
const log = getLogger('AllAuthorsView')
|
||||||
|
|
||||||
|
@ -23,31 +22,37 @@ type Props = {
|
||||||
|
|
||||||
export const AllAuthorsView = (props: Props) => {
|
export const AllAuthorsView = (props: Props) => {
|
||||||
const { sortedAuthors } = useAuthorsStore({ authors: props.authors })
|
const { sortedAuthors } = useAuthorsStore({ authors: props.authors })
|
||||||
const [sortedKeys, setSortedKeys] = createSignal<string[]>([])
|
|
||||||
const [abc, setAbc] = createSignal([])
|
|
||||||
|
|
||||||
const { session } = useAuthStore()
|
const { session } = useAuthStore()
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
setSortAllAuthorsBy(getSearchParams().by || 'shouts')
|
||||||
|
})
|
||||||
|
|
||||||
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 { getSearchParams } = useRouter<AllAuthorsPageSearchParams>()
|
const { getSearchParams } = useRouter<AllAuthorsPageSearchParams>()
|
||||||
|
|
||||||
createEffect(() => {
|
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
|
||||||
if ((!getSearchParams().by || getSearchParams().by === 'name') && abc().length === 0) {
|
return sortedAuthors().reduce((acc, author) => {
|
||||||
console.log('[authors] default grouping by abc')
|
const letter = author.name[0]
|
||||||
const grouped = { ...groupByName(sortedAuthors()) }
|
if (!acc[letter]) {
|
||||||
grouped['A-Z'] = sortBy(grouped['A-Z'], byFirstChar)
|
acc[letter] = []
|
||||||
setAbc(grouped)
|
}
|
||||||
const keys = Object.keys(abc)
|
|
||||||
keys.sort()
|
acc[letter].push(author)
|
||||||
setSortedKeys(keys)
|
|
||||||
} else {
|
return acc
|
||||||
console.log('[authors] sorting by ' + getSearchParams().by)
|
}, {} as { [letter: string]: Author[] })
|
||||||
///setSortedAuthors(sortBy(authorList(), getSearchParams().by))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
log.debug(getSearchParams())
|
const sortedKeys = createMemo<string[]>(() => {
|
||||||
|
const keys = Object.keys(byLetter())
|
||||||
|
keys.sort()
|
||||||
|
return keys
|
||||||
|
})
|
||||||
|
|
||||||
|
// log.debug(getSearchParams())
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="all-topics-page">
|
<div class="all-topics-page">
|
||||||
|
@ -108,7 +113,7 @@ export const AllAuthorsView = (props: Props) => {
|
||||||
<h2>{letter}</h2>
|
<h2>{letter}</h2>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<For each={abc()[letter]}>
|
<For each={byLetter()[letter]}>
|
||||||
{(author: Author) => (
|
{(author: Author) => (
|
||||||
<div class="topic col-sm-6 col-md-3">
|
<div class="topic col-sm-6 col-md-3">
|
||||||
<div class="topic-title">
|
<div class="topic-title">
|
||||||
|
|
|
@ -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 type { Topic } from '../../graphql/types.gen'
|
||||||
import { Icon } from '../Nav/Icon'
|
import { Icon } from '../Nav/Icon'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
|
@ -33,6 +33,25 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
|
||||||
setSortAllTopicsBy(getSearchParams().by || 'shouts')
|
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 || ''))
|
const subscribed = (s) => Boolean(session()?.news?.topics && session()?.news?.topics?.includes(s || ''))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -80,48 +99,39 @@ export const AllTopicsView = (props: AllTopicsViewProps) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="stats">
|
<Show
|
||||||
<For each={sortedTopics()}>
|
when={getSearchParams().by === 'title'}
|
||||||
{(topic) => (
|
fallback={() => (
|
||||||
<TopicCard topic={topic} compact={false} subscribed={subscribed(topic.slug)} />
|
<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>
|
</For>
|
||||||
</div>
|
</Show>
|
||||||
|
|
||||||
{/*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>*/}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import type { Author } from '../../graphql/types.gen'
|
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 { getLogger } from '../../utils/logger'
|
||||||
import { createSignal } from 'solid-js'
|
import { createSignal } from 'solid-js'
|
||||||
|
@ -8,9 +8,11 @@ import { createLazyMemo } from '@solid-primitives/memo'
|
||||||
|
|
||||||
const log = getLogger('authors store')
|
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 [authorEntities, setAuthorEntities] = createSignal<{ [authorSlug: string]: Author }>({})
|
||||||
const [authorsByTopic, setAuthorsByTopic] = createSignal<{ [topicSlug: string]: Author[] }>({})
|
const [authorsByTopic, setAuthorsByTopic] = createSignal<{ [topicSlug: string]: Author[] }>({})
|
||||||
|
@ -18,16 +20,21 @@ 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 'created': {
|
||||||
log.debug('sorted by created')
|
// log.debug('sorted by created')
|
||||||
authors.sort(byCreated)
|
// authors.sort(byCreated)
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
case 'rating':
|
||||||
|
// TODO:
|
||||||
break
|
break
|
||||||
}
|
case 'shouts':
|
||||||
case 'name': {
|
// TODO:
|
||||||
|
break
|
||||||
|
case 'name':
|
||||||
log.debug('sorted by name')
|
log.debug('sorted by name')
|
||||||
authors.sort((a, b) => a.name.localeCompare(b.name))
|
authors.sort((a, b) => a.name.localeCompare(b.name))
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return authors
|
return authors
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user