webapp/src/stores/zine/topics.ts

113 lines
3.0 KiB
TypeScript
Raw Normal View History

2022-09-28 20:16:44 +00:00
import { createMemo, createSignal } from 'solid-js'
2022-09-09 11:53:35 +00:00
import { apiClient } from '../../utils/apiClient'
import type { Topic } from '../../graphql/types.gen'
2022-09-22 09:37:49 +00:00
import { byCreated, byTopicStatDesc } from '../../utils/sortby'
import { getLogger } from '../../utils/logger'
2022-09-29 17:37:21 +00:00
import { createLazyMemo } from '@solid-primitives/memo'
2022-09-09 11:53:35 +00:00
2022-09-22 09:37:49 +00:00
const log = getLogger('topics store')
2022-09-09 11:53:35 +00:00
2022-09-22 09:37:49 +00:00
export type TopicsSortBy = 'created' | 'title' | 'authors' | 'shouts'
2022-09-28 20:16:44 +00:00
const [sortAllBy, setSortAllBy] = createSignal<TopicsSortBy>('shouts')
2022-09-09 11:53:35 +00:00
2022-09-28 20:16:44 +00:00
export { setSortAllBy }
2022-09-22 09:37:49 +00:00
2022-09-28 20:16:44 +00:00
const [topicEntities, setTopicEntities] = createSignal<{ [topicSlug: string]: Topic }>({})
const [randomTopics, setRandomTopics] = createSignal<Topic[]>([])
const [topicsByAuthor, setTopicByAuthor] = createSignal<{ [authorSlug: string]: Topic[] }>({})
2022-09-09 11:53:35 +00:00
2022-09-29 17:37:21 +00:00
const sortedTopics = createLazyMemo<Topic[]>(() => {
const topics = Object.values(topicEntities())
2022-09-28 20:16:44 +00:00
const sortAllByValue = sortAllBy()
2022-09-09 11:53:35 +00:00
2022-09-28 20:16:44 +00:00
switch (sortAllByValue) {
case 'created': {
// log.debug('sorted by created')
topics.sort(byCreated)
break
2022-09-09 11:53:35 +00:00
}
2022-09-28 20:16:44 +00:00
case 'shouts':
case 'authors':
// log.debug(`sorted by ${sortBy}`)
topics.sort(byTopicStatDesc(sortAllByValue))
break
case 'title':
// log.debug('sorted by title')
topics.sort((a, b) => a.title.localeCompare(b.title))
break
default:
log.error(`Unknown sort: ${sortAllByValue}`)
2022-09-22 09:37:49 +00:00
}
2022-09-29 17:37:21 +00:00
2022-09-28 20:16:44 +00:00
return topics
})
const topTopics = createMemo(() => {
const topics = Object.values(topicEntities())
topics.sort(byTopicStatDesc('shouts'))
return topics
})
2022-09-13 13:38:26 +00:00
2022-09-13 09:59:04 +00:00
const addTopics = (...args: Topic[][]) => {
const allTopics = args.flatMap((topics) => topics || [])
const newTopicEntities = allTopics.reduce((acc, topic) => {
2022-09-09 11:53:35 +00:00
acc[topic.slug] = topic
return acc
}, {} as Record<string, Topic>)
2022-09-28 20:16:44 +00:00
setTopicEntities((prevTopicEntities) => {
return {
...prevTopicEntities,
2022-09-09 11:53:35 +00:00
...newTopicEntities
2022-09-28 20:16:44 +00:00
}
})
2022-09-09 11:53:35 +00:00
}
2022-09-28 20:16:44 +00:00
export const addTopicsByAuthor = (newTopicsByAuthors: { [authorSlug: string]: Topic[] }) => {
const allTopics = Object.values(newTopicsByAuthors).flat()
2022-09-13 09:59:04 +00:00
addTopics(allTopics)
2022-09-28 20:16:44 +00:00
setTopicByAuthor((prevTopicsByAuthor) => {
return Object.entries(newTopicsByAuthors).reduce((acc, [authorSlug, topics]) => {
2022-09-13 09:59:04 +00:00
if (!acc[authorSlug]) {
acc[authorSlug] = []
}
topics.forEach((topic) => {
if (!acc[authorSlug].some((t) => t.slug === topic.slug)) {
acc[authorSlug].push(topic)
}
})
return acc
2022-09-28 20:16:44 +00:00
}, prevTopicsByAuthor)
})
2022-09-13 09:59:04 +00:00
}
2022-09-09 11:53:35 +00:00
export const loadAllTopics = async (): Promise<void> => {
const topics = await apiClient.getAllTopics()
addTopics(topics)
}
type InitialState = {
topics?: Topic[]
randomTopics?: Topic[]
2022-09-22 09:37:49 +00:00
sortBy?: TopicsSortBy
2022-09-09 11:53:35 +00:00
}
2022-09-23 07:38:48 +00:00
export const useTopicsStore = (initialState: InitialState = {}) => {
if (initialState.sortBy) {
2022-09-28 20:16:44 +00:00
setSortAllBy(initialState.sortBy)
2022-09-16 07:45:56 +00:00
}
2022-09-22 09:37:49 +00:00
2022-09-28 20:16:44 +00:00
addTopics(initialState.topics, initialState.randomTopics)
2022-09-22 09:37:49 +00:00
2022-09-28 20:16:44 +00:00
if (initialState.randomTopics) {
setRandomTopics(initialState.randomTopics)
2022-09-13 09:59:04 +00:00
}
2022-09-09 11:53:35 +00:00
2022-09-28 20:16:44 +00:00
return { topicEntities, sortedTopics, randomTopics, topTopics, topicsByAuthor }
2022-09-09 11:53:35 +00:00
}