wip-refactoring
This commit is contained in:
parent
f0f944e31a
commit
0c0084365d
|
@ -1,9 +1,9 @@
|
||||||
import { PageWrap } from '../_shared/PageWrap'
|
import { PageWrap } from '../_shared/PageWrap'
|
||||||
import type { PageProps } from '../types'
|
import type { PageProps } from '../types'
|
||||||
import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js'
|
import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js'
|
||||||
import { resetSortedArticles } from '../../stores/zine/articles'
|
import { loadShoutsBy, resetSortedArticles } from '../../stores/zine/articles'
|
||||||
import { useRouter } from '../../stores/router'
|
import { useRouter } from '../../stores/router'
|
||||||
import { LayoutType, loadRecentLayoutShouts, useLayoutsStore } from '../../stores/zine/layouts'
|
import { LayoutType, useLayoutsStore } from '../../stores/zine/layouts'
|
||||||
import { Loading } from '../Loading'
|
import { Loading } from '../Loading'
|
||||||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||||
import type { Shout } from '../../graphql/types.gen'
|
import type { Shout } from '../../graphql/types.gen'
|
||||||
|
@ -28,14 +28,13 @@ export const LayoutShoutsPage = (props: PageProps) => {
|
||||||
return page.params.layout as LayoutType
|
return page.params.layout as LayoutType
|
||||||
})
|
})
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
const { sortedLayoutShouts } = useLayoutsStore(layout(), props.shouts)
|
const { sortedLayoutShouts, loadLayoutShoutsBy } = useLayoutsStore(layout(), props.shouts)
|
||||||
const sortedArticles = createMemo<Shout[]>(() => sortedLayoutShouts().get(layout()) || [])
|
const sortedArticles = createMemo<Shout[]>(() => sortedLayoutShouts().get(layout()) || [])
|
||||||
const loadMoreLayout = async (kind: LayoutType) => {
|
const loadMoreLayout = async (kind: LayoutType) => {
|
||||||
saveScrollPosition()
|
saveScrollPosition()
|
||||||
|
const { hasMore } = await loadLayoutShoutsBy({
|
||||||
const { hasMore } = await loadRecentLayoutShouts({
|
by: { layout: kind },
|
||||||
layout: kind,
|
limit: LOAD_MORE_PAGE_SIZE,
|
||||||
amount: LOAD_MORE_PAGE_SIZE,
|
|
||||||
offset: sortedArticles().length
|
offset: sortedArticles().length
|
||||||
})
|
})
|
||||||
setIsLoadMoreButtonVisible(hasMore)
|
setIsLoadMoreButtonVisible(hasMore)
|
||||||
|
@ -63,7 +62,7 @@ export const LayoutShoutsPage = (props: PageProps) => {
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
await loadRecentLayoutShouts({ layout: layout(), amount: PRERENDERED_ARTICLES_COUNT, offset: 0 })
|
await loadShoutsBy({ by: { layout: layout() }, limit: PRERENDERED_ARTICLES_COUNT, offset: 0 })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import { createEffect, createSignal, Show, Suspense } from 'solid-js'
|
import { createEffect, createSignal, Show, Suspense } from 'solid-js'
|
||||||
import { FullArticle } from '../Article/FullArticle'
|
import { FullArticle } from '../Article/FullArticle'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import type { Shout } from '../../graphql/types.gen'
|
import type { Shout, Reaction } from '../../graphql/types.gen'
|
||||||
import { loadArticleReactions, useReactionsStore } from '../../stores/zine/reactions'
|
import { useReactionsStore } from '../../stores/zine/reactions'
|
||||||
|
|
||||||
import '../../styles/Article.scss'
|
import '../../styles/Article.scss'
|
||||||
|
|
||||||
interface ArticlePageProps {
|
interface ArticlePageProps {
|
||||||
article: Shout
|
article: Shout
|
||||||
|
reactions?: Reaction[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
||||||
|
@ -15,13 +16,20 @@ const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
||||||
export const ArticleView = (props: ArticlePageProps) => {
|
export const ArticleView = (props: ArticlePageProps) => {
|
||||||
const [getCommentsPage] = createSignal(1)
|
const [getCommentsPage] = createSignal(1)
|
||||||
const [getIsCommentsLoading, setIsCommentsLoading] = createSignal(false)
|
const [getIsCommentsLoading, setIsCommentsLoading] = createSignal(false)
|
||||||
const reactionslist = useReactionsStore()
|
const {
|
||||||
|
reactionsByShout,
|
||||||
|
sortedReactions,
|
||||||
|
createReaction,
|
||||||
|
updateReaction,
|
||||||
|
deleteReaction,
|
||||||
|
loadReactionsBy
|
||||||
|
} = useReactionsStore({ reactions: props.reactions })
|
||||||
|
|
||||||
createEffect(async () => {
|
createEffect(async () => {
|
||||||
try {
|
try {
|
||||||
setIsCommentsLoading(true)
|
setIsCommentsLoading(true)
|
||||||
await loadArticleReactions({
|
await loadReactionsBy({
|
||||||
articleSlug: props.article.slug,
|
by: { shout: props.article.slug },
|
||||||
limit: ARTICLE_COMMENTS_PAGE_SIZE,
|
limit: ARTICLE_COMMENTS_PAGE_SIZE,
|
||||||
offset: getCommentsPage() * ARTICLE_COMMENTS_PAGE_SIZE
|
offset: getCommentsPage() * ARTICLE_COMMENTS_PAGE_SIZE
|
||||||
})
|
})
|
||||||
|
@ -36,7 +44,7 @@ export const ArticleView = (props: ArticlePageProps) => {
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<FullArticle
|
<FullArticle
|
||||||
article={props.article}
|
article={props.article}
|
||||||
reactions={reactionslist().filter((r) => r.shout.slug === props.article.slug)}
|
reactions={reactionsByShout()[props.article.slug]}
|
||||||
isCommentsLoading={getIsCommentsLoading()}
|
isCommentsLoading={getIsCommentsLoading()}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
@ -1,56 +1,41 @@
|
||||||
import { createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
import { createEffect, createSignal, For, onMount, Show } from 'solid-js'
|
||||||
import '../../styles/Feed.scss'
|
import '../../styles/Feed.scss'
|
||||||
import stylesBeside from '../../components/Feed/Beside.module.scss'
|
import stylesBeside from '../../components/Feed/Beside.module.scss'
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
import { byCreated, sortBy } from '../../utils/sortby'
|
|
||||||
import { TopicCard } from '../Topic/Card'
|
import { TopicCard } from '../Topic/Card'
|
||||||
import { ArticleCard } from '../Feed/Card'
|
import { ArticleCard } from '../Feed/Card'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { FeedSidebar } from '../Feed/Sidebar'
|
import { FeedSidebar } from '../Feed/Sidebar'
|
||||||
import CommentCard from '../Article/Comment'
|
import CommentCard from '../Article/Comment'
|
||||||
import { loadShoutsBy, useArticlesStore } from '../../stores/zine/articles'
|
import { useArticlesStore } from '../../stores/zine/articles'
|
||||||
import { useReactionsStore } from '../../stores/zine/reactions'
|
import { useReactionsStore } from '../../stores/zine/reactions'
|
||||||
import { useAuthorsStore } from '../../stores/zine/authors'
|
import { useAuthorsStore } from '../../stores/zine/authors'
|
||||||
import { useTopicsStore } from '../../stores/zine/topics'
|
import { useTopicsStore } from '../../stores/zine/topics'
|
||||||
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
||||||
import { useSession } from '../../context/session'
|
import { useSession } from '../../context/session'
|
||||||
|
import { Collab, ReactionKind, Shout } from '../../graphql/types.gen'
|
||||||
|
import { collabs, setCollabs } from '../../stores/editor'
|
||||||
|
|
||||||
// const AUTHORSHIP_REACTIONS = [
|
const AUTHORSHIP_REACTIONS = [
|
||||||
// ReactionKind.Accept,
|
ReactionKind.Accept,
|
||||||
// ReactionKind.Reject,
|
ReactionKind.Reject,
|
||||||
// ReactionKind.Propose,
|
ReactionKind.Propose,
|
||||||
// ReactionKind.Ask
|
ReactionKind.Ask
|
||||||
// ]
|
]
|
||||||
|
|
||||||
export const FEED_PAGE_SIZE = 20
|
export const FEED_PAGE_SIZE = 20
|
||||||
|
|
||||||
export const FeedView = () => {
|
export const FeedView = () => {
|
||||||
// state
|
// state
|
||||||
const { sortedArticles } = useArticlesStore()
|
const { sortedArticles, loadShoutsBy } = useArticlesStore()
|
||||||
const reactions = useReactionsStore()
|
const { sortedReactions: topComments, loadReactionsBy } = useReactionsStore({})
|
||||||
const { sortedAuthors } = useAuthorsStore()
|
const { sortedAuthors } = useAuthorsStore()
|
||||||
const { topTopics } = useTopicsStore()
|
const { topTopics } = useTopicsStore()
|
||||||
const { topAuthors } = useTopAuthorsStore()
|
const { topAuthors } = useTopAuthorsStore()
|
||||||
const { session } = useSession()
|
const { session } = useSession()
|
||||||
|
|
||||||
const topReactions = createMemo(() => sortBy(reactions(), byCreated))
|
|
||||||
|
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
|
|
||||||
// const expectingFocus = createMemo<Shout[]>(() => {
|
|
||||||
// // 1 co-author notifications needs
|
|
||||||
// // TODO: list of articles where you are co-author
|
|
||||||
// // TODO: preload proposals
|
|
||||||
// // TODO: (maybe?) and changes history
|
|
||||||
// console.debug(reactions().filter((r) => r.kind in AUTHORSHIP_REACTIONS))
|
|
||||||
//
|
|
||||||
// // 2 community self-regulating mechanics
|
|
||||||
// // TODO: query all new posts to be rated for publishing
|
|
||||||
// // TODO: query all reactions where user is in authors list
|
|
||||||
// return []
|
|
||||||
// })
|
|
||||||
|
|
||||||
const loadMore = async () => {
|
const loadMore = async () => {
|
||||||
const { hasMore } = await loadShoutsBy({
|
const { hasMore } = await loadShoutsBy({
|
||||||
by: { visibility: 'community' },
|
by: { visibility: 'community' },
|
||||||
|
@ -60,8 +45,27 @@ export const FeedView = () => {
|
||||||
setIsLoadMoreButtonVisible(hasMore)
|
setIsLoadMoreButtonVisible(hasMore)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(async () => {
|
||||||
loadMore()
|
// load 5 recent comments overall
|
||||||
|
await loadReactionsBy({ by: {}, limit: 5, offset: 0 })
|
||||||
|
|
||||||
|
// load recent shouts not only published ( visibility = community )
|
||||||
|
await loadMore()
|
||||||
|
|
||||||
|
// TODO: load collabs
|
||||||
|
// await loadCollabs()
|
||||||
|
|
||||||
|
// load recent editing shouts ( visibility = authors )
|
||||||
|
const userslug = session().user.slug
|
||||||
|
await loadShoutsBy({ by: { author: userslug, visibility: 'authors' }, limit: 15, offset: 0 })
|
||||||
|
const collaborativeShouts = sortedArticles().filter((s: Shout, n: number, arr: Shout[]) => {
|
||||||
|
if (s.visibility !== 'authors') {
|
||||||
|
arr.splice(n, 1)
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// load recent reactions on collabs
|
||||||
|
await loadReactionsBy({ by: { shouts: [...collaborativeShouts], body: true }, limit: 5, offset: 0 })
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -122,7 +126,7 @@ export const FeedView = () => {
|
||||||
<aside class="col-md-3">
|
<aside class="col-md-3">
|
||||||
<section class="feed-comments">
|
<section class="feed-comments">
|
||||||
<h4>{t('Comments')}</h4>
|
<h4>{t('Comments')}</h4>
|
||||||
<For each={topReactions()}>
|
<For each={topComments()}>
|
||||||
{(comment) => <CommentCard comment={comment} compact={true} />}
|
{(comment) => <CommentCard comment={comment} compact={true} />}
|
||||||
</For>
|
</For>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -9,7 +9,7 @@ if (slug.endsWith('.map')) {
|
||||||
return Astro.redirect('/404')
|
return Astro.redirect('/404')
|
||||||
}
|
}
|
||||||
|
|
||||||
const article = await apiClient.loadShoutsBy({ by: { slug }, amount: 1})
|
const article = await apiClient.loadShoutsBy({ by: { slug }, limit: 1})
|
||||||
if (!article) {
|
if (!article) {
|
||||||
return Astro.redirect('/404')
|
return Astro.redirect('/404')
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { initRouter } from '../../../stores/router'
|
||||||
import { PRERENDERED_ARTICLES_COUNT } from '../../../components/Views/Author'
|
import { PRERENDERED_ARTICLES_COUNT } from '../../../components/Views/Author'
|
||||||
|
|
||||||
const slug = Astro.params.slug.toString()
|
const slug = Astro.params.slug.toString()
|
||||||
const shouts = await apiClient.loadShoutsBy({ by: { authors: [slug] } , amount: PRERENDERED_ARTICLES_COUNT })
|
const shouts = await apiClient.loadShoutsBy({ by: { authors: [slug] } , limit: PRERENDERED_ARTICLES_COUNT })
|
||||||
const author = await apiClient.loadAuthorsBy({ by: { slug } })
|
const author = await apiClient.loadAuthorsBy({ by: { slug } })
|
||||||
|
|
||||||
const { pathname, search } = Astro.url
|
const { pathname, search } = Astro.url
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { initRouter } from '../stores/router'
|
||||||
|
|
||||||
const params: URLSearchParams = Astro.url.searchParams
|
const params: URLSearchParams = Astro.url.searchParams
|
||||||
const q = params.get('q')
|
const q = params.get('q')
|
||||||
const searchResults = await apiClient.loadShoutsBy({ by: { title: q, body: q }, amount: 50 })
|
const searchResults = await apiClient.loadShoutsBy({ by: { title: q, body: q }, limit: 50 })
|
||||||
|
|
||||||
const { pathname, search } = Astro.url
|
const { pathname, search } = Astro.url
|
||||||
initRouter(pathname, search)
|
initRouter(pathname, search)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { apiClient } from '../../utils/apiClient'
|
||||||
import { PRERENDERED_ARTICLES_COUNT } from '../../components/Views/Topic'
|
import { PRERENDERED_ARTICLES_COUNT } from '../../components/Views/Topic'
|
||||||
|
|
||||||
const slug = Astro.params.slug?.toString() || ''
|
const slug = Astro.params.slug?.toString() || ''
|
||||||
const shouts = await apiClient.loadShoutsBy({ by: { topics: [slug] }, amount: PRERENDERED_ARTICLES_COUNT })
|
const shouts = await apiClient.loadShoutsBy({ by: { topics: [slug] }, limit: PRERENDERED_ARTICLES_COUNT })
|
||||||
const topic = await apiClient.getTopic({ slug })
|
const topic = await apiClient.getTopic({ slug })
|
||||||
|
|
||||||
import { initRouter } from '../../stores/router'
|
import { initRouter } from '../../stores/router'
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { Shout } from '../../graphql/types.gen'
|
import type { Shout, ShoutsBy } from '../../graphql/types.gen'
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import { useArticlesStore } from './articles'
|
import { useArticlesStore } from './articles'
|
||||||
import { createSignal } from 'solid-js'
|
import { createSignal } from 'solid-js'
|
||||||
import { byCreated } from '../../utils/sortby'
|
|
||||||
|
|
||||||
export type LayoutType = 'article' | 'audio' | 'video' | 'image' | 'literature'
|
export type LayoutType = 'article' | 'audio' | 'video' | 'image' | 'literature'
|
||||||
|
|
||||||
|
@ -23,66 +22,29 @@ export const resetSortedLayoutShouts = () => {
|
||||||
setSortedLayoutShouts(new Map())
|
setSortedLayoutShouts(new Map())
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadRecentLayoutShouts = async ({
|
export const loadLayoutShoutsBy = async ({
|
||||||
layout,
|
by,
|
||||||
amount,
|
|
||||||
offset
|
|
||||||
}: {
|
|
||||||
layout: LayoutType
|
|
||||||
amount: number
|
|
||||||
offset?: number
|
|
||||||
}): Promise<{ hasMore: boolean }> => {
|
|
||||||
const layoutShouts: Shout[] = await apiClient.loadShoutsBy({ by: { layout }, amount, offset })
|
|
||||||
const hasMore = layoutShouts.length < amount
|
|
||||||
if (hasMore) layoutShouts.splice(-1)
|
|
||||||
const shouts = layoutShouts.sort(byCreated)
|
|
||||||
const { articlesByLayout } = useArticlesStore({ shouts })
|
|
||||||
addLayoutShouts(layout, articlesByLayout()[layout])
|
|
||||||
return { hasMore }
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadTopMonthLayoutShouts = async (
|
|
||||||
layout: LayoutType,
|
|
||||||
amount: number,
|
|
||||||
offset: number
|
|
||||||
): Promise<{ hasMore: boolean }> => {
|
|
||||||
const shouts = await apiClient.loadShoutsBy({ by: { layout, stat: 'rating', days: 30 } })
|
|
||||||
const hasMore = shouts.length < amount
|
|
||||||
if (hasMore) shouts.splice(-1)
|
|
||||||
addLayoutShouts(layout, shouts)
|
|
||||||
return { hasMore }
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadTopLayoutShouts = async (
|
|
||||||
layout: LayoutType,
|
|
||||||
amount,
|
|
||||||
offset
|
|
||||||
): Promise<{ hasMore: boolean }> => {
|
|
||||||
const shouts = await apiClient.loadShoutsBy({ by: { layout, stat: 'rating' } })
|
|
||||||
const hasMore = shouts.length < amount
|
|
||||||
if (hasMore) shouts.splice(-1)
|
|
||||||
addLayoutShouts(layout, shouts)
|
|
||||||
return { hasMore }
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadShoutsSearch = async ({
|
|
||||||
layout,
|
|
||||||
query,
|
|
||||||
limit,
|
limit,
|
||||||
offset
|
offset
|
||||||
}: {
|
}: {
|
||||||
layout: LayoutType
|
by: ShoutsBy
|
||||||
query: string
|
|
||||||
limit?: number
|
limit?: number
|
||||||
offset?: number
|
offset?: number
|
||||||
}): Promise<void> => {
|
}): Promise<{ hasMore: boolean }> => {
|
||||||
const by = {
|
const newLayoutShouts = await apiClient.loadShoutsBy({
|
||||||
layout: layout,
|
by,
|
||||||
query: query
|
limit: limit + 1,
|
||||||
|
offset
|
||||||
|
})
|
||||||
|
|
||||||
|
const hasMore = newLayoutShouts.length === limit + 1
|
||||||
|
|
||||||
|
if (hasMore) {
|
||||||
|
newLayoutShouts.splice(-1)
|
||||||
}
|
}
|
||||||
const amount = limit
|
addLayoutShouts(by.layout as LayoutType, newLayoutShouts)
|
||||||
const newLayoutShouts = await apiClient.loadShoutsBy({ by, amount, offset })
|
|
||||||
addLayoutShouts(layout, newLayoutShouts)
|
return { hasMore }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useLayoutsStore = (layout: LayoutType, initialData: Shout[]) => {
|
export const useLayoutsStore = (layout: LayoutType, initialData: Shout[]) => {
|
||||||
|
@ -91,6 +53,6 @@ export const useLayoutsStore = (layout: LayoutType, initialData: Shout[]) => {
|
||||||
return {
|
return {
|
||||||
addLayoutShouts,
|
addLayoutShouts,
|
||||||
sortedLayoutShouts,
|
sortedLayoutShouts,
|
||||||
loadShoutsSearch
|
loadLayoutShoutsBy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +1,52 @@
|
||||||
import { atom, WritableAtom } from 'nanostores'
|
import type { Reaction, Shout } from '../../graphql/types.gen'
|
||||||
import type { Reaction } from '../../graphql/types.gen'
|
|
||||||
import { useStore } from '@nanostores/solid'
|
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import { reduceBy } from '../../utils/reduce'
|
import { createSignal } from 'solid-js'
|
||||||
// import { roomConnect } from '../../utils/p2p'
|
// TODO: import { roomConnect } from '../../utils/p2p'
|
||||||
// FIXME
|
|
||||||
|
|
||||||
export const REACTIONS_AMOUNT_PER_PAGE = 100
|
export const REACTIONS_AMOUNT_PER_PAGE = 100
|
||||||
|
const [sortedReactions, setSortedReactions] = createSignal<Reaction[]>([])
|
||||||
|
const [reactionsByShout, setReactionsByShout] = createSignal<{ [articleSlug: string]: Reaction[] }>({})
|
||||||
|
|
||||||
let reactionsOrdered: WritableAtom<Reaction[]>
|
export const loadReactionsBy = async ({
|
||||||
export const reactions = atom<{ [slug: string]: Reaction[] }>({}) // by shout
|
by,
|
||||||
|
|
||||||
export const useReactionsStore = (initial?: Reaction[]) => {
|
|
||||||
if (!reactionsOrdered) {
|
|
||||||
reactionsOrdered = atom(initial || [])
|
|
||||||
reactionsOrdered.listen((rrr: Reaction[]) => reactions.set(reduceBy(rrr, 'shout')))
|
|
||||||
}
|
|
||||||
return useStore(reactionsOrdered)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const loadArticleReactions = async ({
|
|
||||||
articleSlug,
|
|
||||||
limit = REACTIONS_AMOUNT_PER_PAGE,
|
limit = REACTIONS_AMOUNT_PER_PAGE,
|
||||||
offset = 0
|
offset = 0
|
||||||
}: {
|
}: {
|
||||||
articleSlug: string
|
by
|
||||||
limit?: number
|
limit?: number
|
||||||
offset?: number
|
offset?: number
|
||||||
}): Promise<void> => {
|
}): Promise<{ hasMore: boolean }> => {
|
||||||
const data = await apiClient.loadReactionsBy({ by: { shout: articleSlug }, amount: limit, offset })
|
const data = await apiClient.loadReactionsBy({ by, limit: limit + 1, offset })
|
||||||
|
const hasMore = data.length === limit + 1
|
||||||
|
if (hasMore) data.splice(-1)
|
||||||
// TODO: const [data, provider] = roomConnect(articleSlug, username, "reactions")
|
// TODO: const [data, provider] = roomConnect(articleSlug, username, "reactions")
|
||||||
reactionsOrdered.set(data)
|
setSortedReactions(data)
|
||||||
|
return { hasMore }
|
||||||
|
}
|
||||||
|
export const createReaction = async (reaction: Reaction) => {
|
||||||
|
const { reaction: r } = await apiClient.createReaction({ reaction })
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
export const updateReaction = async (reaction: Reaction) => {
|
||||||
|
const { reaction: r } = await apiClient.updateReaction({ reaction })
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadReactions = async ({
|
export const deleteReaction = async (reactionId: number) => {
|
||||||
shoutSlugs,
|
const resp = await apiClient.destroyReaction({ id: reactionId })
|
||||||
limit = 100,
|
return resp
|
||||||
offset = 0
|
|
||||||
}: {
|
|
||||||
shoutSlugs: string[]
|
|
||||||
limit: number
|
|
||||||
offset: number
|
|
||||||
}): Promise<void> => {
|
|
||||||
const reactionsForShouts = await apiClient.loadReactionsBy({
|
|
||||||
by: { shouts: shoutSlugs },
|
|
||||||
amount: limit,
|
|
||||||
offset
|
|
||||||
})
|
|
||||||
reactionsOrdered.set(reactionsForShouts)
|
|
||||||
}
|
}
|
||||||
|
export const useReactionsStore = (initialState: { reactions?: Reaction[] }) => {
|
||||||
|
if (initialState.reactions) {
|
||||||
|
setSortedReactions([...initialState.reactions])
|
||||||
|
}
|
||||||
|
|
||||||
export const createReaction = async (reaction: Reaction) =>
|
return {
|
||||||
// FIXME
|
reactionsByShout,
|
||||||
reactionsOrdered.set(await apiClient.createReaction({ reaction }))
|
sortedReactions,
|
||||||
|
createReaction,
|
||||||
export const updateReaction = async (reaction: Reaction) =>
|
updateReaction,
|
||||||
// FIXME
|
deleteReaction,
|
||||||
reactionsOrdered.set(await apiClient.updateReaction({ reaction }))
|
loadReactionsBy
|
||||||
|
}
|
||||||
export const deleteReaction = async (reactionId: number) =>
|
}
|
||||||
// FIXME
|
|
||||||
reactionsOrdered.set(await apiClient.destroyReaction({ id: reactionId }))
|
|
||||||
|
|
|
@ -210,6 +210,14 @@ export const apiClient = {
|
||||||
console.debug('[api-client] [api] create reaction mutation called')
|
console.debug('[api-client] [api] create reaction mutation called')
|
||||||
return response.data.createReaction
|
return response.data.createReaction
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// CUDL
|
||||||
|
|
||||||
|
createChat: async ({ title, members }) => {
|
||||||
|
return await privateGraphQLClient
|
||||||
|
.mutation(createChatQuery, { title: title, members: members })
|
||||||
|
.toPromise()
|
||||||
|
},
|
||||||
updateReaction: async ({ reaction }) => {
|
updateReaction: async ({ reaction }) => {
|
||||||
const response = await privateGraphQLClient.mutation(reactionUpdate, { reaction }).toPromise()
|
const response = await privateGraphQLClient.mutation(reactionUpdate, { reaction }).toPromise()
|
||||||
|
|
||||||
|
@ -220,16 +228,9 @@ export const apiClient = {
|
||||||
|
|
||||||
return response.data.deleteReaction
|
return response.data.deleteReaction
|
||||||
},
|
},
|
||||||
createChat: async ({ title, members }) => {
|
|
||||||
return await privateGraphQLClient
|
|
||||||
.mutation(createChatQuery, { title: title, members: members })
|
|
||||||
.toPromise()
|
|
||||||
},
|
|
||||||
|
|
||||||
getChats: async (payload = {}) => {
|
// LOAD BY
|
||||||
const resp = await privateGraphQLClient.query(myChats, payload).toPromise()
|
|
||||||
return resp.data.myChats
|
|
||||||
},
|
|
||||||
loadAuthorsBy: async ({ by, limit = 50, offset = 0 }) => {
|
loadAuthorsBy: async ({ by, limit = 50, offset = 0 }) => {
|
||||||
const resp = await publicGraphQLClient.query(authorsLoadBy, { by, limit, offset }).toPromise()
|
const resp = await publicGraphQLClient.query(authorsLoadBy, { by, limit, offset }).toPromise()
|
||||||
console.debug(resp)
|
console.debug(resp)
|
||||||
|
@ -244,6 +245,14 @@ export const apiClient = {
|
||||||
const resp = await publicGraphQLClient.query(reactionsLoadBy, { by, limit, offset }).toPromise()
|
const resp = await publicGraphQLClient.query(reactionsLoadBy, { by, limit, offset }).toPromise()
|
||||||
return resp.data.loadReactionsBy
|
return resp.data.loadReactionsBy
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// inbox
|
||||||
|
|
||||||
|
getChats: async (payload = {}) => {
|
||||||
|
const resp = await privateGraphQLClient.query(myChats, payload).toPromise()
|
||||||
|
return resp.data.myChats
|
||||||
|
},
|
||||||
|
|
||||||
getChatMessages: async ({
|
getChatMessages: async ({
|
||||||
chat,
|
chat,
|
||||||
amount = 50,
|
amount = 50,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user