webapp/src/stores/zine/authors.ts

109 lines
3.0 KiB
TypeScript
Raw Normal View History

2022-09-09 11:53:35 +00:00
import { apiClient } from '../../utils/apiClient'
import type { ReadableAtom, WritableAtom } from 'nanostores'
import { atom, computed } from 'nanostores'
import type { Author } from '../../graphql/types.gen'
import { useStore } from '@nanostores/solid'
2022-09-22 09:37:49 +00:00
import { byCreated } from '../../utils/sortby'
import { getLogger } from '../../utils/logger'
const log = getLogger('authors store')
2022-09-09 11:53:35 +00:00
export type AuthorsSortBy = 'created' | 'name'
2022-09-13 13:38:26 +00:00
const sortAllByStore = atom<AuthorsSortBy>('created')
2022-09-09 11:53:35 +00:00
2022-09-13 09:59:04 +00:00
let authorEntitiesStore: WritableAtom<{ [authorSlug: string]: Author }>
let authorsByTopicStore: WritableAtom<{ [topicSlug: string]: Author[] }>
2022-09-09 11:53:35 +00:00
let sortedAuthorsStore: ReadableAtom<Author[]>
2022-09-13 09:59:04 +00:00
const initStore = (initial: { [authorSlug: string]: Author }) => {
2022-09-09 11:53:35 +00:00
if (authorEntitiesStore) {
return
}
2022-09-13 09:59:04 +00:00
authorEntitiesStore = atom(initial)
2022-09-09 11:53:35 +00:00
2022-09-13 13:38:26 +00:00
sortedAuthorsStore = computed([authorEntitiesStore, sortAllByStore], (authorEntities, sortBy) => {
2022-09-09 11:53:35 +00:00
const authors = Object.values(authorEntities)
switch (sortBy) {
case 'created': {
2022-09-22 09:37:49 +00:00
// log.debug('sorted by created')
2022-09-09 11:53:35 +00:00
authors.sort(byCreated)
break
}
case 'name': {
2022-09-22 09:37:49 +00:00
// log.debug('sorted by name')
2022-09-13 09:59:04 +00:00
authors.sort((a, b) => a.name.localeCompare(b.name))
2022-09-09 11:53:35 +00:00
break
}
}
return authors
})
}
2022-09-13 13:38:26 +00:00
export const setSortAllBy = (sortBy: AuthorsSortBy) => {
sortAllByStore.set(sortBy)
}
2022-09-09 11:53:35 +00:00
const addAuthors = (authors: Author[]) => {
const newAuthorEntities = authors.reduce((acc, author) => {
acc[author.slug] = author
return acc
}, {} as Record<string, Author>)
if (!authorEntitiesStore) {
initStore(newAuthorEntities)
} else {
authorEntitiesStore.set({
...authorEntitiesStore.get(),
...newAuthorEntities
})
}
}
2022-09-13 09:59:04 +00:00
export const addAuthorsByTopic = (authorsByTopic: { [topicSlug: string]: Author[] }) => {
const allAuthors = Object.values(authorsByTopic).flat()
addAuthors(allAuthors)
if (!authorsByTopicStore) {
authorsByTopicStore = atom<{ [topicSlug: string]: Author[] }>(authorsByTopic)
} else {
const newState = Object.entries(authorsByTopic).reduce((acc, [topicSlug, authors]) => {
if (!acc[topicSlug]) {
acc[topicSlug] = []
}
authors.forEach((author) => {
if (!acc[topicSlug].some((a) => a.slug === author.slug)) {
acc[topicSlug].push(author)
}
})
return acc
}, authorsByTopicStore.get())
authorsByTopicStore.set(newState)
}
}
2022-09-09 11:53:35 +00:00
export const loadAllAuthors = async (): Promise<void> => {
const authors = await apiClient.getAllAuthors()
addAuthors(authors)
}
2022-09-13 09:59:04 +00:00
type InitialState = {
authors?: Author[]
}
2022-09-23 07:38:48 +00:00
export const useAuthorsStore = (initialState: InitialState = {}) => {
const authors = [...(initialState.authors || [])]
addAuthors(authors)
2022-09-09 11:53:35 +00:00
const getAuthorEntities = useStore(authorEntitiesStore)
const getSortedAuthors = useStore(sortedAuthorsStore)
2022-09-13 08:05:11 +00:00
const getAuthorsByTopic = useStore(authorsByTopicStore)
2022-09-13 09:59:04 +00:00
2022-09-22 09:37:49 +00:00
return { getAuthorEntities, getSortedAuthors, getAuthorsByTopic }
2022-09-09 11:53:35 +00:00
}