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
|
|
|
}
|